import React from 'react'; import {OnboardingStackParams} from '../../routes'; import {RouteProp} from '@react-navigation/native'; import {StackNavigationProp} from '@react-navigation/stack'; import {Background, RegistrationWizard, SubmitButton} from '../../components'; import {VERIFY_OTP_ENDPOINT, SEND_OTP_ENDPOINT} from '../../constants'; import {Text} from 'react-native-animatable'; import { CodeField, Cursor, useBlurOnFulfill, useClearByFocusCell, } from 'react-native-confirmation-code-field'; import { StyleSheet, View, TouchableOpacity, KeyboardAvoidingView, Alert, ActivityIndicator, } from 'react-native'; import {usePromiseTracker, trackPromise} from 'react-promise-tracker'; type VerificationScreenRouteProp = RouteProp< OnboardingStackParams, 'Verification' >; type VerificationScreenNavigationProp = StackNavigationProp< OnboardingStackParams, 'Verification' >; interface VerificationProps { route: VerificationScreenRouteProp; navigation: VerificationScreenNavigationProp; } const Verification: React.FC = ({route, navigation}) => { const [value, setValue] = React.useState(''); const ref = useBlurOnFulfill({value, cellCount: 6}); const [valueProps, getCellOnLayoutHandler] = useClearByFocusCell({ value, setValue, }); const {username, email, userId} = route.params; /** * Sends the verify_otp request upon tapping the Verify button. * If successful, it navigates to the Profile page. */ const handleVerification = async () => { try { let verifyOtpResponse = await fetch(VERIFY_OTP_ENDPOINT, { method: 'POST', body: JSON.stringify({ username: username, otp: value, }), }); let statusCode = verifyOtpResponse.status; if (statusCode === 200) { navigation.navigate('Checkpoint', { userId: userId, username: username, }); } else { Alert.alert( 'Invalid verification code 🤔', 'Try again. Tap the resend code button if you need a new code.', ); } } catch (error) { Alert.alert( 'Verifiation failed 😓', 'Please double-check your network connection and retry.', ); return { name: 'Verification error', description: error, }; } }; /** * Sends the send_otp request so to provide a new verification code upon tapping the Resend Code button. */ const handleResend = async () => { try { let sendOtpResponse = await trackPromise( fetch(SEND_OTP_ENDPOINT, { method: 'POST', body: JSON.stringify({ username: username, email: email, }), }), ); let sendOtpStatusCode = sendOtpResponse.status; if (sendOtpStatusCode === 200) { setValue(''); Alert.alert( 'New verification code sent!', 'Check your email for your code.', ); } else { Alert.alert('Something went wrong!'); } } catch (error) { console.log(error); } }; /** * An activity indicator to indicate that the app is working during the send_otp request. */ const LoadingIndicator = () => { const {promiseInProgress} = usePromiseTracker(); return promiseInProgress ? ( ) : ( <> ); }; return ( Enter 6 digit code We sent a 6 digit verification code to the email you provided. ( {symbol || (isFocused ? : null)} )} /> Resend Code ); }; const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', }, wizard: { marginTop: '3.5%', flex: 1, justifyContent: 'center', }, form: { alignItems: 'center', justifyContent: 'flex-start', flex: 3, }, formHeader: { color: '#fff', fontSize: 20, fontWeight: 'bold', alignSelf: 'flex-start', marginBottom: '6%', marginHorizontal: '10%', }, description: { color: '#fff', fontWeight: '600', fontSize: 17, marginHorizontal: '10%', }, resend: { textDecorationLine: 'underline', color: '#fff', fontSize: 15, fontWeight: '600', }, codeFieldRoot: { width: 280, marginHorizontal: 'auto', marginVertical: '15%', }, cellRoot: { width: 40, height: 60, justifyContent: 'center', alignItems: 'center', borderBottomColor: '#fff', borderBottomWidth: 1, }, cellText: { color: '#fff', fontSize: 48, textAlign: 'center', }, focusCell: { borderBottomColor: '#78a0ef', borderBottomWidth: 2, }, button: { marginVertical: '5%', }, loadingIndicator: { marginVertical: '5%', }, }); export default Verification;