diff options
-rw-r--r-- | src/components/onboarding/TermsConditions.tsx | 4 | ||||
-rw-r--r-- | src/screens/onboarding/PhoneVerification.tsx | 6 | ||||
-rw-r--r-- | src/screens/onboarding/RevampedOnboarding.tsx | 320 |
3 files changed, 201 insertions, 129 deletions
diff --git a/src/components/onboarding/TermsConditions.tsx b/src/components/onboarding/TermsConditions.tsx index 08cd8228..9bd0ee3b 100644 --- a/src/components/onboarding/TermsConditions.tsx +++ b/src/components/onboarding/TermsConditions.tsx @@ -49,11 +49,11 @@ const TermsConditions: React.FC<TermsConditionsProps> = (props) => { <View style={styles.body}> <RadioCheckbox checked={accepted} onPress={toggleAccepted} /> <View style={styles.bodyPrompt}> - <Text style={styles.bodyPromptText}>I accept the </Text> + <Text style={styles.bodyPromptText}>Accept </Text> <TouchableOpacity onPress={() => setModalVisible(true)}> <Text style={[styles.bodyPromptText, styles.bodyPromptTextUnderline]}> - EULA & Terms of Service + Terms and Conditions </Text> </TouchableOpacity> </View> diff --git a/src/screens/onboarding/PhoneVerification.tsx b/src/screens/onboarding/PhoneVerification.tsx index a242b44b..9b517d9d 100644 --- a/src/screens/onboarding/PhoneVerification.tsx +++ b/src/screens/onboarding/PhoneVerification.tsx @@ -21,7 +21,6 @@ import { ArrowButton, Background, LoadingIndicator, - // RegistrationWizard, SubmitButton, } from '../../components'; import {codeRegex} from '../../constants'; @@ -92,7 +91,6 @@ const PhoneVerification: React.FC<PhoneVerificationProps> = ({ centered style={styles.container} gradientType={BackgroundGradientType.Light}> - {/* <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}> @@ -142,10 +140,6 @@ const styles = StyleSheet.create({ alignItems: 'center', justifyContent: 'center', }, - // 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 index 0d7f5c3c..782df6a1 100644 --- a/src/screens/onboarding/RevampedOnboarding.tsx +++ b/src/screens/onboarding/RevampedOnboarding.tsx @@ -1,7 +1,7 @@ -import {useNavigation} from '@react-navigation/core'; -import {RouteProp} from '@react-navigation/native'; -import {StackNavigationProp} from '@react-navigation/stack'; -import React, {useEffect, useState} from 'react'; +import { useNavigation } from '@react-navigation/core'; +import { RouteProp } from '@react-navigation/native'; +import { StackNavigationProp } from '@react-navigation/stack'; +import React, { useEffect, useState } from 'react'; import { Alert, KeyboardAvoidingView, @@ -9,13 +9,16 @@ import { StatusBar, StyleSheet, Text, + TouchableOpacity, View, } from 'react-native'; import { ArrowButton, Background, + LoadingIndicator, TaggInput, TaggSquareButton, + TermsConditions, } from '../../components'; import { emailRegex, @@ -29,10 +32,10 @@ import { 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'; +import { OnboardingStackParams } from '../../routes'; +import { sendOtpStatusCode } from '../../services'; +import { BackgroundGradientType } from '../../types'; +import { SCREEN_HEIGHT, SCREEN_WIDTH } from '../../utils'; type RevampedOnboardingRouteProp = RouteProp< OnboardingStackParams, @@ -47,14 +50,17 @@ interface RevampedOnboardingProps { navigation: RevampedOnboardingNavigationProp; } -const RevampedOnboarding: React.FC<RevampedOnboardingProps> = ({route}) => { - const {isPhoneVerified} = route.params; +const RevampedOnboarding: React.FC<RevampedOnboardingProps> = ({ route }) => { + const { isPhoneVerified } = route.params; const navigation = useNavigation(); type renderStatusType = 'firstName' | 'lastName' | 'username' | 'email'; const [attemptedSubmit, setAttemptedSubmit] = useState(false); // TODO: maybe use this? const [valid, setValid] = useState(false); + const [paswordsMatch, setPassMatch] = useState(false) const [currentStep, setCurrentStep] = useState(0); + const [tcAccepted, setTCAccepted] = useState(false); + const [passVisibility, setPassVisibility] = useState(false); const [form, setForm] = useState({ fname: '', lname: '', @@ -63,13 +69,13 @@ const RevampedOnboarding: React.FC<RevampedOnboardingProps> = ({route}) => { email: '', password: '', confirm: '', - isValidFname: false, - isValidLname: false, - isValidPhone: false, - isValidUser: false, - isValidEmail: false, - isValidPassword: false, - passwordsMatch: false, + // isValidFname: false, + // isValidLname: false, + // isValidPhone: false, + // isValidUser: false, + // isValidEmail: false, + // isValidPassword: false, + // passwordsMatch: false, token: '', }); @@ -78,14 +84,13 @@ const RevampedOnboarding: React.FC<RevampedOnboardingProps> = ({route}) => { setAttemptedSubmit(true); } try { - const {isValidPhone} = form; - if (isValidPhone) { - const {phone} = form; + if (valid) { + const { phone } = form; const code = await sendOtpStatusCode(phone); if (code) { switch (code) { case 200: - const {fname, lname} = form; + const { fname, lname } = form; navigation.navigate('PhoneVerification', { firstName: fname, lastName: lname, @@ -113,7 +118,6 @@ const RevampedOnboarding: React.FC<RevampedOnboardingProps> = ({route}) => { }; } }; - // 0 = first name, 1 = last name, 2 = username, 3 = phone # const handleNameUpdate = (name: string, nameType: number) => { name = name.trim(); @@ -123,106 +127,160 @@ const RevampedOnboarding: React.FC<RevampedOnboardingProps> = ({route}) => { setForm({ ...form, fname: name, - isValidFname: isValidName, }); + setValid(isValidName) break; case 1: setForm({ ...form, lname: name, - isValidLname: isValidName, }); + setValid(isValidName) break; case 2: setForm({ ...form, username: name, - isValidUser: usernameRegex.test(name), - }); - break; - case 3: - setForm({ - ...form, - phone: name, - isValidPhone: phoneRegex.test(name), }); + setValid(usernameRegex.test(name)) break; } }; const handlePhoneUpdate = (phone: string) => { phone = phone.trim(); - let isValidPhone: boolean = phoneRegex.test(phone); setForm({ ...form, phone, - isValidPhone, }); + setValid(phoneRegex.test(phone)) }; const handleEmailUpdate = (email: string) => { email = email.trim(); - let isValidEmail: boolean = emailRegex.test(email); setForm({ ...form, email, - isValidEmail, }); + setValid(emailRegex.test(email)) }; const handlePasswordUpdate = (password: string) => { - let isValidPassword: boolean = passwordRegex.test(password); - let passwordsMatch: boolean = form.password === form.confirm; setForm({ ...form, password, - isValidPassword, - passwordsMatch, }); + setValid(passwordRegex.test(password)); + setPassMatch(form.password === form.confirm) + }; + const handleConfirmUpdate = (confirm: string) => { + let passwordsMatch: boolean = form.password === confirm; + setForm({ + ...form, + confirm, + }); + setPassMatch(form.password === form.confirm) + }; + const handleTcUpdate = (tcAccepted: boolean) => { + setTCAccepted(tcAccepted); }; - const formSteps: { placeholder: string; - valid: () => boolean; + valid: boolean; onChangeText: (text: string) => void; }[] = [ - { - placeholder: 'First Name', - valid: () => form.isValidFname, - onChangeText: (text) => handleNameUpdate(text, 0), - }, - { - placeholder: 'Last Name', - valid: () => form.isValidLname, - onChangeText: (text) => handleNameUpdate(text, 1), - }, - { - placeholder: 'Phone', - valid: () => form.isValidPhone, - onChangeText: handlePhoneUpdate, - }, - { - placeholder: 'School Email', - valid: () => form.isValidEmail, - onChangeText: handleEmailUpdate, - }, - { - placeholder: 'Username', - valid: () => form.isValidLname, - onChangeText: (text) => handleNameUpdate(text, 2), - }, - { - placeholder: 'Password', - valid: () => form.isValidLname, - onChangeText: handlePasswordUpdate, - }, - // ... - ]; + { + placeholder: 'First Name', + valid: valid, + onChangeText: (text) => handleNameUpdate(text, 0), + }, + { + placeholder: 'Last Name', + valid: valid, + onChangeText: (text) => handleNameUpdate(text, 1), + }, + { + placeholder: 'Phone', + valid: valid, + onChangeText: handlePhoneUpdate, + }, + { + placeholder: 'School Email', + valid: valid, + onChangeText: handleEmailUpdate, + }, + { + placeholder: 'Username', + valid: valid, + onChangeText: (text) => handleNameUpdate(text, 2), + }, + { + placeholder: 'Password', + valid: valid, + onChangeText: handlePasswordUpdate, + }, + // ... + ]; + const resetForm = (formStep: String) => { + console.log(step.placeholder) + console.log(valid) + setValid(false); + console.log("after " + step.valid) + switch (formStep) { + case 'First Name': + setForm({ + ...form, + fname: '' + }) + break; + case 'Last Name': + setForm({ + ...form, + lname: '' + }) + break; + case 'Email': + setForm({ + ...form, + email: '' + }) + break; + case 'Password': + setForm({ + ...form, + password: '' + }) + break; + case 'School Email': + setForm({ + ...form, + email: '' + }) + break; + case 'Username': + setForm({ + ...form, + username: '' + }) + break; + } + } + const advance = () => { + setAttemptedSubmit(true); + console.log("valid? before: " + valid) + if (step.valid) { + setCurrentStep(currentStep + 1); + setAttemptedSubmit(false); + setValid(false); + } + console.log("valid? after: " + valid) + } + const togglePassVisibility = (passBool: boolean) => { + setPassVisibility(passBool); + } const step = formSteps[currentStep]; useEffect(() => { - // console.log('before: ' + currentStep + ' ' + step.placeholder); if (isPhoneVerified) { - setCurrentStep(currentStep + 1); + advance() } - // console.log('afgter: ' + currentStep + ' ' + step.placeholder); }, [isPhoneVerified]); return ( @@ -230,30 +288,31 @@ const RevampedOnboarding: React.FC<RevampedOnboardingProps> = ({route}) => { 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={styles.footer}> - {currentStep !== 0 && ( + {(currentStep !== 0 && currentStep !== 3) && ( <ArrowButton direction="backward" onPress={() => { - console.log('fooo'); + // if I go back do I want to reset the previous form? setCurrentStep(currentStep - 1); + resetForm(step.placeholder); + setAttemptedSubmit(false); }} /> )} </View> - <ArrowButton + {/* <ArrowButton direction="backward" onPress={() => { console.log('fooo'); setCurrentStep(currentStep - 1); - }} - /> + }} */} + {/* /> */} {step.placeholder === 'Phone' && !isPhoneVerified ? ( <> <TaggInput @@ -268,7 +327,7 @@ const RevampedOnboarding: React.FC<RevampedOnboardingProps> = ({route}) => { onChangeText={handlePhoneUpdate} autoFocus={true} blurOnSubmit={false} - valid={form.isValidPhone} + valid={valid} invalidWarning={'Please enter a valid 10 digit number.'} attemptedSubmit={attemptedSubmit} width={280} @@ -284,48 +343,64 @@ const RevampedOnboarding: React.FC<RevampedOnboardingProps> = ({route}) => { </> ) : ( <> - <Text style={styles.formHeader}>SIGN UP</Text> - <View style={{position: 'absolute', top: 50, borderWidth: 1}}> - <TaggInput - key={step.placeholder} - style={styles.input} - accessibilityHint={`Enter your ${step.placeholder.toLowerCase()}`} - accessibilityLabel={`${step.placeholder} input field.`} - placeholder={currentStep + ' ' + step.placeholder} - autoCompleteType="name" - textContentType="name" + {step.placeholder !== 'Password' ? ( + <><Text style={styles.formHeader}>SIGN UP</Text> + <View> + <TaggInput + key={step.placeholder} + style={styles.input} + accessibilityHint={`Enter your ${step.placeholder.toLowerCase()}`} + accessibilityLabel={`${step.placeholder} input field.`} + placeholder={currentStep + ' ' + step.placeholder} + autoCompleteType="name" + textContentType="name" + returnKeyType="next" + onChangeText={step.onChangeText} + onSubmitEditing={advance} + autoFocus={true} + blurOnSubmit={false} + valid={step.valid} + invalidWarning={`Please enter a valid ${step.placeholder.toLowerCase()}`} + attemptedSubmit={attemptedSubmit} + width={280} /> + <TaggSquareButton + onPress={advance} + autoFocus={true} + title={'Next'} + buttonStyle={'normal'} + buttonColor={'white'} + labelColor={'blue'} /> + </View></>) : ( + <><TaggInput + accessibilityHint="Enter a password." + accessibilityLabel="Password input field." + placeholder="Password" + autoCompleteType="password" + textContentType="oneTimeCode" returnKeyType="next" - onChangeText={step.onChangeText} - onSubmitEditing={() => { - setAttemptedSubmit(true); - if (step.valid()) { - setCurrentStep(currentStep + 1); - setAttemptedSubmit(false); - } - }} - autoFocus={true} + onChangeText={handlePasswordUpdate} + onSubmitEditing={advance} blurOnSubmit={false} - valid={step.valid()} - invalidWarning={`Please enter a valid ${step.placeholder.toLowerCase()}`} + secureTextEntry={passVisibility} + valid={valid} + invalidWarning={'Password must be at least 8 characters & contain at least one of a-z, A-Z, 0-9, and a special character.'} attemptedSubmit={attemptedSubmit} - width={280} - /> - {/* <TaggSquareButton - onPress={() => { - if (step.valid()) { - setCurrentStep(currentStep + 1); - } - }} - autoFocus={true} - title={'Next'} - buttonStyle={'normal'} - buttonColor={'white'} - labelColor={'blue'} - /> */} - </View> + width={280} /> + <TouchableOpacity onPress={() => togglePassVisibility(!passVisibility)}> + <Text + style={[styles.tc, styles.tc]}> + Show Password + </Text> + </TouchableOpacity> + <LoadingIndicator /> + <TermsConditions + style={styles.tc} + accepted={tcAccepted} + onChange={handleTcUpdate} /></> + )} </> )} - <View style={{position: 'absolute', bottom: 150}} /> + <View style={{ position: 'absolute', bottom: 150 }} /> </KeyboardAvoidingView> </Background> ); @@ -363,6 +438,9 @@ const styles = StyleSheet.create({ load: { top: '5%', }, + tc: { + marginVertical: '5%', + }, footer: { width: '100%', flexDirection: 'row', |