alf email confirmation dialog

This commit is contained in:
Hailey
2024-10-09 13:53:14 -07:00
parent 86b0d3b498
commit 95bea8bf6a
3 changed files with 227 additions and 7 deletions
@@ -0,0 +1,218 @@
import React from 'react'
import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {cleanError} from '#/lib/strings/errors'
import {logger} from '#/logger'
import {useModalControls} from '#/state/modals'
import {useAgent, useSession} from '#/state/session'
import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
import {atoms as a} from '#/alf'
import {Button, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
import * as TextField from '#/components/forms/TextField'
import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography'
export function VerifyEmailDialog({
control,
}: {
control: Dialog.DialogControlProps
}) {
return (
<Dialog.Outer control={control}>
<Dialog.Handle />
<Inner control={control} />
</Dialog.Outer>
)
}
export function Inner({control}: {control: Dialog.DialogControlProps}) {
const {_} = useLingui()
const {currentAccount} = useSession()
const agent = useAgent()
const {openModal} = useModalControls()
const [currentStep, setCurrentStep] = React.useState<
'StepOne' | 'StepTwo' | 'StepThree'
>('StepOne')
const [confirmationCode, setConfirmationCode] = React.useState('')
const [isProcessing, setIsProcessing] = React.useState(false)
const [error, setError] = React.useState('')
const uiStrings = {
StepOne: {
title: _(msg`Verify Your Email`),
message: '',
},
StepTwo: {
title: _(msg`Enter Code`),
message: _(
msg`An email has been sent! Please enter the confirmation code included in the email below.`,
),
},
StepThree: {
title: _(msg`Success!`),
message: _(msg`Thank you! Your email has been successfully verified.`),
},
}
const onSendEmail = async () => {
setError('')
setIsProcessing(true)
try {
await agent.com.atproto.server.requestEmailConfirmation()
setCurrentStep('StepTwo')
} catch (e: unknown) {
setError(cleanError(e))
} finally {
setIsProcessing(false)
}
}
const onVerifyEmail = async () => {
setError('')
setIsProcessing(true)
try {
await agent.com.atproto.server.confirmEmail({
email: (currentAccount?.email || '').trim(),
token: confirmationCode.trim(),
})
} catch (e: unknown) {
setError(cleanError(String(e)))
setIsProcessing(false)
return
}
try {
await agent.resumeSession(agent.session!)
} catch (e: unknown) {
setError(cleanError(String(e)))
setIsProcessing(false)
logger.error(String(e))
return
}
setIsProcessing(false)
setCurrentStep('StepThree')
}
return (
<Dialog.ScrollableInner label={_(msg`Verify email dialog`)}>
<View style={[a.gap_xl]}>
<View style={[a.gap_sm]}>
<Text style={[a.font_heavy, a.text_2xl]}>
{uiStrings[currentStep].title}
</Text>
{error ? (
<View style={[a.rounded_sm, a.overflow_hidden]}>
<ErrorMessage message={error} />
</View>
) : null}
<Text style={[a.text_md, a.leading_snug]}>
{currentStep === 'StepOne' ? (
<Trans>
You'll receive an email at{' '}
<Text style={[a.text_md, a.leading_snug, a.font_bold]}>
{currentAccount?.email}
</Text>{' '}
to verify it is you.
</Trans>
) : (
uiStrings[currentStep].message
)}
</Text>
</View>
{currentStep === 'StepTwo' ? (
<View>
<TextField.LabelText>
<Trans>Confirmation Code</Trans>
</TextField.LabelText>
<TextField.Root>
<TextField.Input
label={_(msg`Confirmation code`)}
placeholder="XXXXX-XXXXX"
onChangeText={setConfirmationCode}
/>
</TextField.Root>
</View>
) : null}
<View style={[a.gap_sm]}>
{currentStep === 'StepOne' ? (
<>
<Button
label={_(msg`Send confirmation email`)}
variant="solid"
color="primary"
size="large"
disabled={isProcessing}
onPress={onSendEmail}>
<ButtonText>
<Trans>Send Confirmation</Trans>
</ButtonText>
{isProcessing ? (
<Loader size="sm" style={[{color: 'white'}]} />
) : null}
</Button>
<Button
label={_(msg`Send confirmation email`)}
variant="ghost"
color="primary"
size="large"
disabled={isProcessing}
onPress={() => {
control.close(() => {
openModal({name: 'change-email'})
})
}}>
<ButtonText>
<Trans>Change Email</Trans>
</ButtonText>
</Button>
</>
) : currentStep === 'StepTwo' ? (
<>
<Button
label={_(msg`Confirm`)}
variant="solid"
color="primary"
size="large"
disabled={isProcessing}
onPress={onVerifyEmail}>
<ButtonText>
<Trans>Confirm</Trans>
</ButtonText>
</Button>
<Button
label={_(msg`Resend Email`)}
variant="ghost"
color="primary"
size="large"
disabled={isProcessing}
onPress={() => {
setConfirmationCode('')
setCurrentStep('StepOne')
}}>
<ButtonText>
<Trans>Resend Email</Trans>
</ButtonText>
</Button>
</>
) : currentStep === 'StepThree' ? (
<Button
label={_(msg`Confirm`)}
variant="solid"
color="primary"
size="large"
onPress={() => control.close()}>
<ButtonText>
<Trans>Close</Trans>
</ButtonText>
</Button>
) : null}
</View>
</View>
</Dialog.ScrollableInner>
)
}