import {useReducer} from 'react' import {View} from 'react-native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {wait} from '#/lib/async/wait' import {useCleanError} from '#/lib/hooks/useCleanError' import {logger} from '#/logger' import {useSession} from '#/state/session' import {atoms as a, useTheme} from '#/alf' import {Admonition} from '#/components/Admonition' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {ResendEmailText} from '#/components/dialogs/EmailDialog/components/ResendEmailText' import { isValidCode, TokenField, } from '#/components/dialogs/EmailDialog/components/TokenField' import {useConfirmEmail} from '#/components/dialogs/EmailDialog/data/useConfirmEmail' import {useRequestEmailVerification} from '#/components/dialogs/EmailDialog/data/useRequestEmailVerification' import {useOnEmailVerified} from '#/components/dialogs/EmailDialog/events' import { ScreenID, type ScreenProps, } from '#/components/dialogs/EmailDialog/types' import {Divider} from '#/components/Divider' import {CheckThick_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check' import {Envelope_Stroke2_Corner0_Rounded as Envelope} from '#/components/icons/Envelope' import {createStaticClick, InlineLinkText} from '#/components/Link' import {Loader} from '#/components/Loader' import {Span, Text} from '#/components/Typography' type State = { step: 'email' | 'token' | 'success' mutationStatus: 'pending' | 'success' | 'error' | 'default' error: string token: string } type Action = | { type: 'setStep' step: State['step'] } | { type: 'setError' error: string } | { type: 'setMutationStatus' status: State['mutationStatus'] } | { type: 'setToken' value: string } function reducer(state: State, action: Action): State { switch (action.type) { case 'setStep': { return { ...state, error: '', mutationStatus: 'default', step: action.step, } } case 'setError': { return { ...state, error: action.error, mutationStatus: 'error', } } case 'setMutationStatus': { return { ...state, error: '', mutationStatus: action.status, } } case 'setToken': { return { ...state, error: '', token: action.value, } } } } export function Verify({config, showScreen}: ScreenProps) { const t = useTheme() const {_} = useLingui() const cleanError = useCleanError() const {currentAccount} = useSession() const [state, dispatch] = useReducer(reducer, { step: 'email', mutationStatus: 'default', error: '', token: '', }) const {mutateAsync: requestEmailVerification} = useRequestEmailVerification() const {mutateAsync: confirmEmail} = useConfirmEmail() useOnEmailVerified(() => { if (config.onVerify) { config.onVerify() } else { dispatch({ type: 'setStep', step: 'success', }) } }) const handleRequestEmailVerification = async () => { dispatch({ type: 'setMutationStatus', status: 'pending', }) try { await wait(1000, requestEmailVerification()) dispatch({ type: 'setMutationStatus', status: 'success', }) } catch (e) { logger.error('EmailDialog: sending verification email failed', { safeMessage: e, }) const {clean} = cleanError(e) dispatch({ type: 'setError', error: clean || _(msg`Failed to send email, please try again.`), }) } } const handleConfirmEmail = async () => { if (!isValidCode(state.token)) { dispatch({ type: 'setError', error: _(msg`Please enter a valid code.`), }) return } dispatch({ type: 'setMutationStatus', status: 'pending', }) try { await wait(1000, confirmEmail({token: state.token})) dispatch({ type: 'setStep', step: 'success', }) } catch (e) { logger.error('EmailDialog: confirming email failed', { safeMessage: e, }) const {clean} = cleanError(e) dispatch({ type: 'setError', error: clean || _(msg`Failed to verify email, please try again.`), }) } } if (state.step === 'success') { return ( {' '} Email verification complete! You have successfully verified your email address. You can close this dialog. ) } return ( {state.step === 'email' ? ( state.mutationStatus === 'success' ? ( <> {' '} Email sent! ) : ( Verify your email ) ) : ( Verify email code )} {state.step === 'email' && state.mutationStatus !== 'success' && ( <> {config.instructions?.map((int, i) => ( {int} ))} )} {state.step === 'email' ? ( state.mutationStatus === 'success' ? ( We sent an email to{' '} {currentAccount!.email} {' '} containing a link. Please click on it to complete the email verification process. ) : ( We'll send an email to{' '} {currentAccount!.email} {' '} containing a link. Please click on it to complete the email verification process. ) ) : ( Please enter the code we sent to{' '} {currentAccount!.email} {' '} below. )} {state.step === 'email' && state.mutationStatus !== 'success' && ( If you need to update your email,{' '} { showScreen({id: ScreenID.Update}) })}> click here . )} {state.step === 'email' && state.mutationStatus === 'success' && ( )} {state.step === 'email' && state.mutationStatus !== 'success' ? ( <> {state.error && {state.error}} ) : null} {state.step === 'email' && ( <> Have a code?{' '} { dispatch({ type: 'setStep', step: 'token', }) })}> Click here. )} {state.step === 'token' ? ( <> { dispatch({ type: 'setToken', value: token, }) }} onSubmitEditing={handleConfirmEmail} /> {state.error && {state.error}} Don't have a code or need a new one?{' '} { dispatch({ type: 'setStep', step: 'email', }) })}> Click here. ) : null} ) }