import AsyncStorage from '@react-native-community/async-storage'; import {RouteProp} from '@react-navigation/native'; 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, LoadingIndicator, RegistrationWizard, TaggInput, TermsConditions, } from '../../components'; import {emailRegex, passwordRegex, usernameRegex} from '../../constants'; import { ERROR_DOUBLE_CHECK_CONNECTION, ERROR_REGISTRATION, ERROR_SOMETHING_WENT_WRONG_REFRESH, } from '../../constants/strings'; import {OnboardingStackParams} from '../../routes'; import {sendRegister} from '../../services'; import {BackgroundGradientType} from '../../types'; import {SCREEN_HEIGHT} from '../../utils'; type OnboardingStepTwoRouteProp = RouteProp< OnboardingStackParams, 'OnboardingStepTwo' >; type OnboardingStepTwoNavigationProp = StackNavigationProp< OnboardingStackParams, 'OnboardingStepTwo' >; interface OnboardingStepTwoProps { route: OnboardingStepTwoRouteProp; navigation: OnboardingStepTwoNavigationProp; } const OnboardingStepTwo: React.FC = ({ route, navigation, }) => { const emailRef = useRef(); const usernameRef = useRef(); const passwordRef = useRef(); const confirmRef = useRef(); const handleFocusChange = (field: string): void => { switch (field) { case 'email': const emailField: any = emailRef.current; emailField.focus(); break; case 'username': const usernameField: any = usernameRef.current; usernameField.focus(); break; case 'password': const passwordField: any = passwordRef.current; passwordField.focus(); break; case 'confirm': const confirmField: any = confirmRef.current; confirmField.focus(); break; default: return; } }; // registration form state const [form, setForm] = useState({ email: '', username: '', password: '', confirm: '', isValidEmail: false, isValidUsername: false, isValidPassword: false, passwordsMatch: false, tcAccepted: false, attemptedSubmit: false, }); const handleEmailUpdate = (email: string) => { email = email.trim(); let isValidEmail: boolean = emailRegex.test(email); setForm({ ...form, email, isValidEmail, }); }; const handleUsernameUpdate = (username: string) => { let isValidUsername: boolean = usernameRegex.test(username); setForm({ ...form, username, isValidUsername, }); }; const handlePasswordUpdate = (password: string) => { let isValidPassword: boolean = passwordRegex.test(password); let passwordsMatch: boolean = form.password === form.confirm; setForm({ ...form, password, isValidPassword, passwordsMatch, }); }; const handleConfirmUpdate = (confirm: string) => { let passwordsMatch: boolean = form.password === confirm; setForm({ ...form, confirm, passwordsMatch, }); }; const handleTcUpdate = (tcAccepted: boolean) => { setForm({ ...form, tcAccepted, }); }; const handleRegister = async () => { if (!form.attemptedSubmit) { setForm({ ...form, attemptedSubmit: true, }); } const { isValidEmail, isValidUsername, isValidPassword, passwordsMatch, tcAccepted, } = form; try { if ( isValidEmail && isValidUsername && isValidPassword && passwordsMatch ) { if (tcAccepted) { const {email, username, password} = form; const {firstName, lastName, phone} = route.params; const response = await sendRegister( firstName, lastName, phone, email, username, password, ); if (response) { const data = await response.json(); const {token, UserID} = data; switch (response.status) { case 201: await AsyncStorage.setItem('token', token); navigation.navigate('OnboardingStepThree', { userId: UserID, username: username, }); break; case 400: Alert.alert(ERROR_REGISTRATION(data.toLowerCase())); break; default: Alert.alert(ERROR_SOMETHING_WENT_WRONG_REFRESH); break; } } else { Alert.alert(ERROR_SOMETHING_WENT_WRONG_REFRESH); } } else { Alert.alert( 'Terms and conditions', 'You must first agree to the terms and conditions.', ); } } else { setForm({...form, attemptedSubmit: false}); setTimeout(() => setForm({...form, attemptedSubmit: true})); } } catch (error) { Alert.alert(ERROR_REGISTRATION(ERROR_DOUBLE_CHECK_CONNECTION)); return { name: 'Registration error', description: error, }; } }; const footer = useMemo( () => ( navigation.navigate('PhoneVerification', {...route.params}) } /> ), [ form.email, form.username, form.password, form.confirm, form.isValidEmail, form.isValidUsername, form.isValidPassword, form.passwordsMatch, form.tcAccepted, ], ); return ( SIGN UP handleFocusChange('password')} blurOnSubmit={false} ref={usernameRef} valid={form.isValidUsername} invalidWarning={ 'Username must beĀ at least 6 characters and contain only alphanumerics.' } attemptedSubmit={form.attemptedSubmit} width={280} /> handleFocusChange('confirm')} blurOnSubmit={false} secureTextEntry ref={passwordRef} valid={form.isValidPassword} invalidWarning={ 'Password must be at least 8 characters & contain at least one of a-z, A-Z, 0-9, and a special character.' } attemptedSubmit={form.attemptedSubmit} width={280} /> {footer} ); }; 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%', }, tc: { marginVertical: '5%', }, load: { top: '5%', }, footer: { width: '100%', flexDirection: 'row', justifyContent: 'space-around', ...Platform.select({ ios: { bottom: '20%', }, android: { bottom: '10%', }, }), }, }); export default OnboardingStepTwo;