diff options
author | Eric Bailey <git@esb.lol> | 2025-07-16 13:58:07 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-16 13:58:07 -0500 |
commit | 1dbc331314278cb7a42ded9b190dac7038ad9878 (patch) | |
tree | b5d44e1ea75ea9d5343eec90425c8c7ac74df39f /src/components/ageAssurance/AgeAssuranceAccountCard.tsx | |
parent | 712c3ad4211e2e68d0cdbcc480967c63aeaa6c0e (diff) | |
download | voidsky-1dbc331314278cb7a42ded9b190dac7038ad9878.tar.zst |
UI for age assurance compliance (#8652)
* Add geo prop * Add prelim fetch * Add geo debug * Pass in assurance state to notifications registration * Comments * Bump git index * Add some component utils, no design, gate chat * Disable mod prefs buttons, does not yet edit mod prefs * Add initial prompt component * Refine logic for showing prompt * Add send email dialog * Hook up dialog to fake mutation * Fix geo debug bug * Move provider inside query provider * Slightly better screen gater * Ok decent fallback with isExempt * Reorg * Wrap prompt in new logic * Override mod prefs * Use real endpoints, optimistic state * Add persistent card, add time-ago, warning to dialog * Add comment * No undefined query values * Fix case in import * Wait for AA to load before registering push * Override prefs in all locations * Small refactor of notifications registration * Register push after aa state * Add retries * Update blocked screens UI * Strengthen email validation * Add intent dialog * Do service auth for init * Rug refreshJwt * Update copy * Some mobile styles, add dev mode option * Fix links on native * Clean up intent dialog on native * Don't mutate existing session, only copy * Handle email validation error from server * Clarity is better * Moar clear * Fixes * Tweaks * Add country code * Gate it * Refresh state after redirect * Re-check on window focus * Remove todo * Enable in dev * Check for did match on redirect * Add blocked state * Add appeal dialog * Copy tweaks * Inset in blue well * Nux the prompt * Copy updates * Refetch just in case * Uppercase country code * Align copy, add notice to chat screens * Tweak copy * Add test code * Add debug code * Refactor AccountCard * Big refactor * Delay post-feed queries instead * Debug code * Clean up state * Reorg * Clean up copy * Comments * Reorg * UPdate URL * Cleanup * Remove todo * Update debug code * revert unneeded changes * UPdate nux name * Revert unneeded change * Updaet storage schema * Checkpoint: cleanup * Checkpoint: almost there * isLoaded -> isReady * Rename useAgeAssurance * isUnderage -> isDeclaredUnderage * Decompose, add docblocks * Refactor * UPdate debug * Apply suggestion from @surfdude29 Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Apply suggestion from @surfdude29 Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Apply suggestion from @surfdude29 Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Apply suggestion from @surfdude29 Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Apply suggestion from @surfdude29 Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Apply suggestion from @surfdude29 Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Drop including Bluesky * Apply suggestion from @surfdude29 Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Apply suggestion from @surfdude29 Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Remove todo * Gate debug * Revert unneeded change * Fail closed * Comments * Comment * Comment * fix prettier * rm viewheader * bump sdk * prevent overlap in admonition * add age assurance intent route * Just meow Co-authored-by: Samuel Newman <mozzius@protonmail.com> * Nix callback * Fix spelling of dismissible lol * Don't compare translated string * Better KWS link labels * Hide DMs send options in menu * Add button * Fix order * Use only supported languages * Rm button * best-effort language mapping * improve typing --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Diffstat (limited to 'src/components/ageAssurance/AgeAssuranceAccountCard.tsx')
-rw-r--r-- | src/components/ageAssurance/AgeAssuranceAccountCard.tsx | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/src/components/ageAssurance/AgeAssuranceAccountCard.tsx b/src/components/ageAssurance/AgeAssuranceAccountCard.tsx new file mode 100644 index 000000000..530e43d44 --- /dev/null +++ b/src/components/ageAssurance/AgeAssuranceAccountCard.tsx @@ -0,0 +1,148 @@ +import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {dateDiff, useGetTimeAgo} from '#/lib/hooks/useTimeAgo' +import {useAgeAssurance} from '#/state/ageAssurance/useAgeAssurance' +import {atoms as a, useBreakpoints, useTheme, type ViewStyleProp} from '#/alf' +import {Admonition} from '#/components/Admonition' +import {AgeAssuranceAppealDialog} from '#/components/ageAssurance/AgeAssuranceAppealDialog' +import {AgeAssuranceBadge} from '#/components/ageAssurance/AgeAssuranceBadge' +import { + AgeAssuranceInitDialog, + useDialogControl, +} from '#/components/ageAssurance/AgeAssuranceInitDialog' +import {useAgeAssuranceCopy} from '#/components/ageAssurance/useAgeAssuranceCopy' +import {Button, ButtonText} from '#/components/Button' +import * as Dialog from '#/components/Dialog' +import {Divider} from '#/components/Divider' +import {createStaticClick, InlineLinkText} from '#/components/Link' +import {Text} from '#/components/Typography' + +export function AgeAssuranceAccountCard({style}: ViewStyleProp & {}) { + const {isReady, isAgeRestricted, isDeclaredUnderage} = useAgeAssurance() + + if (!isReady) return null + if (isDeclaredUnderage) return null + if (!isAgeRestricted) return null + + return <Inner style={style} /> +} + +function Inner({style}: ViewStyleProp & {}) { + const t = useTheme() + const {_, i18n} = useLingui() + const control = useDialogControl() + const appealControl = Dialog.useDialogControl() + const getTimeAgo = useGetTimeAgo() + const {gtPhone} = useBreakpoints() + + const copy = useAgeAssuranceCopy() + const {status, lastInitiatedAt} = useAgeAssurance() + const isBlocked = status === 'blocked' + const hasInitiated = !!lastInitiatedAt + const timeAgo = lastInitiatedAt + ? getTimeAgo(lastInitiatedAt, new Date()) + : null + const diff = lastInitiatedAt + ? dateDiff(lastInitiatedAt, new Date(), 'down') + : null + + return ( + <> + <AgeAssuranceInitDialog control={control} /> + <AgeAssuranceAppealDialog control={appealControl} /> + + <View style={style}> + <View + style={[a.p_lg, a.rounded_md, a.border, t.atoms.border_contrast_low]}> + <View + style={[ + a.flex_row, + a.justify_between, + a.align_center, + a.gap_lg, + a.pb_md, + a.z_10, + ]}> + <View style={[a.align_start]}> + <AgeAssuranceBadge /> + </View> + </View> + + <View style={[a.pb_md]}> + <Text style={[a.text_sm, a.leading_snug]}>{copy.notice}</Text> + </View> + + {isBlocked ? ( + <Admonition type="warning"> + <Trans> + You are currently unable to access Bluesky's Age Assurance flow. + Please{' '} + <InlineLinkText + label={_(msg`Contact our moderation team`)} + {...createStaticClick(() => { + appealControl.open() + })}> + contact our moderation team + </InlineLinkText>{' '} + if you believe this is an error. + </Trans> + </Admonition> + ) : ( + <> + <Divider /> + <View + style={[ + a.pt_md, + gtPhone + ? [ + a.flex_row_reverse, + a.gap_xl, + a.justify_between, + a.align_center, + ] + : [a.gap_md], + ]}> + <Button + label={_(msg`Verify now`)} + size="small" + variant="solid" + color={hasInitiated ? 'secondary' : 'primary'} + onPress={() => control.open()}> + <ButtonText> + {hasInitiated ? ( + <Trans>Verify again</Trans> + ) : ( + <Trans>Verify now</Trans> + )} + </ButtonText> + </Button> + + {lastInitiatedAt && timeAgo && diff ? ( + <Text + style={[a.text_sm, a.italic, t.atoms.text_contrast_medium]} + title={i18n.date(lastInitiatedAt, { + dateStyle: 'medium', + timeStyle: 'medium', + })}> + {diff.value === 0 ? ( + <Trans>Last initiated just now</Trans> + ) : ( + <Trans>Last initiated {timeAgo} ago</Trans> + )} + </Text> + ) : ( + <Text + style={[a.text_sm, a.italic, t.atoms.text_contrast_medium]}> + <Trans>Age assurance only takes a few minutes</Trans> + </Text> + )} + </View> + </> + )} + </View> + </View> + </> + ) +} |