aboutsummaryrefslogtreecommitdiff
path: root/src/screens/onboarding/OnboardingStepOne.tsx
diff options
context:
space:
mode:
authorIvan Chen <ivan@tagg.id>2021-03-05 16:38:32 -0500
committerIvan Chen <ivan@tagg.id>2021-03-05 16:38:32 -0500
commit1465df9621fb963ff873485ad927ff79ea547fa0 (patch)
treeaffcb43f37f263f3e0e555dd019dd952b62e1f0a /src/screens/onboarding/OnboardingStepOne.tsx
parent2360e774d94e271d1d9db0d5b92b801b9325535e (diff)
parentb1dee65ee7bb8e120fc38a495f4027905d300650 (diff)
Merge branch 'master' into tma-634-badge-selection-screen
# Conflicts: # src/components/taggs/SocialMediaInfo.tsx
Diffstat (limited to 'src/screens/onboarding/OnboardingStepOne.tsx')
-rw-r--r--src/screens/onboarding/OnboardingStepOne.tsx263
1 files changed, 263 insertions, 0 deletions
diff --git a/src/screens/onboarding/OnboardingStepOne.tsx b/src/screens/onboarding/OnboardingStepOne.tsx
new file mode 100644
index 00000000..0fa7a6a5
--- /dev/null
+++ b/src/screens/onboarding/OnboardingStepOne.tsx
@@ -0,0 +1,263 @@
+import {StackNavigationProp} from '@react-navigation/stack';
+import React, {useMemo, useRef, useState} from 'react';
+import {
+ Alert,
+ KeyboardAvoidingView,
+ Platform,
+ StatusBar,
+ StyleSheet,
+ Text,
+ TouchableOpacity,
+ View,
+} from 'react-native';
+import {
+ ArrowButton,
+ Background,
+ RegistrationWizard,
+ TaggInput,
+} from '../../components';
+import {nameRegex, phoneRegex} 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} from '../../utils';
+
+type OnboardingStepOneNavigationProp = StackNavigationProp<
+ OnboardingStackParams,
+ 'OnboardingStepOne'
+>;
+interface OnboardingStepOneProps {
+ navigation: OnboardingStepOneNavigationProp;
+}
+
+const OnboardingStepOne: React.FC<OnboardingStepOneProps> = ({navigation}) => {
+ const lnameRef = useRef();
+ const emailRef = useRef();
+ const phoneRef = useRef();
+
+ const handleFocusChange = (field: string): void => {
+ switch (field) {
+ case 'lname':
+ const lnameField: any = lnameRef.current;
+ lnameField.focus();
+ break;
+ case 'email':
+ const emailField: any = emailRef.current;
+ emailField.focus();
+ break;
+ case 'phone':
+ const phoneField: any = phoneRef.current;
+ phoneField.focus();
+ break;
+ default:
+ return;
+ }
+ };
+
+ const [form, setForm] = useState({
+ fname: '',
+ lname: '',
+ phone: '',
+ isValidFname: false,
+ isValidLname: false,
+ isValidPhone: false,
+ attemptedSubmit: false,
+ token: '',
+ });
+
+ const handleFnameUpdate = (fname: string) => {
+ fname = fname.trim();
+ let isValidFname: boolean = nameRegex.test(fname);
+ setForm({
+ ...form,
+ fname,
+ isValidFname,
+ });
+ };
+
+ const handleLnameUpdate = (lname: string) => {
+ lname = lname.trim();
+ let isValidLname: boolean = nameRegex.test(lname);
+ setForm({
+ ...form,
+ lname,
+ isValidLname,
+ });
+ };
+
+ const handlePhoneUpdate = (phone: string) => {
+ phone = phone.trim();
+ let isValidPhone: boolean = phoneRegex.test(phone);
+ setForm({
+ ...form,
+ phone,
+ isValidPhone,
+ });
+ };
+
+ const goNext = async () => {
+ if (!form.attemptedSubmit) {
+ setForm({
+ ...form,
+ attemptedSubmit: true,
+ });
+ }
+ try {
+ if (form.isValidFname && form.isValidLname && form.isValidPhone) {
+ const code = await sendOtpStatusCode(form.phone);
+ if (code) {
+ switch (code) {
+ case 200:
+ navigation.navigate('PhoneVerification', {
+ firstName: form.fname,
+ lastName: form.lname,
+ phone: form.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,
+ };
+ }
+ };
+
+ 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>
+ ),
+ [form.isValidFname, form.isValidLname, form.isValidPhone],
+ );
+
+ return (
+ <Background
+ style={styles.container}
+ gradientType={BackgroundGradientType.Light}>
+ <StatusBar barStyle="light-content" />
+ <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>
+ <TaggInput
+ accessibilityHint="Enter your first name."
+ accessibilityLabel="First name input field."
+ placeholder="First Name"
+ autoCompleteType="name"
+ textContentType="name"
+ returnKeyType="next"
+ onChangeText={handleFnameUpdate}
+ onSubmitEditing={() => handleFocusChange('lname')}
+ blurOnSubmit={false}
+ valid={form.isValidFname}
+ invalidWarning="Please enter a valid first name."
+ attemptedSubmit={form.attemptedSubmit}
+ width={280}
+ />
+ <TaggInput
+ accessibilityHint="Enter your last name."
+ accessibilityLabel="Last name input field."
+ placeholder="Last Name"
+ autoCompleteType="name"
+ textContentType="name"
+ returnKeyType="next"
+ onChangeText={handleLnameUpdate}
+ blurOnSubmit={false}
+ ref={lnameRef}
+ valid={form.isValidLname}
+ invalidWarning="Please enter a valid last name."
+ attemptedSubmit={form.attemptedSubmit}
+ width={280}
+ />
+ <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}
+ ref={phoneRef}
+ valid={form.isValidPhone}
+ invalidWarning={'Please enter a valid 10 digit number.'}
+ attemptedSubmit={form.attemptedSubmit}
+ width={280}
+ onSubmitEditing={goNext}
+ />
+ </KeyboardAvoidingView>
+ {footer}
+ </Background>
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ wizard: {
+ position: 'absolute',
+ top: SCREEN_HEIGHT * 0.1,
+ },
+ formHeader: {
+ color: '#fff',
+ fontSize: 30,
+ fontWeight: '600',
+ marginBottom: '16%',
+ },
+ load: {
+ top: '5%',
+ },
+ footer: {
+ width: '100%',
+ flexDirection: 'row',
+ justifyContent: 'space-around',
+ ...Platform.select({
+ ios: {
+ bottom: '20%',
+ },
+ android: {
+ bottom: '10%',
+ },
+ }),
+ },
+});
+
+export default OnboardingStepOne;