From 90cb1ac41fffbbd0833525a8580f6b4756d2e6f9 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Fri, 25 Apr 2025 15:34:56 -0500 Subject: [PATCH] Handle token step --- .../EmailDialog/data/useConfirmEmail.ts | 22 +++++ .../dialogs/EmailDialog/screens/Verify.tsx | 92 +++++++++++++++++-- 2 files changed, 105 insertions(+), 9 deletions(-) create mode 100644 src/components/dialogs/EmailDialog/data/useConfirmEmail.ts diff --git a/src/components/dialogs/EmailDialog/data/useConfirmEmail.ts b/src/components/dialogs/EmailDialog/data/useConfirmEmail.ts new file mode 100644 index 0000000000..fa7c8b2d2f --- /dev/null +++ b/src/components/dialogs/EmailDialog/data/useConfirmEmail.ts @@ -0,0 +1,22 @@ +import {useMutation} from '@tanstack/react-query' + +import {useAgent, useSession} from '#/state/session' + +export function useConfirmEmail() { + const agent = useAgent() + const {currentAccount} = useSession() + + return useMutation({ + mutationFn: async ({token}: {token: string}) => { + if (!currentAccount?.email) { + throw new Error('No email found for the current account') + } + + await agent.com.atproto.server.confirmEmail({ + email: currentAccount.email, + token: token.trim(), + }) + await agent.resumeSession(agent.session!) + }, + }) +} diff --git a/src/components/dialogs/EmailDialog/screens/Verify.tsx b/src/components/dialogs/EmailDialog/screens/Verify.tsx index fe67e3a25d..e09ffeddea 100644 --- a/src/components/dialogs/EmailDialog/screens/Verify.tsx +++ b/src/components/dialogs/EmailDialog/screens/Verify.tsx @@ -10,6 +10,8 @@ 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 {TokenField} from '#/components/dialogs/EmailDialog/components/TokenField' +import {useConfirmEmail} from '#/components/dialogs/EmailDialog/data/useConfirmEmail' import {useRequestEmailVerification} from '#/components/dialogs/EmailDialog/data/useRequestEmailVerification' import {type Screen} from '#/components/dialogs/EmailDialog/types' import {Divider} from '#/components/Divider' @@ -25,17 +27,25 @@ export function Verify(_props: {config: Exclude}) { const {currentAccount} = useSession() const [error, setError] = useState('') - const [sentEmail, setSentEmail] = useState(false) + const [step, setStep] = useState< + 'default' | 'sent' | 'token' | 'tokenConfirmed' + >('default') const [sendingStatus, setSendingStatus] = useState<'sending' | null>(null) const {mutateAsync: requestEmailVerification} = useRequestEmailVerification() + const [token, setToken] = useState('') + const [confirmingStatus, setConfirmingStatus] = useState<'sending' | null>( + null, + ) + const {mutateAsync: confirmEmail} = useConfirmEmail() + const handleRequestEmailVerification = async () => { setError('') setSendingStatus('sending') try { await wait(1000, requestEmailVerification()) - setSentEmail(true) + setStep('sent') } catch (e) { logger.error('EmailDialog: sending verification email failed', { safeMessage: e, @@ -46,24 +56,48 @@ export function Verify(_props: {config: Exclude}) { } } + const handleConfirmEmail = async () => { + setError('') + setConfirmingStatus('sending') + + try { + await wait(1000, confirmEmail({token})) + setStep('tokenConfirmed') + } catch (e) { + logger.error('EmailDialog: confirming email failed', { + safeMessage: e, + }) + setError(_(msg`Failed to verify email, please try again.`)) + } finally { + setConfirmingStatus(null) + } + } + return ( - {sentEmail ? ( + {step === 'sent' ? ( <> {' '} Email sent! + ) : step === 'tokenConfirmed' ? ( + <> + + + {' '} + Email verification complete + ) : ( Verify email )} - {sentEmail ? ( + {step === 'sent' ? ( We sent an email to{' '} @@ -72,6 +106,19 @@ export function Verify(_props: {config: Exclude}) { containing a link. Click on it to complete the email verification process. + ) : step === 'token' ? ( + + Enter the code we sent to{' '} + + {currentAccount!.email} + {' '} + below. + + ) : step === 'tokenConfirmed' ? ( + + You have successfully verified your email address. You can close + this dialog. + ) : ( We'll send you an email to{' '} @@ -84,10 +131,12 @@ export function Verify(_props: {config: Exclude}) { )} - {sentEmail && } + {step === 'sent' && ( + + )} - {!sentEmail && ( + {step === 'default' ? ( <> {error && {error} } @@ -95,7 +144,7 @@ export function Verify(_props: {config: Exclude}) { label={_(msg`Send verification email`)} size="large" variant="solid" - color={'primary'} + color="primary" onPress={handleRequestEmailVerification} disabled={sendingStatus === 'sending'}> @@ -114,13 +163,38 @@ export function Verify(_props: {config: Exclude}) { Have a code?{' '} {})}> + {...createStaticClick(() => { + setStep('token') + })}> Click here. - )} + ) : step === 'token' ? ( + <> + {}} + /> + + {error && {error} } + + + + ) : null} ) }