Handle birth dates as UTC, handle locale formatting (#2363)
* Enforce UTC for birthdate picker * Handle locales * Remove log * Add a second snap point to the date input in case text is zoomed * Guard against bad dates * Log message --------- Co-authored-by: Paul Frazee <pfrazee@gmail.com>zio/stable
parent
23c9c8977b
commit
705f9b61ef
|
@ -13,6 +13,17 @@ import {isWeb} from 'platform/detection'
|
|||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
import {logger} from '#/logger'
|
||||
|
||||
function sanitizeDate(date: Date): Date {
|
||||
if (!date || date.toString() === 'Invalid Date') {
|
||||
logger.error(`Create account: handled invalid date for birthDate`, {
|
||||
hasDate: !!date,
|
||||
})
|
||||
return new Date()
|
||||
}
|
||||
return date
|
||||
}
|
||||
|
||||
/** STEP 2: Your account
|
||||
* @field Invite code or waitlist
|
||||
|
@ -38,6 +49,10 @@ export function Step2({
|
|||
openModal({name: 'waitlist'})
|
||||
}, [openModal])
|
||||
|
||||
const birthDate = React.useMemo(() => {
|
||||
return sanitizeDate(uiState.birthDate)
|
||||
}, [uiState.birthDate])
|
||||
|
||||
return (
|
||||
<View>
|
||||
<StepHeader step="2" title={_(msg`Your account`)} />
|
||||
|
@ -122,8 +137,9 @@ export function Step2({
|
|||
<Trans>Your birth date</Trans>
|
||||
</Text>
|
||||
<DateInput
|
||||
handleAsUTC
|
||||
testID="birthdayInput"
|
||||
value={uiState.birthDate}
|
||||
value={birthDate}
|
||||
onChange={value => uiDispatch({type: 'set-birth-date', value})}
|
||||
buttonType="default-light"
|
||||
buttonStyle={[pal.border, styles.dateInputButton]}
|
||||
|
|
|
@ -23,7 +23,7 @@ import {
|
|||
} from '#/state/queries/preferences'
|
||||
import {logger} from '#/logger'
|
||||
|
||||
export const snapPoints = ['50%']
|
||||
export const snapPoints = ['50%', '90%']
|
||||
|
||||
function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) {
|
||||
const pal = usePalette('default')
|
||||
|
@ -63,6 +63,7 @@ function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) {
|
|||
|
||||
<View>
|
||||
<DateInput
|
||||
handleAsUTC
|
||||
testID="birthdayInput"
|
||||
value={date}
|
||||
onChange={setDate}
|
||||
|
|
|
@ -13,6 +13,9 @@ import {Text} from '../text/Text'
|
|||
import {TypographyVariant} from 'lib/ThemeContext'
|
||||
import {useTheme} from 'lib/ThemeContext'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {getLocales} from 'expo-localization'
|
||||
|
||||
const LOCALE = getLocales()[0]
|
||||
|
||||
interface Props {
|
||||
testID?: string
|
||||
|
@ -25,6 +28,7 @@ interface Props {
|
|||
accessibilityLabel: string
|
||||
accessibilityHint: string
|
||||
accessibilityLabelledBy?: string
|
||||
handleAsUTC?: boolean
|
||||
}
|
||||
|
||||
export function DateInput(props: Props) {
|
||||
|
@ -32,6 +36,12 @@ export function DateInput(props: Props) {
|
|||
const theme = useTheme()
|
||||
const pal = usePalette('default')
|
||||
|
||||
const formatter = React.useMemo(() => {
|
||||
return new Intl.DateTimeFormat(LOCALE.languageTag, {
|
||||
timeZone: props.handleAsUTC ? 'UTC' : undefined,
|
||||
})
|
||||
}, [props.handleAsUTC])
|
||||
|
||||
const onChangeInternal = useCallback(
|
||||
(event: DateTimePickerEvent, date: Date | undefined) => {
|
||||
setShow(false)
|
||||
|
@ -64,7 +74,7 @@ export function DateInput(props: Props) {
|
|||
<Text
|
||||
type={props.buttonLabelType}
|
||||
style={[pal.text, props.buttonLabelStyle]}>
|
||||
{props.value.toLocaleDateString()}
|
||||
{formatter.format(props.value)}
|
||||
</Text>
|
||||
</View>
|
||||
</Button>
|
||||
|
@ -73,6 +83,7 @@ export function DateInput(props: Props) {
|
|||
<DateTimePicker
|
||||
testID={props.testID ? `${props.testID}-datepicker` : undefined}
|
||||
mode="date"
|
||||
timeZoneName={props.handleAsUTC ? 'Etc/UTC' : undefined}
|
||||
display="spinner"
|
||||
// @ts-ignore applies in iOS only -prf
|
||||
themeVariant={theme.colorScheme}
|
||||
|
|
Loading…
Reference in New Issue