From e32241734c8cc258812ac12c7727aaa7f947eed5 Mon Sep 17 00:00:00 2001 From: Leon Jiang <35908040+leonyjiang@users.noreply.github.com> Date: Wed, 8 Jul 2020 09:56:17 -0700 Subject: [TMA-60] Registration Page UI & Field Validation (#13) * remove unused image * refactor LoginInput component to be more generic * configure bare registration screen * create index files for exports * add yarn typing script * refactor and re-style LoginInput component * re-style login screen according to designs * make LoginInput name more generic, give TaggInput dirty & width props * add disabled feature to login screen submit button, finalized styles * add arrow images and create ArrowButton component * create RegistrationWizard component and move files around * added disabled & enabled buttons to ArrowButton component * create dummy terms and conditions text * create common CenteredView component for re-use * create custom RadioCheckbox for registration screen * create TermsConditions & OverlayView components * update index.ts export files * build registration page UI with basic validation * yarn lint/type & add platform-specific styling * add yarn type item to PR checklist * add react-native-animatable dependency to project * add regex variables to constants file * Add width prop for more flexible styling * Add types and disable auto-capitalization * Update email validation regex * Create linear-gradient background component * Update password regex and add inline docs * Refactor code to be more readable * Add warning prop and animation to TaggInput * Add wrapper View for vertical margins * Make JSX more readable & add TaggInput components * Integrate refactored code into registration page * Merge in login screen changes * Lint and fix file syntax * Fix function docs * Add ViewProps to CenterView props * Add KeyboardAvoidingView to Background component * Add blurOnSubmit for inputs, restore deleted handleLogin code * Create Verification screen and add it to routes * Add routing to Verification page upon success * Add API request upon registration submit * Trigger warning shaking animation on submit * Make disabled arrow touchable, tap triggers submit --- src/components/onboarding/ArrowButton.tsx | 23 ++++ src/components/onboarding/Background.tsx | 44 +++++++ src/components/onboarding/RegistrationWizard.tsx | 47 ++++++++ src/components/onboarding/TermsConditions.tsx | 140 +++++++++++++++++++++++ src/components/onboarding/index.ts | 4 + 5 files changed, 258 insertions(+) create mode 100644 src/components/onboarding/ArrowButton.tsx create mode 100644 src/components/onboarding/Background.tsx create mode 100644 src/components/onboarding/RegistrationWizard.tsx create mode 100644 src/components/onboarding/TermsConditions.tsx create mode 100644 src/components/onboarding/index.ts (limited to 'src/components/onboarding') diff --git a/src/components/onboarding/ArrowButton.tsx b/src/components/onboarding/ArrowButton.tsx new file mode 100644 index 00000000..bf07c6ac --- /dev/null +++ b/src/components/onboarding/ArrowButton.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import {Image, TouchableOpacity, TouchableOpacityProps} from 'react-native'; + +interface ArrowButtonProps extends TouchableOpacityProps { + direction: 'forward' | 'backward'; + disabled?: boolean; +} +const ArrowButton: React.FC = (props: ArrowButtonProps) => { + const arrow = + props.direction === 'forward' + ? props.disabled + ? require('../../assets/images/arrow-forward-disabled.png') + : require('../../assets/images/arrow-forward-enabled.png') + : require('../../assets/images/arrow-backward.png'); + + return ( + + + + ); +}; + +export default ArrowButton; diff --git a/src/components/onboarding/Background.tsx b/src/components/onboarding/Background.tsx new file mode 100644 index 00000000..98082022 --- /dev/null +++ b/src/components/onboarding/Background.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import LinearGradient from 'react-native-linear-gradient'; +import { + StyleSheet, + TouchableWithoutFeedback, + Keyboard, + ViewProps, + KeyboardAvoidingView, + View, + Platform, +} from 'react-native'; + +interface BackgroundProps extends ViewProps {} +const Background: React.FC = (props) => { + return ( + + + + + {props.children} + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + }, + view: { + alignItems: 'center', + }, +}); + +export default Background; diff --git a/src/components/onboarding/RegistrationWizard.tsx b/src/components/onboarding/RegistrationWizard.tsx new file mode 100644 index 00000000..5d7e6ee2 --- /dev/null +++ b/src/components/onboarding/RegistrationWizard.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import {View, StyleSheet, ViewProps} from 'react-native'; + +interface RegistrationWizardProps extends ViewProps { + step: 'one' | 'two' | 'three'; +} + +const RegistrationWizard = (props: RegistrationWizardProps) => { + const stepStyle = styles.step; + const stepActiveStyle = [styles.step, styles.stepActive]; + return ( + + + + + + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flexDirection: 'row', + justifyContent: 'center', + alignItems: 'center', + }, + step: { + height: 18, + width: 18, + borderRadius: 9, + borderWidth: 2, + borderColor: '#e1f0ff', + }, + stepActive: { + backgroundColor: '#e1f0ff', + }, + progress: { + width: '30%', + height: 2, + backgroundColor: '#e1f0ff', + }, +}); + +export default RegistrationWizard; diff --git a/src/components/onboarding/TermsConditions.tsx b/src/components/onboarding/TermsConditions.tsx new file mode 100644 index 00000000..5af1b972 --- /dev/null +++ b/src/components/onboarding/TermsConditions.tsx @@ -0,0 +1,140 @@ +import React, {useState} from 'react'; +import { + Modal, + StyleSheet, + View, + Text, + Button, + TouchableOpacity, + ScrollView, + ViewProps, +} from 'react-native'; + +import {RadioCheckbox, CenteredView, OverlayView} from '../common'; +import {dummyTermsConditions} from '../../constants'; + +interface TermsConditionsProps extends ViewProps { + accepted: boolean; + onChange: (accepted: boolean) => void; +} +const TermsConditions: React.FC = (props) => { + // boolean representing if modal is visible + const [modalVisible, setModalVisible] = useState(false); + // destructure props + const {accepted, onChange} = props; + /** + * Hides the modal. + */ + const hideModal = (): void => { + if (modalVisible) { + setModalVisible(false); + } + }; + /** + * Sets `accepted` to `true` and hides the modal. + */ + const handleAccept = (): void => { + onChange(true); + hideModal(); + }; + /** + * Toggles the value of `accepted`. + */ + const toggleAccepted = (): void => { + onChange(!accepted); + }; + + return ( + + + + + I accept the + setModalVisible(true)}> + + terms and conditions. + + + + + + + + + + Terms and Conditions + {dummyTermsConditions} + + +