Verify email handling

This commit is contained in:
Eric Bailey
2024-11-26 12:02:41 -06:00
parent 533ebf5daa
commit 1e7eaf0ee6
@@ -19,8 +19,11 @@ import {atoms as a, tokens, useBreakpoints, useTheme} from '#/alf'
import {Admonition} from '#/components/Admonition' import {Admonition} from '#/components/Admonition'
import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog' import * as Dialog from '#/components/Dialog'
import {Divider} from '#/components/Divider'
import * as TextField from '#/components/forms/TextField'
import * as Toggle from '#/components/forms/Toggle' import * as Toggle from '#/components/forms/Toggle'
import {GradientFill} from '#/components/GradientFill' import {GradientFill} from '#/components/GradientFill'
import {At_Stroke2_Corner0_Rounded as At} from '#/components/icons/At'
import {Full as BlueskyPlusLogo} from '#/components/icons/BlueskyPlus' import {Full as BlueskyPlusLogo} from '#/components/icons/BlueskyPlus'
import {CheckThick_Stroke2_Corner0_Rounded as CheckThink} from '#/components/icons/Check' import {CheckThick_Stroke2_Corner0_Rounded as CheckThink} from '#/components/icons/Check'
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
@@ -50,7 +53,12 @@ function DialogInner({control}: {control: Dialog.DialogControlProps}) {
const routes = useNavigationState(state => state.routes) const routes = useNavigationState(state => state.routes)
const currentRoute = routes.at(routes.length - 1) const currentRoute = routes.at(routes.length - 1)
const isOnSubscriptionsPage = currentRoute?.name === 'Subscriptions' const isOnSubscriptionsPage = currentRoute?.name === 'Subscriptions'
// TODO if 3p PDS
const needsEmail = !currentAccount?.email
const needsConfirmEmail = !currentAccount?.emailConfirmed
const isDisabled = needsEmail || needsConfirmEmail
const [email, setEmail] = React.useState('')
const [error, setError] = React.useState<string>('') const [error, setError] = React.useState<string>('')
const [offeringId, setOfferingId] = React.useState<SubscriptionOfferingId>( const [offeringId, setOfferingId] = React.useState<SubscriptionOfferingId>(
SubscriptionOfferingId.CoreAnnual, SubscriptionOfferingId.CoreAnnual,
@@ -59,22 +67,40 @@ function DialogInner({control}: {control: Dialog.DialogControlProps}) {
const {mutateAsync: purchaseOffering, isPending} = usePurchaseOffering() const {mutateAsync: purchaseOffering, isPending} = usePurchaseOffering()
const onPressSubscribe = async () => { const onPressSubscribe = async () => {
setError('')
async function purchase() { async function purchase() {
if (!currentAccount) return if (!currentAccount) return
const offering = coreOffering?.offerings.find(o => o.id === offeringId) const offering = coreOffering?.offerings.find(o => o.id === offeringId)
if (!offering) { if (!offering) {
Toast.show( const message = _(msg`Hmmmm. We couldn't locate that subscription.`)
_(msg`Hmmmm. We couldn't locate that subscription.`), if (isWeb) {
'xmark', setError(message)
} else {
Toast.show(message, 'xmark')
}
return
}
const emailValue = email ?? currentAccount.email
if (!emailValue) {
const message = _(
msg`Hmmm. Something went wrong, sorry about that. Please try again.`,
) )
if (isWeb) {
setError(message)
} else {
Toast.show(message, 'xmark')
}
return return
} }
await purchaseOffering({ await purchaseOffering({
did: currentAccount.did, did: currentAccount.did,
email: currentAccount.email!, email: emailValue,
offering, offering,
}) })
} }
@@ -263,6 +289,47 @@ function DialogInner({control}: {control: Dialog.DialogControlProps}) {
})} })}
</Toggle.Group> </Toggle.Group>
{needsEmail ? (
<View style={[a.pt_md]}>
<Divider />
<View style={[a.py_md, a.gap_xs]}>
<Text
style={[a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]}>
<Trans>
A real email is required in order to receive support and updates
for your subscription.
</Trans>
</Text>
<TextField.Root>
<TextField.Icon icon={At} />
<TextField.Input
label={_(
msg`Enter your email for support and updates to your subscription.`,
)}
placeholder={_(msg`Email`)}
onChangeText={setEmail}
/>
</TextField.Root>
</View>
<Divider />
</View>
) : needsConfirmEmail ? (
<View style={[a.pt_sm]}>
<Admonition type="warning" style={[a.flex_1]}>
<Trans>
You must verify your email to continue. Without a valid email, we
can provide no support for your subscription.
</Trans>{' '}
<InlineLinkText
to="/settings/account"
label={_(msg`Visit account settings`)}>
<Trans>Click here to begin.</Trans>
</InlineLinkText>
</Admonition>
</View>
) : null}
<View style={[a.flex_row, a.pt_md, a.gap_sm]}> <View style={[a.flex_row, a.pt_md, a.gap_sm]}>
{!isOnSubscriptionsPage && ( {!isOnSubscriptionsPage && (
<Link <Link
@@ -283,7 +350,7 @@ function DialogInner({control}: {control: Dialog.DialogControlProps}) {
color="secondary" color="secondary"
size="large" size="large"
onPress={onPressSubscribe} onPress={onPressSubscribe}
disabled={isPending} disabled={isPending || isDisabled}
style={[a.flex_1, a.overflow_hidden]}> style={[a.flex_1, a.overflow_hidden]}>
<GradientFill gradient={tokens.gradients.nordic} /> <GradientFill gradient={tokens.gradients.nordic} />
<ButtonText style={[{color: 'white'}]}> <ButtonText style={[{color: 'white'}]}>