about summary refs log tree commit diff
path: root/src/view/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com')
-rw-r--r--src/view/com/auth/create/Step2.tsx62
-rw-r--r--src/view/com/util/forms/Button.tsx11
-rw-r--r--src/view/com/util/forms/DateInput.tsx96
-rw-r--r--src/view/com/util/forms/DateInput.web.tsx92
4 files changed, 215 insertions, 46 deletions
diff --git a/src/view/com/auth/create/Step2.tsx b/src/view/com/auth/create/Step2.tsx
index eceee50d3..1e014f18e 100644
--- a/src/view/com/auth/create/Step2.tsx
+++ b/src/view/com/auth/create/Step2.tsx
@@ -1,14 +1,9 @@
 import React from 'react'
-import {
-  StyleSheet,
-  TouchableOpacity,
-  TouchableWithoutFeedback,
-  View,
-} from 'react-native'
+import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native'
 import {observer} from 'mobx-react-lite'
-import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
 import {CreateAccountModel} from 'state/models/ui/create-account'
 import {Text} from 'view/com/util/text/Text'
+import {DateInput} from 'view/com/util/forms/DateInput'
 import {StepHeader} from './StepHeader'
 import {s} from 'lib/styles'
 import {usePalette} from 'lib/hooks/usePalette'
@@ -104,26 +99,20 @@ export const Step2 = observer(({model}: {model: CreateAccountModel}) => {
             <Text
               type="md-medium"
               style={[pal.text, s.mb2]}
-              nativeID="legalCheck">
-              Legal check
+              nativeID="birthDate">
+              Your birth date
             </Text>
-            <TouchableOpacity
-              testID="is13Input"
-              style={[styles.toggleBtn, pal.border]}
-              onPress={() => model.setIs13(!model.is13)}
-              accessibilityRole="checkbox"
-              accessibilityLabel="Verify age"
-              accessibilityHint="Verifies that I am at least 13 years of age"
-              accessibilityLabelledBy="legalCheck">
-              <View style={[pal.borderDark, styles.checkbox]}>
-                {model.is13 && (
-                  <FontAwesomeIcon icon="check" style={s.blue3} size={16} />
-                )}
-              </View>
-              <Text type="md" style={[pal.text, styles.toggleBtnLabel]}>
-                I am 13 years old or older
-              </Text>
-            </TouchableOpacity>
+            <DateInput
+              testID="birthdayInput"
+              value={model.birthDate}
+              onChange={model.setBirthDate}
+              buttonType="default-light"
+              buttonStyle={[pal.border, styles.dateInputButton]}
+              buttonLabelType="lg"
+              accessibilityLabel="Birthday"
+              accessibilityHint="Enter your birth date"
+              accessibilityLabelledBy="birthDate"
+            />
           </View>
 
           {model.serviceDescription && (
@@ -144,26 +133,9 @@ const styles = StyleSheet.create({
     marginTop: 10,
   },
 
-  toggleBtn: {
-    flexDirection: 'row',
-    flex: 1,
-    alignItems: 'center',
+  dateInputButton: {
     borderWidth: 1,
-    paddingHorizontal: 10,
-    paddingVertical: 10,
     borderRadius: 6,
-  },
-  toggleBtnLabel: {
-    flex: 1,
-    paddingHorizontal: 10,
-  },
-
-  checkbox: {
-    borderWidth: 1,
-    borderRadius: 2,
-    width: 24,
-    height: 24,
-    alignItems: 'center',
-    justifyContent: 'center',
+    paddingVertical: 14,
   },
 })
diff --git a/src/view/com/util/forms/Button.tsx b/src/view/com/util/forms/Button.tsx
index 3b5b00284..1c9b1cf51 100644
--- a/src/view/com/util/forms/Button.tsx
+++ b/src/view/com/util/forms/Button.tsx
@@ -35,6 +35,9 @@ export function Button({
   onPress,
   children,
   testID,
+  accessibilityLabel,
+  accessibilityHint,
+  accessibilityLabelledBy,
 }: React.PropsWithChildren<{
   type?: ButtonType
   label?: string
@@ -42,6 +45,9 @@ export function Button({
   labelStyle?: StyleProp<TextStyle>
   onPress?: () => void
   testID?: string
+  accessibilityLabel?: string
+  accessibilityHint?: string
+  accessibilityLabelledBy?: string
 }>) {
   const theme = useTheme()
   const typeOuterStyle = choose<ViewStyle, Record<ButtonType, ViewStyle>>(
@@ -133,7 +139,10 @@ export function Button({
       style={[typeOuterStyle, styles.outer, style]}
       onPress={onPressWrapped}
       testID={testID}
-      accessibilityRole="button">
+      accessibilityRole="button"
+      accessibilityLabel={accessibilityLabel}
+      accessibilityHint={accessibilityHint}
+      accessibilityLabelledBy={accessibilityLabelledBy}>
       {label ? (
         <Text type="button" style={[typeLabelStyle, labelStyle]}>
           {label}
diff --git a/src/view/com/util/forms/DateInput.tsx b/src/view/com/util/forms/DateInput.tsx
new file mode 100644
index 000000000..4aa5cb610
--- /dev/null
+++ b/src/view/com/util/forms/DateInput.tsx
@@ -0,0 +1,96 @@
+import React, {useState, useCallback} from 'react'
+import {StyleProp, StyleSheet, TextStyle, View, ViewStyle} from 'react-native'
+import DateTimePicker, {
+  DateTimePickerEvent,
+} from '@react-native-community/datetimepicker'
+import {
+  FontAwesomeIcon,
+  FontAwesomeIconStyle,
+} from '@fortawesome/react-native-fontawesome'
+import {isIOS, isAndroid} from 'platform/detection'
+import {Button, ButtonType} from './Button'
+import {Text} from '../text/Text'
+import {TypographyVariant} from 'lib/ThemeContext'
+import {useTheme} from 'lib/ThemeContext'
+import {usePalette} from 'lib/hooks/usePalette'
+
+interface Props {
+  testID?: string
+  value: Date
+  onChange: (date: Date) => void
+  buttonType?: ButtonType
+  buttonStyle?: StyleProp<ViewStyle>
+  buttonLabelType?: TypographyVariant
+  buttonLabelStyle?: StyleProp<TextStyle>
+  accessibilityLabel: string
+  accessibilityHint: string
+  accessibilityLabelledBy?: string
+}
+
+export function DateInput(props: Props) {
+  const [show, setShow] = useState(false)
+  const theme = useTheme()
+  const pal = usePalette('default')
+
+  const onChangeInternal = useCallback(
+    (event: DateTimePickerEvent, date: Date | undefined) => {
+      setShow(false)
+      if (date) {
+        props.onChange(date)
+      }
+    },
+    [setShow, props],
+  )
+
+  const onPress = useCallback(() => {
+    setShow(true)
+  }, [setShow])
+
+  return (
+    <View>
+      {isAndroid && (
+        <Button
+          type={props.buttonType}
+          style={props.buttonStyle}
+          onPress={onPress}
+          accessibilityLabel={props.accessibilityLabel}
+          accessibilityHint={props.accessibilityHint}
+          accessibilityLabelledBy={props.accessibilityLabelledBy}>
+          <View style={styles.button}>
+            <FontAwesomeIcon
+              icon={['far', 'calendar']}
+              style={pal.textLight as FontAwesomeIconStyle}
+            />
+            <Text
+              type={props.buttonLabelType}
+              style={[pal.text, props.buttonLabelStyle]}>
+              {props.value.toLocaleDateString()}
+            </Text>
+          </View>
+        </Button>
+      )}
+      {(isIOS || show) && (
+        <DateTimePicker
+          testID={props.testID ? `${props.testID}-datepicker` : undefined}
+          mode="date"
+          display="spinner"
+          // @ts-ignore applies in iOS only -prf
+          themeVariant={theme.colorScheme}
+          value={props.value}
+          onChange={onChangeInternal}
+          accessibilityLabel={props.accessibilityLabel}
+          accessibilityHint={props.accessibilityHint}
+          accessibilityLabelledBy={props.accessibilityLabelledBy}
+        />
+      )}
+    </View>
+  )
+}
+
+const styles = StyleSheet.create({
+  button: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    gap: 10,
+  },
+})
diff --git a/src/view/com/util/forms/DateInput.web.tsx b/src/view/com/util/forms/DateInput.web.tsx
new file mode 100644
index 000000000..89dff5510
--- /dev/null
+++ b/src/view/com/util/forms/DateInput.web.tsx
@@ -0,0 +1,92 @@
+import React, {useState, useCallback} from 'react'
+import {
+  StyleProp,
+  StyleSheet,
+  TextInput as RNTextInput,
+  TextStyle,
+  View,
+  ViewStyle,
+} from 'react-native'
+import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
+import {useTheme} from 'lib/ThemeContext'
+import {usePalette} from 'lib/hooks/usePalette'
+
+interface Props {
+  testID?: string
+  value: Date
+  onChange: (date: Date) => void
+  buttonType?: string
+  buttonStyle?: StyleProp<ViewStyle>
+  buttonLabelType?: string
+  buttonLabelStyle?: StyleProp<TextStyle>
+  accessibilityLabel: string
+  accessibilityHint: string
+  accessibilityLabelledBy?: string
+}
+
+export function DateInput(props: Props) {
+  const theme = useTheme()
+  const pal = usePalette('default')
+  const palError = usePalette('error')
+  const [value, setValue] = useState(props.value.toLocaleDateString())
+  const [isValid, setIsValid] = useState(true)
+
+  const onChangeInternal = useCallback(
+    (v: string) => {
+      setValue(v)
+      const d = new Date(v)
+      if (!isNaN(Number(d))) {
+        setIsValid(true)
+        props.onChange(d)
+      } else {
+        setIsValid(false)
+      }
+    },
+    [setValue, setIsValid, props],
+  )
+
+  return (
+    <View style={[isValid ? pal.border : palError.border, styles.container]}>
+      <FontAwesomeIcon
+        icon={['far', 'calendar']}
+        style={[pal.textLight, styles.icon]}
+      />
+      <RNTextInput
+        testID={props.testID}
+        style={[pal.text, styles.textInput]}
+        placeholderTextColor={pal.colors.textLight}
+        autoCapitalize="none"
+        autoCorrect={false}
+        keyboardAppearance={theme.colorScheme}
+        onChangeText={v => onChangeInternal(v)}
+        value={value}
+        accessibilityLabel={props.accessibilityLabel}
+        accessibilityHint={props.accessibilityHint}
+        accessibilityLabelledBy={props.accessibilityLabelledBy}
+      />
+    </View>
+  )
+}
+
+const styles = StyleSheet.create({
+  container: {
+    borderWidth: 1,
+    borderRadius: 6,
+    flexDirection: 'row',
+    alignItems: 'center',
+    paddingHorizontal: 4,
+  },
+  icon: {
+    marginLeft: 10,
+  },
+  textInput: {
+    flex: 1,
+    width: '100%',
+    paddingVertical: 10,
+    paddingHorizontal: 10,
+    fontSize: 17,
+    letterSpacing: 0.25,
+    fontWeight: '400',
+    borderRadius: 10,
+  },
+})