diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/common/index.ts | 1 | ||||
-rw-r--r-- | src/components/onboarding/TaggBigInput.tsx | 64 | ||||
-rw-r--r-- | src/components/onboarding/TaggDatePicker.tsx | 63 | ||||
-rw-r--r-- | src/components/onboarding/TaggDropDown.tsx | 40 | ||||
-rw-r--r-- | src/components/onboarding/TaggInput.tsx (renamed from src/components/common/TaggInput.tsx) | 0 | ||||
-rw-r--r-- | src/components/onboarding/index.ts | 4 | ||||
-rw-r--r-- | src/constants/regex.ts | 22 | ||||
-rw-r--r-- | src/routes/onboarding/Onboarding.tsx | 6 | ||||
-rw-r--r-- | src/routes/onboarding/OnboardingStack.tsx | 1 | ||||
-rw-r--r-- | src/screens/onboarding/Checkpoint.tsx | 144 | ||||
-rw-r--r-- | src/screens/onboarding/ProfileOnboarding.tsx | 310 | ||||
-rw-r--r-- | src/screens/onboarding/Verification.tsx | 2 | ||||
-rw-r--r-- | src/screens/onboarding/index.ts | 3 |
13 files changed, 619 insertions, 41 deletions
diff --git a/src/components/common/index.ts b/src/components/common/index.ts index 826675ff..cb8b9b6a 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -1,7 +1,6 @@ export {default as CenteredView} from './CenteredView'; export {default as OverlayView} from './OverlayView'; export {default as RadioCheckbox} from './RadioCheckbox'; -export {default as TaggInput} from './TaggInput'; export {default as NavigationIcon} from './NavigationIcon'; export {default as GradientBackground} from './GradientBackground'; export {default as Post} from './post'; diff --git a/src/components/onboarding/TaggBigInput.tsx b/src/components/onboarding/TaggBigInput.tsx new file mode 100644 index 00000000..ba965465 --- /dev/null +++ b/src/components/onboarding/TaggBigInput.tsx @@ -0,0 +1,64 @@ +import React from 'react'; +import {View, TextInput, StyleSheet, TextInputProps} from 'react-native'; +import * as Animatable from 'react-native-animatable'; + +interface TaggBigInputProps extends TextInputProps { + valid?: boolean; + invalidWarning?: string; + attemptedSubmit?: boolean; + width?: number | string; +} +/** + * An input component that receives all props a normal TextInput component does. TaggInput components grow to 60% of their parent's width by default, but this can be set using the `width` prop. + */ +const TaggBigInput = React.forwardRef((props: TaggBigInputProps, ref: any) => { + return ( + <View style={styles.container}> + <TextInput + style={[{width: props.width}, styles.input]} + placeholderTextColor="#ddd" + clearButtonMode="while-editing" + ref={ref} + multiline={true} + {...props} + /> + {props.attemptedSubmit && !props.valid && ( + <Animatable.Text + animation="shake" + duration={500} + style={styles.warning}> + {props.invalidWarning} + </Animatable.Text> + )} + </View> + ); +}); + +const styles = StyleSheet.create({ + container: { + width: '100%', + alignItems: 'center', + marginVertical: 11, + }, + input: { + minWidth: '60%', + height: 120, + fontSize: 16, + fontWeight: '600', + color: '#fff', + borderColor: '#fffdfd', + borderWidth: 2, + borderRadius: 20, + paddingLeft: 13, + paddingTop: 13, + }, + warning: { + fontSize: 14, + marginTop: 5, + color: '#f4ddff', + maxWidth: 350, + textAlign: 'center', + }, +}); + +export default TaggBigInput; diff --git a/src/components/onboarding/TaggDatePicker.tsx b/src/components/onboarding/TaggDatePicker.tsx new file mode 100644 index 00000000..39af6234 --- /dev/null +++ b/src/components/onboarding/TaggDatePicker.tsx @@ -0,0 +1,63 @@ +import React from 'react'; +import DatePicker from 'react-native-datepicker'; +import {View, StyleSheet, TextInputProps} from 'react-native'; + +interface TaggDatePickerProps extends TextInputProps { + width?: number | string; + date?: string; + maxDate?: Date | string; +} +/** + * An input component that receives all props a normal TextInput component does. TaggInput components grow to 60% of their parent's width by default, but this can be set using the `width` prop. + */ +const TaggDatePicker = React.forwardRef( + (props: TaggDatePickerProps, ref: any) => { + return ( + <View style={styles.container}> + <DatePicker + {...props} + style={styles.input} + placeholder={'Date of Birth'} + showIcon={false} + ref={ref} + format={'YYYY-MM-DD'} + customStyles={{ + placeholderText: { + color: '#ddd', + + fontSize: 16, + fontWeight: '600', + }, + dateText: { + color: '#fff', + fontSize: 16, + fontWeight: '600', + }, + dateInput: { + borderColor: '#fffdfd', + borderWidth: 2, + borderRadius: 20, + justifyContent: 'center', + alignItems: 'flex-start', + paddingLeft: 13, + }, + }} + /> + </View> + ); + }, +); + +const styles = StyleSheet.create({ + container: { + width: '100%', + alignItems: 'center', + marginVertical: 11, + }, + input: { + minWidth: '67%', + height: 40, + }, +}); + +export default TaggDatePicker; diff --git a/src/components/onboarding/TaggDropDown.tsx b/src/components/onboarding/TaggDropDown.tsx new file mode 100644 index 00000000..a45426ca --- /dev/null +++ b/src/components/onboarding/TaggDropDown.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import RNSelectPicker from 'react-native-picker-select'; +import {View, StyleSheet, TextInputProps} from 'react-native'; + +interface TaggDropDownProps extends TextInputProps { + width?: number | string; +} + +/** + * An input component that receives all props a normal TextInput component does. TaggInput components grow to 60% of their parent's width by default, but this can be set using the `width` prop. + */ +const TaggDropDown = React.forwardRef((props: TaggDropDownProps, ref: any) => { + return ( + <View style={styles.container}> + <RNSelectPicker {...props} style={styles} ref={ref} /> + </View> + ); +}); + +const styles = StyleSheet.create({ + container: { + width: '66.67%', + alignItems: 'center', + marginVertical: 11, + }, + inputIOS: { + paddingVertical: 8, + paddingHorizontal: 10, + minWidth: '60%', + fontSize: 16, + fontWeight: '600', + color: '#fff', + borderColor: '#fffdfd', + borderWidth: 2, + borderRadius: 20, + paddingLeft: 13, + }, +}); + +export default TaggDropDown; diff --git a/src/components/common/TaggInput.tsx b/src/components/onboarding/TaggInput.tsx index fe11d4f0..fe11d4f0 100644 --- a/src/components/common/TaggInput.tsx +++ b/src/components/onboarding/TaggInput.tsx diff --git a/src/components/onboarding/index.ts b/src/components/onboarding/index.ts index ef972194..31f356d3 100644 --- a/src/components/onboarding/index.ts +++ b/src/components/onboarding/index.ts @@ -3,3 +3,7 @@ export {default as Background} from './Background'; export {default as RegistrationWizard} from './RegistrationWizard'; export {default as TermsConditions} from './TermsConditions'; export {default as SubmitButton} from './SubmitButton'; +export {default as TaggInput} from './TaggInput'; +export {default as TaggBigInput} from './TaggBigInput'; +export {default as TaggDatePicker} from './TaggDatePicker'; +export {default as TaggDropDown} from './TaggDropDown'; diff --git a/src/constants/regex.ts b/src/constants/regex.ts index 40c82691..c380ee30 100644 --- a/src/constants/regex.ts +++ b/src/constants/regex.ts @@ -26,3 +26,25 @@ export const usernameRegex: RegExp = /^[a-zA-Z0-9_.]{6,30}$/; * - match alphanumerics, apostrophes, commas, periods, dashes, and spaces */ export const nameRegex: RegExp = /^[A-Za-z'\-,. ]{2,20}$/; + +/** + * The website regex has the following constraints + * - starts with http:// or https:// + * - min. 2 chars, max. 50 chars on website name + * - match alphanumerics, and special characters used in URLs + */ +export const websiteRegex: RegExp = /^$|^(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,50}\.[a-zA-Z0-9()]{2,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]{0,35})$/; + +/** + * The website regex has the following constraints + * - max. 150 chars for bio + * - match alphanumerics, and special characters used in URLs + */ +export const bioRegex: RegExp = /^$|^[A-Za-z'\-,. ]{1,150}$/; + +/** + * The gender regex has the following constraints + * - max. 20 chars for bio + * - match alphanumerics, hyphens, and whitespaces + */ +export const genderRegex: RegExp = /^$|^[A-Za-z\- ]{2,20}$/; diff --git a/src/routes/onboarding/Onboarding.tsx b/src/routes/onboarding/Onboarding.tsx index d2bfbfd6..40dbc970 100644 --- a/src/routes/onboarding/Onboarding.tsx +++ b/src/routes/onboarding/Onboarding.tsx @@ -6,6 +6,7 @@ import { RegistrationTwo, Verification, ProfileOnboarding, + Checkpoint, } from '../../screens'; const Onboarding: React.FC = () => { @@ -27,6 +28,11 @@ const Onboarding: React.FC = () => { options={{headerShown: false}} /> <OnboardingStack.Screen + name="Checkpoint" + component={Checkpoint} + options={{headerShown: false}} + /> + <OnboardingStack.Screen name="Verification" component={Verification} options={{headerShown: false}} diff --git a/src/routes/onboarding/OnboardingStack.tsx b/src/routes/onboarding/OnboardingStack.tsx index f9722d46..0f0b5c83 100644 --- a/src/routes/onboarding/OnboardingStack.tsx +++ b/src/routes/onboarding/OnboardingStack.tsx @@ -6,6 +6,7 @@ export type OnboardingStackParams = { RegistrationTwo: | {firstName: string; lastName: string; email: string} | undefined; + Checkpoint: {username: string; email: string; userId: string}; Verification: {username: string; email: string; userId: string}; ProfileOnboarding: {username: string; userId: string}; }; diff --git a/src/screens/onboarding/Checkpoint.tsx b/src/screens/onboarding/Checkpoint.tsx new file mode 100644 index 00000000..013a80d2 --- /dev/null +++ b/src/screens/onboarding/Checkpoint.tsx @@ -0,0 +1,144 @@ +import React from 'react'; +import {RouteProp} from '@react-navigation/native'; +import {StackNavigationProp} from '@react-navigation/stack'; +import { + View, + Text, + StyleSheet, + StatusBar, + Platform, + TouchableOpacity, +} from 'react-native'; + +import {RootStackParamList, AuthContext} from '../../routes'; +import {RegistrationWizard, Background} from '../../components'; + +type CheckpointRouteProp = RouteProp<RootStackParamList, 'Checkpoint'>; +type CheckpointNavigationProp = StackNavigationProp< + RootStackParamList, + 'Checkpoint' +>; +interface CheckpointProps { + route: CheckpointRouteProp; + navigation: CheckpointNavigationProp; +} +/** + * Registration screen 2 for email, username, password, and terms and conditions + * @param navigation react-navigation navigation object + */ +const Checkpoint: React.FC<CheckpointProps> = ({route, navigation}) => { + const {userId, username} = route.params; + + /** + * login: determines if user successully created an account to + * navigate to home and display main tab navigation bar + */ + const {login} = React.useContext(AuthContext); + + const handleSkip = () => { + login(userId, username); + }; + + const handleProceed = () => { + navigation.navigate('ProfileOnboarding', { + userId: userId, + username: username, + }); + }; + + return ( + <Background style={styles.container}> + <StatusBar barStyle="light-content" /> + <RegistrationWizard style={styles.wizard} step="four" /> + + <View style={styles.textContainer}> + <Text style={styles.header}>Email verified!</Text> + <Text style={styles.subtext}> + We're almost there. Would you like to setup your profile now? + </Text> + <View style={styles.buttonContainer}> + <TouchableOpacity onPress={handleSkip} style={styles.skipButton}> + <Text style={styles.skipButtonLabel}>Do it later</Text> + </TouchableOpacity> + <TouchableOpacity + onPress={handleProceed} + style={styles.proceedButton}> + <Text style={styles.proceedButtonLabel}>Let's do it!</Text> + </TouchableOpacity> + </View> + </View> + </Background> + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + }, + textContainer: { + marginTop: '65%', + }, + + buttonContainer: { + flexDirection: 'row', + justifyContent: 'space-evenly', + }, + wizard: { + ...Platform.select({ + ios: { + top: 50, + }, + android: { + bottom: 40, + }, + }), + }, + header: { + color: '#fff', + fontSize: 22, + fontWeight: '600', + textAlign: 'center', + marginBottom: '4%', + marginHorizontal: '10%', + }, + subtext: { + color: '#fff', + fontSize: 14, + fontWeight: '600', + textAlign: 'center', + marginBottom: '16%', + marginHorizontal: '10%', + }, + proceedButton: { + backgroundColor: '#8F01FF', + justifyContent: 'center', + alignItems: 'center', + width: 150, + height: 40, + borderRadius: 5, + marginTop: '5%', + }, + proceedButtonLabel: { + fontSize: 16, + fontWeight: '500', + color: '#fff', + }, + skipButton: { + justifyContent: 'center', + alignItems: 'center', + width: 150, + height: 40, + borderRadius: 5, + borderWidth: 1, + borderColor: '#ddd', + marginTop: '5%', + }, + skipButtonLabel: { + fontSize: 16, + fontWeight: '500', + color: '#ddd', + }, +}); + +export default Checkpoint; diff --git a/src/screens/onboarding/ProfileOnboarding.tsx b/src/screens/onboarding/ProfileOnboarding.tsx index 9405ca52..ea045434 100644 --- a/src/screens/onboarding/ProfileOnboarding.tsx +++ b/src/screens/onboarding/ProfileOnboarding.tsx @@ -10,11 +10,23 @@ import { Alert, View, } from 'react-native'; +import { + Background, + TaggBigInput, + TaggInput, + TaggDatePicker, + TaggDropDown, +} from '../../components'; import {OnboardingStackParams} from '../../routes/onboarding'; import {AuthContext} from '../../routes/authentication'; -import {Background} from '../../components'; import ImagePicker from 'react-native-image-crop-picker'; -import {REGISTER_ENDPOINT} from '../../constants'; +import { + REGISTER_ENDPOINT, + websiteRegex, + bioRegex, + genderRegex, +} from '../../constants'; +import moment from 'moment'; type ProfileOnboardingScreenRouteProp = RouteProp< OnboardingStackParams, @@ -36,8 +48,51 @@ interface ProfileOnboardingProps { const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({route}) => { const {userId, username} = route.params; - const [largePic, setLargePic] = React.useState(''); - const [smallPic, setSmallPic] = React.useState(''); + const [form, setForm] = React.useState({ + largePic: '', + smallPic: '', + website: '', + bio: '', + birthdate: '', + gender: '', + isValidWebsite: true, + isValidBio: true, + isValidGender: true, + attemptedSubmit: false, + }); + const [customGender, setCustomGender] = React.useState(); + + // refs for changing focus + const bioRef = React.useRef(); + const birthdateRef = React.useRef(); + const genderRef = React.useRef(); + const customGenderRef = React.useRef(); + /** + * Handles focus change to the next input field. + * @param field key for field to move focus onto + */ + const handleFocusChange = (field: string): void => { + switch (field) { + case 'bio': + const bioField: any = bioRef.current; + bioField.focus(); + break; + case 'birthdate': + const birthdateField: any = birthdateRef.current; + birthdateField.focus(); + break; + case 'gender': + const genderField: any = genderRef.current; + genderField.focus(); + break; + case 'customGender': + const customGenderField: any = customGenderRef.current; + customGenderField.focus(); + break; + default: + return; + } + }; /** * login: determines if user successully created an account to @@ -54,9 +109,9 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({route}) => { accessibilityLabel="ADD LARGE PROFILE PIC HERE" onPress={goToGalleryLargePic} style={styles.largeProfile}> - {largePic ? ( + {form.largePic ? ( <Image - source={{uri: largePic}} + source={{uri: form.largePic}} style={[styles.largeProfile, styles.profilePic]} /> ) : ( @@ -74,9 +129,9 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({route}) => { accessibilityLabel="ADD SMALLER PIC" onPress={goToGallerySmallPic} style={styles.smallProfile}> - {smallPic ? ( + {form.smallPic ? ( <Image - source={{uri: smallPic}} + source={{uri: form.smallPic}} style={[styles.smallProfile, styles.profilePic]} /> ) : ( @@ -99,7 +154,10 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({route}) => { }) .then((picture) => { if ('path' in picture) { - setLargePic(picture.path); + setForm({ + ...form, + largePic: picture.path, + }); } }) .catch(() => {}); @@ -120,28 +178,140 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({route}) => { }) .then((picture) => { if ('path' in picture) { - setSmallPic(picture.path); + setForm({ + ...form, + smallPic: picture.path, + }); } }) .catch(() => {}); }; + /* + * Handles changes to the website field value and verifies the input by updating state and running a validation function. + */ + const handleWebsiteUpdate = (website: string) => { + let isValidWebsite: boolean = websiteRegex.test(website); + setForm({ + ...form, + website, + isValidWebsite, + }); + }; + + /* + * Handles changes to the bio field value and verifies the input by updating state and running a validation function. + */ + const handleBioUpdate = (bio: string) => { + let isValidBio: boolean = bioRegex.test(bio); + setForm({ + ...form, + bio, + isValidBio, + }); + }; + + const handleGenderUpdate = (gender: string) => { + if (gender === 'custom') { + setCustomGender(true); + } else { + setCustomGender(false); + let isValidGender: boolean = true; + setForm({ + ...form, + gender, + isValidGender, + }); + } + }; + + const handleCustomGenderUpdate = (gender: string) => { + let isValidGender: boolean = genderRegex.test(gender); + gender = gender.replace(' ', '-'); + setForm({ + ...form, + gender, + isValidGender, + }); + }; + + const handleBirthdateUpdate = (birthdate: string) => { + setForm({ + ...form, + birthdate, + }); + }; + + const getMaxDate = () => { + const maxDate = moment().subtract(13, 'y').subtract(1, 'd'); + return maxDate.format('YYYY-MM-DD'); + }; + const handleSubmit = async () => { - const form = new FormData(); - if (largePic) { - form.append('largeProfilePicture', { - uri: largePic, + if (!form.attemptedSubmit) { + setForm({ + ...form, + attemptedSubmit: true, + }); + } + let invalidFields: boolean = false; + const request = new FormData(); + if (form.largePic) { + request.append('largeProfilePicture', { + uri: form.largePic, name: 'large_profile_pic.jpg', type: 'image/jpg', }); } - if (smallPic) { - form.append('smallProfilePicture', { - uri: smallPic, + if (form.smallPic) { + request.append('smallProfilePicture', { + uri: form.smallPic, name: 'small_profile_pic.jpg', type: 'image/jpg', }); } + if (form.website) { + if (form.isValidWebsite) { + request.append('website', form.website); + } else { + setForm({...form, attemptedSubmit: false}); + setTimeout(() => setForm({...form, attemptedSubmit: true})); + invalidFields = true; + } + } + + if (form.bio) { + if (form.isValidBio) { + request.append('biography', form.bio); + } else { + setForm({...form, attemptedSubmit: false}); + setTimeout(() => setForm({...form, attemptedSubmit: true})); + invalidFields = true; + } + } + + if (form.birthdate) { + request.append('birthday', form.birthdate); + } + + if (customGender) { + if (form.isValidGender) { + request.append('gender', form.gender); + } else { + setForm({...form, attemptedSubmit: false}); + setTimeout(() => setForm({...form, attemptedSubmit: true})); + invalidFields = true; + } + } else { + if (form.isValidGender) { + request.append('gender', form.gender); + } + } + + if (invalidFields) { + return; + } + const endpoint = REGISTER_ENDPOINT + `${userId}/`; try { let response = await fetch(endpoint, { @@ -149,7 +319,7 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({route}) => { headers: { 'Content-Type': 'multipart/form-data', }, - body: form, + body: request, }); let statusCode = response.status; let data = await response.json(); @@ -178,14 +348,82 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({route}) => { return ( <Background centered> <StatusBar barStyle="light-content" /> - <LargeProfilePic /> - <SmallProfilePic /> - <View style={styles.dummyField}> - <Text>DUMMY WEBSITE</Text> - </View> - <View style={styles.dummyField}> - <Text>DUMMY BIO</Text> + <View style={styles.profile}> + <LargeProfilePic /> + <SmallProfilePic /> </View> + <TaggInput + accessibilityHint="Enter a website." + accessibilityLabel="Website input field." + placeholder="Website" + autoCompleteType="off" + textContentType="URL" + autoCapitalize="none" + returnKeyType="next" + onChangeText={handleWebsiteUpdate} + onSubmitEditing={() => handleFocusChange('bio')} + blurOnSubmit={false} + valid={form.isValidWebsite} + attemptedSubmit={form.attemptedSubmit} + invalidWarning={'Website must be a valid link to your website'} + width={280} + /> + <TaggBigInput + accessibilityHint="Enter a bio." + accessibilityLabel="Bio input field." + placeholder="Bio" + autoCompleteType="off" + textContentType="none" + autoCapitalize="none" + returnKeyType="next" + onChangeText={handleBioUpdate} + onSubmitEditing={() => handleFocusChange('bio')} + blurOnSubmit={false} + ref={bioRef} + valid={form.isValidBio} + attemptedSubmit={form.attemptedSubmit} + invalidWarning={ + 'Bio must be less than 150 characters and must contain valid characters' + } + width={280} + /> + <TaggDatePicker + date={form.birthdate} + maxDate={getMaxDate()} + onDateChange={(birthdate) => handleBirthdateUpdate(birthdate)} + /> + <TaggDropDown + onValueChange={(value) => handleGenderUpdate(value)} + items={[ + {label: 'Male', value: 'male'}, + {label: 'Female', value: 'female'}, + {label: 'Custom', value: 'custom'}, + ]} + placeholder={{ + label: 'Gender', + value: null, + color: '#ddd', + }} + /> + {customGender && ( + <TaggInput + accessibilityHint="Custom" + accessibilityLabel="Gender input field." + placeholder="Enter your gender" + autoCompleteType="off" + textContentType="none" + autoCapitalize="none" + returnKeyType="next" + blurOnSubmit={false} + ref={customGenderRef} + onChangeText={handleCustomGenderUpdate} + onSubmitEditing={() => handleSubmit()} + valid={form.isValidGender} + attemptedSubmit={form.attemptedSubmit} + invalidWarning={'Custom field can only contain letters and hyphens'} + width={280} + /> + )} <TouchableOpacity onPress={handleSubmit} style={styles.submitBtn}> <Text style={styles.submitBtnLabel}>Let's start!</Text> </TouchableOpacity> @@ -194,6 +432,10 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({route}) => { }; const styles = StyleSheet.create({ + profile: { + flexDirection: 'row', + marginBottom: '5%', + }, largeProfile: { justifyContent: 'center', alignItems: 'center', @@ -202,7 +444,8 @@ const styles = StyleSheet.create({ width: 230, borderRadius: 23, backgroundColor: '#fff', - marginRight: '6%', + marginLeft: '13%', + marginTop: '5%', }, largeProfileText: { textAlign: 'center', @@ -218,8 +461,8 @@ const styles = StyleSheet.create({ width: 110, borderRadius: 55, backgroundColor: '#E1F0FF', - marginLeft: '45%', - bottom: '7%', + right: '18%', + marginTop: '38%', }, smallProfileText: { textAlign: 'center', @@ -232,16 +475,6 @@ const styles = StyleSheet.create({ marginLeft: 0, bottom: 0, }, - dummyField: { - height: '10%', - width: '80%', - justifyContent: 'center', - alignItems: 'center', - borderColor: '#fff', - borderWidth: 1, - borderRadius: 8, - marginBottom: '10%', - }, submitBtn: { backgroundColor: '#8F01FF', justifyContent: 'center', @@ -249,6 +482,7 @@ const styles = StyleSheet.create({ width: 150, height: 40, borderRadius: 5, + marginTop: '5%', }, submitBtnLabel: { fontSize: 16, diff --git a/src/screens/onboarding/Verification.tsx b/src/screens/onboarding/Verification.tsx index 0676bb3a..7c74324a 100644 --- a/src/screens/onboarding/Verification.tsx +++ b/src/screens/onboarding/Verification.tsx @@ -59,7 +59,7 @@ const Verification: React.FC<VerificationProps> = ({route, navigation}) => { }); let statusCode = verifyOtpResponse.status; if (statusCode === 200) { - navigation.navigate('ProfileOnboarding', { + navigation.navigate('Checkpoint', { userId: userId, username: username, }); diff --git a/src/screens/onboarding/index.ts b/src/screens/onboarding/index.ts index 7a9816e7..e6627ca7 100644 --- a/src/screens/onboarding/index.ts +++ b/src/screens/onboarding/index.ts @@ -1,5 +1,6 @@ export {default as Login} from './Login'; -export {default as ProfileOnboarding} from './ProfileOnboarding'; export {default as RegistrationOne} from './RegistrationOne'; export {default as RegistrationTwo} from './RegistrationTwo'; export {default as Verification} from './Verification'; +export {default as Checkpoint} from './Checkpoint'; +export {default as ProfileOnboarding} from './ProfileOnboarding'; |