Fix email verification dialog (#10657)
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
import {useState} from 'react'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {wait} from '#/lib/async/wait'
|
||||
import {atoms as a, type TextStyleProp, useTheme} from '#/alf'
|
||||
@@ -14,10 +12,10 @@ export function ResendEmailText({
|
||||
onPress,
|
||||
style,
|
||||
}: TextStyleProp & {
|
||||
onPress: () => Promise<any>
|
||||
onPress: () => Promise<unknown>
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
const {t: l} = useLingui()
|
||||
const [status, setStatus] = useState<'sending' | 'success' | null>(null)
|
||||
|
||||
const handleOnPress = async () => {
|
||||
@@ -38,7 +36,7 @@ export function ResendEmailText({
|
||||
<Trans>
|
||||
Don't see an email?{' '}
|
||||
<InlineLinkText
|
||||
label={_(msg`Resend`)}
|
||||
label={l`Resend`}
|
||||
{...createStaticClick(() => {
|
||||
handleOnPress()
|
||||
})}>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {type TextInputProps, View} from 'react-native'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
|
||||
import * as TextField from '#/components/forms/TextField'
|
||||
import {Shield_Stroke2_Corner0_Rounded as Shield} from '#/components/icons/Shield'
|
||||
@@ -20,7 +19,7 @@ export function TokenField({
|
||||
onChangeText,
|
||||
onSubmitEditing,
|
||||
}: Pick<TextInputProps, 'value' | 'onChangeText' | 'onSubmitEditing'>) {
|
||||
const {_} = useLingui()
|
||||
const {t: l} = useLingui()
|
||||
const isInvalid = Boolean(value && value.length > 10 && !isValidCode(value))
|
||||
|
||||
const handleOnChangeText = (v: string) => {
|
||||
@@ -35,7 +34,7 @@ export function TokenField({
|
||||
autoComplete="off"
|
||||
autoCorrect={false}
|
||||
isInvalid={isInvalid}
|
||||
label={_(msg`Confirmation code`)}
|
||||
label={l`Confirmation code`}
|
||||
maxLength={11}
|
||||
placeholder="XXXXX-XXXXX"
|
||||
value={value}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useCallback, useState} from 'react'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {web} from '#/alf'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
@@ -21,7 +20,7 @@ export function useEmailDialogControl() {
|
||||
}
|
||||
|
||||
export function EmailDialog() {
|
||||
const {_} = useLingui()
|
||||
const {t: l} = useLingui()
|
||||
const emailDialogControl = useEmailDialogControl()
|
||||
const {isEmailVerified} = useAccountEmailState()
|
||||
const onClose = useCallback(() => {
|
||||
@@ -36,9 +35,8 @@ export function EmailDialog() {
|
||||
return (
|
||||
<Dialog.Outer control={emailDialogControl.control} onClose={onClose}>
|
||||
<Dialog.Handle />
|
||||
|
||||
<Dialog.ScrollableInner
|
||||
label={_(msg`Make adjustments to email settings for your account`)}
|
||||
label={l`Make adjustments to email settings for your account`}
|
||||
style={web({maxWidth: 400})}>
|
||||
<Inner control={emailDialogControl} />
|
||||
<Dialog.Close />
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import {useReducer, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {wait} from '#/lib/async/wait'
|
||||
import {useCleanError} from '#/lib/hooks/useCleanError'
|
||||
@@ -90,7 +88,7 @@ function reducer(state: State, action: Action): State {
|
||||
|
||||
export function Disable() {
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
const {t: l} = useLingui()
|
||||
const cleanError = useCleanError()
|
||||
const {currentAccount} = useSession()
|
||||
const {mutateAsync: requestEmailUpdate} = useRequestEmailUpdate()
|
||||
@@ -120,7 +118,7 @@ export function Disable() {
|
||||
const {clean} = cleanError(e)
|
||||
dispatch({
|
||||
type: 'setError',
|
||||
error: clean || _(msg`Failed to send email, please try again.`),
|
||||
error: clean || l`Failed to send email, please try again.`,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -129,7 +127,7 @@ export function Disable() {
|
||||
if (!isValidCode(token)) {
|
||||
dispatch({
|
||||
type: 'setError',
|
||||
error: _(msg`Please enter a valid code.`),
|
||||
error: l`Please enter a valid code.`,
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -147,7 +145,7 @@ export function Disable() {
|
||||
const {clean} = cleanError(e)
|
||||
dispatch({
|
||||
type: 'setError',
|
||||
error: clean || _(msg`Failed to update email 2FA settings`),
|
||||
error: clean || l`Failed to update email 2FA settings`,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -157,7 +155,6 @@ export function Disable() {
|
||||
<Text style={[a.text_xl, a.font_bold, a.leading_snug]}>
|
||||
<Trans>Disable email 2FA</Trans>
|
||||
</Text>
|
||||
|
||||
{state.step === 'email' ? (
|
||||
<>
|
||||
<Text
|
||||
@@ -172,7 +169,7 @@ export function Disable() {
|
||||
{state.error && <Admonition type="error">{state.error}</Admonition>}
|
||||
|
||||
<Button
|
||||
label={_(msg`Send email`)}
|
||||
label={l`Send email`}
|
||||
size="large"
|
||||
variant="solid"
|
||||
color="primary"
|
||||
@@ -199,7 +196,7 @@ export function Disable() {
|
||||
<Trans>
|
||||
Have a code?{' '}
|
||||
<InlineLinkText
|
||||
label={_(msg`Enter code`)}
|
||||
label={l`Enter code`}
|
||||
{...createStaticClick(() => {
|
||||
dispatch({type: 'setStep', step: 'token'})
|
||||
})}>
|
||||
@@ -231,7 +228,7 @@ export function Disable() {
|
||||
{state.error && <Admonition type="error">{state.error}</Admonition>}
|
||||
|
||||
<Button
|
||||
label={_(msg`Disable 2FA`)}
|
||||
label={l`Disable 2FA`}
|
||||
size="large"
|
||||
variant="solid"
|
||||
color="primary"
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import {useReducer} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {wait} from '#/lib/async/wait'
|
||||
import {useCleanError} from '#/lib/hooks/useCleanError'
|
||||
@@ -56,7 +54,7 @@ function reducer(state: State, action: Action): State {
|
||||
|
||||
export function Enable() {
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
const {t: l} = useLingui()
|
||||
const cleanError = useCleanError()
|
||||
const {gtPhone} = useBreakpoints()
|
||||
const {mutateAsync: manageEmail2FA} = useManageEmail2FA()
|
||||
@@ -81,7 +79,7 @@ export function Enable() {
|
||||
const {clean} = cleanError(e)
|
||||
dispatch({
|
||||
type: 'setError',
|
||||
error: clean || _(msg`Failed to update email 2FA settings`),
|
||||
error: clean || l`Failed to update email 2FA settings`,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -97,12 +95,10 @@ export function Enable() {
|
||||
<Trans>Require an email code to sign in to your account.</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{state.error && <Admonition type="error">{state.error}</Admonition>}
|
||||
|
||||
<View style={[a.gap_sm, gtPhone && [a.flex_row_reverse]]}>
|
||||
<Button
|
||||
label={_(msg`Enable`)}
|
||||
label={l`Enable`}
|
||||
size="large"
|
||||
variant="solid"
|
||||
color="primary"
|
||||
@@ -123,7 +119,7 @@ export function Enable() {
|
||||
/>
|
||||
</Button>
|
||||
<Button
|
||||
label={_(msg`Cancel`)}
|
||||
label={l`Cancel`}
|
||||
size="large"
|
||||
variant="solid"
|
||||
color="secondary"
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import {useReducer} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
import {validate as validateEmail} from 'email-validator'
|
||||
|
||||
import {wait} from '#/lib/async/wait'
|
||||
@@ -106,7 +104,7 @@ function reducer(state: State, action: Action): State {
|
||||
|
||||
export function Update(_props: ScreenProps<ScreenID.Update>) {
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
const {t: l} = useLingui()
|
||||
const cleanError = useCleanError()
|
||||
const {currentAccount} = useSession()
|
||||
const [state, dispatch] = useReducer(reducer, {
|
||||
@@ -133,7 +131,7 @@ export function Update(_props: ScreenProps<ScreenID.Update>) {
|
||||
if (state.step === 'token' && !isValidCode(state.token)) {
|
||||
dispatch({
|
||||
type: 'setError',
|
||||
error: _(msg`Please enter a valid code.`),
|
||||
error: l`Please enter a valid code.`,
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -146,7 +144,7 @@ export function Update(_props: ScreenProps<ScreenID.Update>) {
|
||||
if (state.emailValid === false) {
|
||||
dispatch({
|
||||
type: 'setError',
|
||||
error: _(msg`Please enter a valid email address.`),
|
||||
error: l`Please enter a valid email address.`,
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -154,7 +152,7 @@ export function Update(_props: ScreenProps<ScreenID.Update>) {
|
||||
if (state.email === currentAccount!.email) {
|
||||
dispatch({
|
||||
type: 'setError',
|
||||
error: _(msg`This email is already associated with your account.`),
|
||||
error: l`This email is already associated with your account.`,
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -193,7 +191,7 @@ export function Update(_props: ScreenProps<ScreenID.Update>) {
|
||||
const {clean} = cleanError(e)
|
||||
dispatch({
|
||||
type: 'setError',
|
||||
error: clean || _(msg`Failed to update email, please try again.`),
|
||||
error: clean || l`Failed to update email, please try again.`,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -203,7 +201,6 @@ export function Update(_props: ScreenProps<ScreenID.Update>) {
|
||||
<Text style={[a.text_xl, a.font_bold]}>
|
||||
<Trans>Update your email</Trans>
|
||||
</Text>
|
||||
|
||||
{currentAccount?.emailAuthFactor && (
|
||||
<Admonition type="warning">
|
||||
<Trans>
|
||||
@@ -211,7 +208,6 @@ export function Update(_props: ScreenProps<ScreenID.Update>) {
|
||||
</Trans>
|
||||
</Admonition>
|
||||
)}
|
||||
|
||||
<View style={[a.gap_md]}>
|
||||
<View>
|
||||
<Text style={[a.pb_sm, a.leading_snug, t.atoms.text_contrast_medium]}>
|
||||
@@ -220,8 +216,8 @@ export function Update(_props: ScreenProps<ScreenID.Update>) {
|
||||
<TextField.Root>
|
||||
<TextField.Icon icon={Envelope} />
|
||||
<TextField.Input
|
||||
label={_(msg`New email address`)}
|
||||
placeholder={_(msg`alice@example.com`)}
|
||||
label={l`New email address`}
|
||||
placeholder={l`alice@example.com`}
|
||||
defaultValue={state.email}
|
||||
onChangeText={
|
||||
state.mutationStatus === 'success'
|
||||
@@ -276,7 +272,6 @@ export function Update(_props: ScreenProps<ScreenID.Update>) {
|
||||
|
||||
{state.error && <Admonition type="error">{state.error}</Admonition>}
|
||||
</View>
|
||||
|
||||
{state.mutationStatus === 'success' ? (
|
||||
<>
|
||||
<Divider />
|
||||
@@ -298,7 +293,7 @@ export function Update(_props: ScreenProps<ScreenID.Update>) {
|
||||
</>
|
||||
) : (
|
||||
<Button
|
||||
label={_(msg`Update email`)}
|
||||
label={l`Update email`}
|
||||
size="large"
|
||||
variant="solid"
|
||||
color="primary"
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import {View} from 'react-native'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {atoms as a, platform, tokens, useBreakpoints, useTheme} from '#/alf'
|
||||
import {Button, ButtonText} from '#/components/Button'
|
||||
@@ -19,7 +17,7 @@ export function VerificationReminder({
|
||||
showScreen,
|
||||
}: ScreenProps<ScreenID.VerificationReminder>) {
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
const {t: l} = useLingui()
|
||||
const {gtPhone, gtMobile} = useBreakpoints()
|
||||
const control = useDialogContext()
|
||||
|
||||
@@ -55,9 +53,7 @@ export function VerificationReminder({
|
||||
<ShieldIcon width={64} fill="white" style={[a.z_10]} />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={[a.mb_xs, {height: 150 - dialogPadding}]} />
|
||||
|
||||
<View style={[a.gap_sm]}>
|
||||
<Text style={[a.text_xl, a.font_bold]}>
|
||||
<Trans>Please verify your email</Trans>
|
||||
@@ -69,12 +65,10 @@ export function VerificationReminder({
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<Divider />
|
||||
|
||||
<View style={[a.gap_sm, gtPhone && [a.flex_row_reverse]]}>
|
||||
<Button
|
||||
label={_(msg`Get started`)}
|
||||
label={l`Get started`}
|
||||
variant="solid"
|
||||
color="primary"
|
||||
size="large"
|
||||
@@ -88,8 +82,8 @@ export function VerificationReminder({
|
||||
</ButtonText>
|
||||
</Button>
|
||||
<Button
|
||||
label={_(msg`Maybe later`)}
|
||||
accessibilityHint={_(msg`Snoozes the reminder`)}
|
||||
label={l`Maybe later`}
|
||||
accessibilityHint={l`Snoozes the reminder`}
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
size="large"
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import {useReducer} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {wait} from '#/lib/async/wait'
|
||||
import {useCleanError} from '#/lib/hooks/useCleanError'
|
||||
@@ -11,6 +9,7 @@ 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 {useDialogContext} from '#/components/Dialog/context'
|
||||
import {ResendEmailText} from '#/components/dialogs/EmailDialog/components/ResendEmailText'
|
||||
import {
|
||||
isValidCode,
|
||||
@@ -91,7 +90,8 @@ function reducer(state: State, action: Action): State {
|
||||
|
||||
export function Verify({config, showScreen}: ScreenProps<ScreenID.Verify>) {
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
const {t: l} = useLingui()
|
||||
const control = useDialogContext()
|
||||
const cleanError = useCleanError()
|
||||
const {currentAccount} = useSession()
|
||||
const [state, dispatch] = useReducer(reducer, {
|
||||
@@ -134,7 +134,7 @@ export function Verify({config, showScreen}: ScreenProps<ScreenID.Verify>) {
|
||||
const {clean} = cleanError(e)
|
||||
dispatch({
|
||||
type: 'setError',
|
||||
error: clean || _(msg`Failed to send email, please try again.`),
|
||||
error: clean || l`Failed to send email, please try again.`,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -143,7 +143,7 @@ export function Verify({config, showScreen}: ScreenProps<ScreenID.Verify>) {
|
||||
if (!isValidCode(state.token)) {
|
||||
dispatch({
|
||||
type: 'setError',
|
||||
error: _(msg`Please enter a valid code.`),
|
||||
error: l`Please enter a valid code.`,
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -166,7 +166,7 @@ export function Verify({config, showScreen}: ScreenProps<ScreenID.Verify>) {
|
||||
const {clean} = cleanError(e)
|
||||
dispatch({
|
||||
type: 'setError',
|
||||
error: clean || _(msg`Failed to verify email, please try again.`),
|
||||
error: clean || l`Failed to verify email, please try again.`,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -191,6 +191,15 @@ export function Verify({config, showScreen}: ScreenProps<ScreenID.Verify>) {
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
<Button
|
||||
label={l`Done`}
|
||||
size="large"
|
||||
color="primary"
|
||||
onPress={() => control.close()}>
|
||||
<ButtonText>
|
||||
<Trans>Done</Trans>
|
||||
</ButtonText>
|
||||
</Button>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -273,7 +282,7 @@ export function Verify({config, showScreen}: ScreenProps<ScreenID.Verify>) {
|
||||
<Trans>
|
||||
If you need to update your email,{' '}
|
||||
<InlineLinkText
|
||||
label={_(msg`Click here to update your email`)}
|
||||
label={l`Click here to update your email`}
|
||||
{...createStaticClick(() => {
|
||||
showScreen({id: ScreenID.Update})
|
||||
})}>
|
||||
@@ -288,12 +297,11 @@ export function Verify({config, showScreen}: ScreenProps<ScreenID.Verify>) {
|
||||
<ResendEmailText onPress={requestEmailVerification} />
|
||||
)}
|
||||
</View>
|
||||
|
||||
{state.step === 'email' && state.mutationStatus !== 'success' ? (
|
||||
<>
|
||||
{state.error && <Admonition type="error">{state.error}</Admonition>}
|
||||
<Button
|
||||
label={_(msg`Send verification email`)}
|
||||
label={l`Send verification email`}
|
||||
size="large"
|
||||
variant="solid"
|
||||
color="primary"
|
||||
@@ -308,7 +316,6 @@ export function Verify({config, showScreen}: ScreenProps<ScreenID.Verify>) {
|
||||
</Button>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{state.step === 'email' && (
|
||||
<>
|
||||
<Divider />
|
||||
@@ -318,7 +325,7 @@ export function Verify({config, showScreen}: ScreenProps<ScreenID.Verify>) {
|
||||
<Trans>
|
||||
Have a code?{' '}
|
||||
<InlineLinkText
|
||||
label={_(msg`Enter code`)}
|
||||
label={l`Enter code`}
|
||||
{...createStaticClick(() => {
|
||||
dispatch({
|
||||
type: 'setStep',
|
||||
@@ -331,7 +338,6 @@ export function Verify({config, showScreen}: ScreenProps<ScreenID.Verify>) {
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
|
||||
{state.step === 'token' ? (
|
||||
<>
|
||||
<TokenField
|
||||
@@ -348,13 +354,11 @@ export function Verify({config, showScreen}: ScreenProps<ScreenID.Verify>) {
|
||||
{state.error && <Admonition type="error">{state.error}</Admonition>}
|
||||
|
||||
<Button
|
||||
label={_(
|
||||
msg({
|
||||
message: `Verify code`,
|
||||
context: `action`,
|
||||
comment: `Button text and accessibility label for action to verify the user's email address using the code entered`,
|
||||
}),
|
||||
)}
|
||||
label={l({
|
||||
message: `Verify code`,
|
||||
context: `action`,
|
||||
comment: `Button text and accessibility label for action to verify the user's email address using the code entered`,
|
||||
})}
|
||||
size="large"
|
||||
variant="solid"
|
||||
color="primary"
|
||||
@@ -381,7 +385,7 @@ export function Verify({config, showScreen}: ScreenProps<ScreenID.Verify>) {
|
||||
<Trans>
|
||||
Don't have a code or need a new one?{' '}
|
||||
<InlineLinkText
|
||||
label={_(msg`Click here to restart the verification process.`)}
|
||||
label={l`Click here to restart the verification process.`}
|
||||
{...createStaticClick(() => {
|
||||
dispatch({
|
||||
type: 'setStep',
|
||||
|
||||
Reference in New Issue
Block a user