+63
-28
src/components/dialogs/BirthDateSettings.tsx
+63
-28
src/components/dialogs/BirthDateSettings.tsx
···
4
4
import {useLingui} from '@lingui/react'
5
5
6
6
import {cleanError} from '#/lib/strings/errors'
7
-
import {getDateAgo} from '#/lib/strings/time'
7
+
import {getAge, getDateAgo} from '#/lib/strings/time'
8
8
import {logger} from '#/logger'
9
9
import {isIOS, isWeb} from '#/platform/detection'
10
10
import {
11
11
usePreferencesQuery,
12
-
UsePreferencesQueryResponse,
12
+
type UsePreferencesQueryResponse,
13
13
usePreferencesSetBirthDateMutation,
14
14
} from '#/state/queries/preferences'
15
15
import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
16
-
import {atoms as a, useTheme} from '#/alf'
16
+
import {atoms as a, useTheme, web} from '#/alf'
17
+
import {Admonition} from '#/components/Admonition'
18
+
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
17
19
import * as Dialog from '#/components/Dialog'
18
20
import {DateField} from '#/components/forms/DateField'
21
+
import {InlineLinkText} from '#/components/Link'
19
22
import {Loader} from '#/components/Loader'
20
23
import {Text} from '#/components/Typography'
21
-
import {Button, ButtonIcon, ButtonText} from '../Button'
22
24
23
25
export function BirthDateSettingsDialog({
24
26
control,
···
32
34
return (
33
35
<Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
34
36
<Dialog.Handle />
35
-
<Dialog.ScrollableInner label={_(msg`My Birthday`)}>
36
-
<View style={[a.gap_sm, a.pb_lg]}>
37
-
<Text style={[a.text_2xl, a.font_bold]}>
37
+
<Dialog.ScrollableInner
38
+
label={_(msg`My Birthday`)}
39
+
style={web({maxWidth: 400})}>
40
+
<View style={[a.gap_sm]}>
41
+
<Text style={[a.text_xl, a.font_bold]}>
38
42
<Trans>My Birthday</Trans>
39
43
</Text>
40
-
<Text style={[a.text_md, t.atoms.text_contrast_medium]}>
41
-
<Trans>This information is not shared with other users.</Trans>
44
+
<Text style={[a.leading_snug, t.atoms.text_contrast_medium]}>
45
+
<Trans>
46
+
This information is private and not shared with other users.
47
+
</Trans>
42
48
</Text>
49
+
50
+
{isLoading ? (
51
+
<Loader size="xl" />
52
+
) : error || !preferences ? (
53
+
<ErrorMessage
54
+
message={
55
+
error?.toString() ||
56
+
_(
57
+
msg`We were unable to load your birth date preferences. Please try again.`,
58
+
)
59
+
}
60
+
style={[a.rounded_sm]}
61
+
/>
62
+
) : (
63
+
<BirthdayInner control={control} preferences={preferences} />
64
+
)}
43
65
</View>
44
66
45
-
{isLoading ? (
46
-
<Loader size="xl" />
47
-
) : error || !preferences ? (
48
-
<ErrorMessage
49
-
message={
50
-
error?.toString() ||
51
-
_(
52
-
msg`We were unable to load your birth date preferences. Please try again.`,
53
-
)
54
-
}
55
-
style={[a.rounded_sm]}
56
-
/>
57
-
) : (
58
-
<BirthdayInner control={control} preferences={preferences} />
59
-
)}
60
-
61
67
<Dialog.Close />
62
68
</Dialog.ScrollableInner>
63
69
</Dialog.Outer>
···
72
78
preferences: UsePreferencesQueryResponse
73
79
}) {
74
80
const {_} = useLingui()
75
-
const [date, setDate] = React.useState(preferences.birthDate || new Date())
81
+
const [date, setDate] = React.useState(
82
+
preferences.birthDate || getDateAgo(18),
83
+
)
76
84
const {
77
85
isPending,
78
86
isError,
···
80
88
mutateAsync: setBirthDate,
81
89
} = usePreferencesSetBirthDateMutation()
82
90
const hasChanged = date !== preferences.birthDate
91
+
92
+
const age = getAge(new Date(date))
93
+
const isUnder13 = age < 13
94
+
const isUnder18 = age >= 13 && age < 18
83
95
84
96
const onSave = React.useCallback(async () => {
85
97
try {
···
102
114
onChangeDate={newDate => setDate(new Date(newDate))}
103
115
label={_(msg`Birthday`)}
104
116
accessibilityHint={_(msg`Enter your birth date`)}
105
-
maximumDate={getDateAgo(13)}
106
117
/>
107
118
</View>
108
119
120
+
{isUnder18 && hasChanged && (
121
+
<Admonition type="info">
122
+
<Trans>
123
+
The birthdate you've entered means you are under 18 years old.
124
+
Certain content and features may be unavailable to you.
125
+
</Trans>
126
+
</Admonition>
127
+
)}
128
+
129
+
{isUnder13 && (
130
+
<Admonition type="error">
131
+
<Trans>
132
+
You must be at least 13 years old to use Bluesky. Read our{' '}
133
+
<InlineLinkText
134
+
to="https://bsky.social/about/support/tos"
135
+
label={_(msg`Terms of Service`)}>
136
+
Terms of Service
137
+
</InlineLinkText>{' '}
138
+
for more information.
139
+
</Trans>
140
+
</Admonition>
141
+
)}
142
+
109
143
{isError ? (
110
144
<ErrorMessage message={cleanError(error)} style={[a.rounded_sm]} />
111
145
) : undefined}
···
116
150
size="large"
117
151
onPress={onSave}
118
152
variant="solid"
119
-
color="primary">
153
+
color="primary"
154
+
disabled={isUnder13}>
120
155
<ButtonText>
121
156
{hasChanged ? <Trans>Save</Trans> : <Trans>Done</Trans>}
122
157
</ButtonText>