diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/routes/onboarding/OnboardingStackNavigator.tsx | 3 | ||||
-rw-r--r-- | src/routes/onboarding/OnboardingStackScreen.tsx | 2 | ||||
-rw-r--r-- | src/screens/onboarding/OnboardingStepOne.tsx | 127 | ||||
-rw-r--r-- | src/screens/onboarding/OnboardingStepTwo.tsx | 38 | ||||
-rw-r--r-- | src/screens/onboarding/PhoneVerification.tsx | 18 | ||||
-rw-r--r-- | src/screens/onboarding/RevampedOnboarding.tsx | 298 | ||||
-rw-r--r-- | src/screens/onboarding/WelcomeScreen.tsx | 2 | ||||
-rw-r--r-- | src/screens/onboarding/index.ts | 2 |
8 files changed, 397 insertions, 93 deletions
diff --git a/src/routes/onboarding/OnboardingStackNavigator.tsx b/src/routes/onboarding/OnboardingStackNavigator.tsx index 4726a47d..761efc91 100644 --- a/src/routes/onboarding/OnboardingStackNavigator.tsx +++ b/src/routes/onboarding/OnboardingStackNavigator.tsx @@ -1,11 +1,12 @@ import {createStackNavigator} from '@react-navigation/stack'; export type OnboardingStackParams = { + RevampedOnboarding: {isPhoneVerified: boolean}; InvitationCodeVerification: {userId: string; username: string}; Login: undefined; OnboardingStepOne: undefined; OnboardingStepThree: {userId: string; username: string}; - OnboardingStepTwo: {firstName: string; lastName: string; phone: string}; + OnboardingStepTwo: {firstName: string}; PasswordReset: {value: string}; PasswordResetRequest: undefined; PasswordVerification: {id: string}; diff --git a/src/routes/onboarding/OnboardingStackScreen.tsx b/src/routes/onboarding/OnboardingStackScreen.tsx index 339c3d0d..458697ad 100644 --- a/src/routes/onboarding/OnboardingStackScreen.tsx +++ b/src/routes/onboarding/OnboardingStackScreen.tsx @@ -10,6 +10,7 @@ import { PasswordVerification, PhoneVerification, WelcomeScreen, + RevampedOnboarding } from '../../screens'; import OnboardingStepOne from '../../screens/onboarding/OnboardingStepOne'; import {modalStyle} from '../main'; @@ -43,6 +44,7 @@ const Onboarding: React.FC = () => { }} /> <OnboardingStack.Screen name="WelcomeScreen" component={WelcomeScreen} /> + <OnboardingStack.Screen name="RevampedOnboarding" component={RevampedOnboarding} /> <OnboardingStack.Screen name="PasswordReset" component={PasswordReset} diff --git a/src/screens/onboarding/OnboardingStepOne.tsx b/src/screens/onboarding/OnboardingStepOne.tsx index 618bc39b..abec050e 100644 --- a/src/screens/onboarding/OnboardingStepOne.tsx +++ b/src/screens/onboarding/OnboardingStepOne.tsx @@ -13,8 +13,10 @@ import { import { ArrowButton, Background, - RegistrationWizard, + BasicButton, + // RegistrationWizard, TaggInput, + TaggSquareButton, } from '../../components'; import {nameRegex, phoneRegex} from '../../constants'; import { @@ -25,7 +27,7 @@ import { import {OnboardingStackParams} from '../../routes'; import {sendOtpStatusCode} from '../../services'; import {BackgroundGradientType} from '../../types'; -import {SCREEN_HEIGHT} from '../../utils'; +import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; type OnboardingStepOneNavigationProp = StackNavigationProp< OnboardingStackParams, @@ -108,28 +110,27 @@ const OnboardingStepOne: React.FC<OnboardingStepOneProps> = ({navigation}) => { }); } try { - const {isValidFname, isValidLname, isValidPhone} = form; - if (isValidFname && isValidLname && isValidPhone) { - const {phone} = form; - const code = await sendOtpStatusCode(phone); - if (code) { - switch (code) { - case 200: - const {fname, lname} = form; - navigation.navigate('PhoneVerification', { - firstName: fname, - lastName: lname, - phone, - }); - break; - case 409: - Alert.alert(ERROR_PHONE_IN_USE); - break; - default: - Alert.alert(ERROR_TWILIO_SERVER_ERROR); - } - } - } else { + const {isValidFname} = form; + // const {isValidFname, isValidLname, isValidPhone} = form; + if (isValidFname) { + const {fname} = form; + navigation.navigate('OnboardingStepTwo', { + firstName: fname + }); + // const {phone} = form; + // const code = await sendOtpStatusCode(phone); + // if (code) { + // switch (code) { + // case 200: + // const {fname, lname} = form; + + // break; + // case 409: + // Alert.alert(ERROR_PHONE_IN_USE); + // break; + // default: + // Alert.alert(ERROR_TWILIO_SERVER_ERROR); + } else { setForm({...form, attemptedSubmit: false}); setTimeout(() => setForm({...form, attemptedSubmit: true})); } @@ -144,29 +145,36 @@ const OnboardingStepOne: React.FC<OnboardingStepOneProps> = ({navigation}) => { const footer = useMemo( () => ( - <View style={styles.footer}> - <ArrowButton - direction="backward" - onPress={() => navigation.navigate('Login')} - /> - <TouchableOpacity onPress={goNext}> - <ArrowButton - direction="forward" - disabled={ - !(form.isValidFname && form.isValidLname && form.isValidPhone) - } - onPress={goNext} - /> - </TouchableOpacity> - </View> + <TaggSquareButton + onPress={goNext} + title={'Next'} + buttonStyle={'normal'} + buttonColor={'white'} + labelColor={'blue'} + /> + // // <View style={styles.footer}> + // {/* <ArrowButton + // direction="backward" + // onPress={() => navigation.navigate('Login')} + // /> */} + // {/* <TouchableOpacity onPress={goNext}> */} + // {/* <ArrowButton + // direction="forward" + // disabled={ + // !(form.isValidFname && form.isValidLname && form.isValidPhone) + // } + // onPress={goNext} + // /> */} + // {/* </TouchableOpacity> */} + // // </View> ), [ form.fname, - form.lname, - form.phone, + // form.lname, + // form.phone, form.isValidFname, - form.isValidLname, - form.isValidPhone, + // form.isValidLname, + // form.isValidPhone, ], ); @@ -175,13 +183,14 @@ const OnboardingStepOne: React.FC<OnboardingStepOneProps> = ({navigation}) => { style={styles.container} gradientType={BackgroundGradientType.Light}> <StatusBar barStyle="light-content" /> - <RegistrationWizard style={styles.wizard} step="one" /> + {/* getting rid of registration progress in onboarding*/} + {/* <RegistrationWizard style={styles.wizard} step="one" /> */} <KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : 'height'} style={styles.container}> - <View> - <Text style={styles.formHeader}>ENTER NAME</Text> - </View> + {/* <View style={{backgroundColor: 'thistle', position: 'absolute', top: 0, marginTop: '45%', height: 0}}> */} + <Text style={styles.formHeader}>SIGN UP</Text> + {/* </View> */} <TaggInput accessibilityHint="Enter your first name." accessibilityLabel="First name input field." @@ -197,7 +206,7 @@ const OnboardingStepOne: React.FC<OnboardingStepOneProps> = ({navigation}) => { attemptedSubmit={form.attemptedSubmit} width={280} /> - <TaggInput + {/* <TaggInput accessibilityHint="Enter your last name." accessibilityLabel="Last name input field." placeholder="Last Name" @@ -211,8 +220,8 @@ const OnboardingStepOne: React.FC<OnboardingStepOneProps> = ({navigation}) => { invalidWarning="Please enter a valid last name." attemptedSubmit={form.attemptedSubmit} width={280} - /> - <TaggInput + /> */} + {/* <TaggInput maxLength={10} // currently only support US phone numbers accessibilityHint="Enter your phone number." accessibilityLabel="Phone number input field." @@ -229,28 +238,32 @@ const OnboardingStepOne: React.FC<OnboardingStepOneProps> = ({navigation}) => { attemptedSubmit={form.attemptedSubmit} width={280} onSubmitEditing={goNext} - /> + /> */} + <View style = {{position: 'absolute', bottom: 150}}> + {footer} + </View> </KeyboardAvoidingView> - {footer} </Background> ); }; const styles = StyleSheet.create({ container: { - flex: 1, + height: SCREEN_HEIGHT, + width: SCREEN_WIDTH, alignItems: 'center', justifyContent: 'center', }, - wizard: { - position: 'absolute', - top: SCREEN_HEIGHT * 0.1, - }, + button: { + width: 40, + aspectRatio: 10, + }, formHeader: { color: '#fff', fontSize: 30, fontWeight: '600', marginBottom: '16%', + position: 'absolute', top: 0, marginTop: '45%', }, load: { top: '5%', diff --git a/src/screens/onboarding/OnboardingStepTwo.tsx b/src/screens/onboarding/OnboardingStepTwo.tsx index fc89b887..5c474c14 100644 --- a/src/screens/onboarding/OnboardingStepTwo.tsx +++ b/src/screens/onboarding/OnboardingStepTwo.tsx @@ -16,8 +16,9 @@ import { ArrowButton, Background, LoadingIndicator, - RegistrationWizard, + // RegistrationWizard, TaggInput, + TaggSquareButton, TermsConditions, } from '../../components'; import {emailRegex, passwordRegex, usernameRegex} from '../../constants'; @@ -211,25 +212,14 @@ const OnboardingStepTwo: React.FC<OnboardingStepTwoProps> = ({ const footer = useMemo( () => ( <View style={styles.footer}> - <ArrowButton - direction="backward" - onPress={() => - navigation.navigate('PhoneVerification', {...route.params}) - } - /> <TouchableOpacity onPress={handleRegister}> - <ArrowButton - direction="forward" - disabled={ - !( - form.isValidUsername && - form.isValidPassword && - form.passwordsMatch && - form.tcAccepted - ) - } - onPress={handleRegister} - /> + <TaggSquareButton + onPress={goNext} + title={'Next'} + buttonStyle={'normal'} + buttonColor={'white'} + labelColor={'blue'} + /> </TouchableOpacity> </View> ), @@ -251,7 +241,7 @@ const OnboardingStepTwo: React.FC<OnboardingStepTwoProps> = ({ style={styles.container} gradientType={BackgroundGradientType.Light}> <StatusBar barStyle="light-content" /> - <RegistrationWizard style={styles.wizard} step="two" /> + {/* <RegistrationWizard style={styles.wizard} step="two" /> */} <KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : 'height'} style={styles.container}> @@ -347,10 +337,10 @@ const styles = StyleSheet.create({ alignItems: 'center', justifyContent: 'center', }, - wizard: { - position: 'absolute', - top: SCREEN_HEIGHT * 0.1, - }, + // wizard: { + // position: 'absolute', + // top: SCREEN_HEIGHT * 0.1, + // }, formHeader: { color: '#fff', fontSize: 30, diff --git a/src/screens/onboarding/PhoneVerification.tsx b/src/screens/onboarding/PhoneVerification.tsx index 6ec511b3..a242b44b 100644 --- a/src/screens/onboarding/PhoneVerification.tsx +++ b/src/screens/onboarding/PhoneVerification.tsx @@ -21,7 +21,7 @@ import { ArrowButton, Background, LoadingIndicator, - RegistrationWizard, + // RegistrationWizard, SubmitButton, } from '../../components'; import {codeRegex} from '../../constants'; @@ -67,9 +67,7 @@ const PhoneVerification: React.FC<PhoneVerificationProps> = ({ try { const success = await trackPromise(verifyOtp(phone, value)); if (success) { - navigation.navigate('OnboardingStepTwo', { - ...route.params, - }); + navigation.navigate('RevampedOnboarding', {isPhoneVerified: true}); } } catch (error) { console.log(error); @@ -82,7 +80,7 @@ const PhoneVerification: React.FC<PhoneVerificationProps> = ({ <View style={styles.footer}> <ArrowButton direction="backward" - onPress={() => navigation.navigate('OnboardingStepOne')} + onPress={() => navigation.navigate('RevampedOnboarding', {isPhoneVerified: false})} /> </View> ), @@ -94,7 +92,7 @@ const PhoneVerification: React.FC<PhoneVerificationProps> = ({ centered style={styles.container} gradientType={BackgroundGradientType.Light}> - <RegistrationWizard style={styles.wizard} step="one" /> + {/* <RegistrationWizard style={styles.wizard} step="one" /> */} <KeyboardAvoidingView behavior="padding" style={styles.form}> <Text style={styles.formHeader}>Enter 6 digit code</Text> <Text style={styles.description}> @@ -144,10 +142,10 @@ const styles = StyleSheet.create({ alignItems: 'center', justifyContent: 'center', }, - wizard: { - position: 'absolute', - top: SCREEN_HEIGHT * 0.1, - }, + // wizard: { + // position: 'absolute', + // top: SCREEN_HEIGHT * 0.1, + // }, form: { top: '20%', alignItems: 'center', diff --git a/src/screens/onboarding/RevampedOnboarding.tsx b/src/screens/onboarding/RevampedOnboarding.tsx new file mode 100644 index 00000000..bae2777c --- /dev/null +++ b/src/screens/onboarding/RevampedOnboarding.tsx @@ -0,0 +1,298 @@ +import { useNavigation } from '@react-navigation/core'; +import { RouteProp } from '@react-navigation/native'; +import {StackNavigationProp} from '@react-navigation/stack'; +import { current } from 'immer'; +import React, {useEffect, useMemo, useRef, useState} from 'react'; +import { + Alert, + KeyboardAvoidingView, + Platform, + StatusBar, + StyleSheet, + Text, + TouchableOpacity, + View, +} from 'react-native'; +import { + ArrowButton, + Background, + BasicButton, + // RegistrationWizard, + TaggInput, + TaggSquareButton, +} from '../../components'; +import {emailRegex, nameRegex, phoneRegex, usernameRegex} from '../../constants'; +import { + ERROR_NEXT_PAGE, + ERROR_PHONE_IN_USE, + ERROR_TWILIO_SERVER_ERROR, +} from '../../constants/strings'; +import {OnboardingStackParams} from '../../routes'; +import {sendOtpStatusCode} from '../../services'; +import {BackgroundGradientType} from '../../types'; +import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; + +type RevampedOnboardingRouteProp = RouteProp<OnboardingStackParams, 'RevampedOnboarding'>; +type RevampedOnboardingNavigationProp = StackNavigationProp< + OnboardingStackParams, + 'RevampedOnboarding' +>; +interface RevampedOnboardingProps { + route: RevampedOnboardingRouteProp; + navigation: RevampedOnboardingNavigationProp; +} + +const RevampedOnboarding: React.FC<RevampedOnboardingProps> = ({route}) => { + const {isPhoneVerified} = route.params; + const navigation = useNavigation(); + type renderStatusType = 'firstName' | 'lastName' | 'username' | 'email'; + const [renderStatus, setStatus] = useState<renderStatusType>('firstName'); + const [currentStep, setCurrentStep] = useState(0); + const [form, setForm] = useState({ + fname: '', + lname: '', + phone: '', + email: '', + isValidFname: false, + isValidLname: false, + isValidPhone: false, + isValidEmail: false, + attemptedSubmit: false, + token: '', + }); + + + + const goNext = async () => { + if (!form.attemptedSubmit) { + setForm({ + ...form, + attemptedSubmit: true, + }); + } + try { + const {isValidPhone} = form; + // const {isValidFname, isValidLname, isValidPhone} = form; + if (isValidPhone) { + const {phone} = form; + const code = await sendOtpStatusCode(phone); + if (code) { + switch (code) { + case 200: + const {fname, lname} = form; + navigation.navigate('PhoneVerification', { + firstName: fname, + lastName: lname, + phone, + }); + break; + case 409: + Alert.alert(ERROR_PHONE_IN_USE); + break; + default: + Alert.alert(ERROR_TWILIO_SERVER_ERROR); + } + } else { + setForm({...form, attemptedSubmit: false}); + setTimeout(() => setForm({...form, attemptedSubmit: true})); + } + } + } catch (error) { + Alert.alert(ERROR_NEXT_PAGE); + return { + name: 'Navigation error', + description: error, + }; + } + }; + + // 0 = first name, 1 = last name, 2 = username, 3 = phone # + const handleNameUpdate= (name: string, nameType: number) => { + name = name.trim(); + let isValidName: boolean = nameRegex.test(name); + switch(nameType) { + case 0: + setForm({ + ...form, + fname: name, + isValidFname: isValidName, + }); + case 1: + setForm({ + ...form, + lname: name, + isValidLname: isValidName, + }); + case 2: + let isvalidUserName = usernameRegex.test(name); + setForm({ + ...form, + fname: name, + isValidFname: isValidName, + }); + // case 3: + // let isValidPhone: boolean = phoneRegex.test(name); + // setForm({ + // ...form, + // phone: name, + // isValidPhone, + // }); + } + + }; + const handlePhoneUpdate = (phone: string) => { + phone = phone.trim(); + let isValidPhone: boolean = phoneRegex.test(phone); + setForm({ + ...form, + phone, + isValidPhone, + }); + }; + const handleEmailUpdate = (email: string) => { + email = email.trim(); + let isValidEmail: boolean = emailRegex.test(email); + setForm({ + ...form, + email, + isValidEmail, + }); + }; + + const formSteps: { + placeholder: string, + valid: boolean, + onChangeText: (text: string, nameType: number) => void, + }[] = [ + { + placeholder: 'First Name', + valid: form.isValidFname, + onChangeText: handleNameUpdate, + }, + { + placeholder: 'Last Name', + valid: form.isValidLname, + onChangeText: handleNameUpdate, + }, + { + placeholder: 'Phone', + valid: form.isValidPhone, + onChangeText: handlePhoneUpdate, + }, + { + placeholder: 'Email', + valid: form.isValidEmail, + onChangeText: handleEmailUpdate, + }, + { + placeholder: 'Username', + valid: form.isValidLname, + onChangeText: handleNameUpdate, + }, + // ... + ] + useEffect( + () => { + console.log("before: " + currentStep + " " + step.placeholder) + if(isPhoneVerified) { + setCurrentStep(currentStep + 1) + } + console.log("afgter: " + currentStep + " " + step.placeholder) + }, [isPhoneVerified]) + const step = formSteps[currentStep] + return ( + <Background + style={styles.container} + gradientType={BackgroundGradientType.Light}> + <StatusBar barStyle="light-content" /> + {/* getting rid of registration progress in onboarding*/} + {/* <RegistrationWizard style={styles.wizard} step="one" /> */} + <KeyboardAvoidingView + behavior={Platform.OS === 'ios' ? 'padding' : 'height'} + style={styles.container}> + {/* <View style={{backgroundColor: 'thistle', position: 'absolute', top: 0, marginTop: '45%', height: 0}}> */} + {(step.placeholder === "Phone" && !isPhoneVerified) ? ( + <TaggInput + maxLength={10} // currently only support US phone numbers + accessibilityHint="Enter your phone number." + accessibilityLabel="Phone number input field." + placeholder="Phone Number" + autoCompleteType="tel" + textContentType="telephoneNumber" + autoCapitalize="none" + keyboardType="number-pad" + onChangeText={handlePhoneUpdate} + blurOnSubmit={false} + valid={form.isValidPhone} + invalidWarning={'Please enter a valid 10 digit number.'} + attemptedSubmit={form.attemptedSubmit} + width={280} + onSubmitEditing={goNext} + /> + ) : ( + <> + <Text style={styles.formHeader}>SIGN UP</Text> + <View style = {{position: 'absolute', top: 50}}> + <TaggInput + key = {step.placeholder} + accessibilityHint={`Enter your ${step.placeholder.toLowerCase()}`} + accessibilityLabel={`${step.placeholder} input field.`} + placeholder={step.placeholder} + autoCompleteType="name" + textContentType="name" + returnKeyType="next" + onChangeText={step.onChangeText} + onSubmitEditing={() => setCurrentStep(currentStep + 1)} + blurOnSubmit={false} + valid={step.valid} + invalidWarning={`Please enter a valid ${step.placeholder.toLowerCase()}`} + attemptedSubmit={form.attemptedSubmit} + width={280} + /> + {/* {footer('username')} */} + </View> + </>)} + <View style = {{position: 'absolute', bottom: 150}}> + </View> + </KeyboardAvoidingView> + </Background> + )}; +// in return listen for button click, if fname valid, then change state to return the next component in the list +// conditionally display subsequent components. + +const styles = StyleSheet.create({ + container: { + height: SCREEN_HEIGHT, + width: SCREEN_WIDTH, + alignItems: 'center', + justifyContent: 'center', + }, + button: { + width: 40, + aspectRatio: 10, + }, + formHeader: { + color: '#fff', + fontSize: 30, + fontWeight: '600', + marginBottom: '16%', + position: 'absolute', top: 0, marginTop: '45%', + }, + load: { + top: '5%', + }, + footer: { + width: '100%', + flexDirection: 'row', + justifyContent: 'space-around', + ...Platform.select({ + ios: { + bottom: '20%', + }, + android: { + bottom: '10%', + }, + }), + }, + }); +export default RevampedOnboarding; diff --git a/src/screens/onboarding/WelcomeScreen.tsx b/src/screens/onboarding/WelcomeScreen.tsx index c36a6e05..358661f7 100644 --- a/src/screens/onboarding/WelcomeScreen.tsx +++ b/src/screens/onboarding/WelcomeScreen.tsx @@ -35,7 +35,7 @@ const WelcomeScreen: React.FC<WelcomeScreenProps> = ({navigation}) => { </View> <TaggSquareButton onPress={() => { - navigation.navigate('OnboardingStepOne'); + navigation.navigate('RevampedOnboarding', {isPhoneVerified: false}); }} title={'Next'} buttonStyle={'large'} diff --git a/src/screens/onboarding/index.ts b/src/screens/onboarding/index.ts index 7eb0587f..c0d99dd2 100644 --- a/src/screens/onboarding/index.ts +++ b/src/screens/onboarding/index.ts @@ -8,3 +8,5 @@ export {default as PasswordResetRequest} from './PasswordResetRequest'; export {default as PhoneVerification} from './PhoneVerification'; export {default as PasswordVerification} from './PasswordVerification'; export {default as WelcomeScreen} from './WelcomeScreen'; +export {default as RevampedOnboarding} from './RevampedOnboarding'; + |