From a1c4f19731878f7026d398d28e475bbeb7de824a Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 19 Mar 2024 12:47:46 -0700 Subject: Use ALF for signup flow, improve a11y of signup (#3151) * Use ALF for signup flow, improve a11y of signup * adjust padding * rm log * org imports * clarify allowance of hyphens Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * fix a few accessibility items * Standardise date input across platforms (#3223) * make the date input consistent across platforms * integrate into new signup form * rm log * add transitions * show correct # of steps * use `FormError` * animate buttons * use `ScreenTransition` * fix android text overflow via flex -> flex_1 * change button color * (android) make date input the same height as others * fix deps * fix deps --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> Co-authored-by: Samuel Newman --- src/screens/Signup/index.tsx | 225 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 src/screens/Signup/index.tsx (limited to 'src/screens/Signup/index.tsx') diff --git a/src/screens/Signup/index.tsx b/src/screens/Signup/index.tsx new file mode 100644 index 000000000..b1acbbdf0 --- /dev/null +++ b/src/screens/Signup/index.tsx @@ -0,0 +1,225 @@ +import React from 'react' +import {ScrollView, View} from 'react-native' +import {useLingui} from '@lingui/react' +import {msg, Trans} from '@lingui/macro' +import { + initialState, + reducer, + SignupContext, + SignupStep, + useSubmitSignup, +} from '#/screens/Signup/state' +import {StepInfo} from '#/screens/Signup/StepInfo' +import {StepHandle} from '#/screens/Signup/StepHandle' +import {StepCaptcha} from '#/screens/Signup/StepCaptcha' +import {atoms as a, useTheme} from '#/alf' +import {Button, ButtonText} from '#/components/Button' +import {Text} from '#/components/Typography' +import {LoggedOutLayout} from 'view/com/util/layouts/LoggedOutLayout' +import {FEEDBACK_FORM_URL} from 'lib/constants' +import {InlineLink} from '#/components/Link' +import {useServiceQuery} from 'state/queries/service' +import {getAgent} from 'state/session' +import {createFullHandle} from 'lib/strings/handles' +import {useAnalytics} from 'lib/analytics/analytics' + +export function Signup({onPressBack}: {onPressBack: () => void}) { + const {_} = useLingui() + const t = useTheme() + const {screen} = useAnalytics() + const [state, dispatch] = React.useReducer(reducer, initialState) + const submit = useSubmitSignup({state, dispatch}) + + const { + data: serviceInfo, + isFetching, + isError, + refetch, + } = useServiceQuery(state.serviceUrl) + + React.useEffect(() => { + screen('CreateAccount') + }, [screen]) + + React.useEffect(() => { + if (isFetching) { + dispatch({type: 'setIsLoading', value: true}) + } else if (!isFetching) { + dispatch({type: 'setIsLoading', value: false}) + } + }, [isFetching]) + + React.useEffect(() => { + if (isError) { + dispatch({type: 'setServiceDescription', value: undefined}) + dispatch({ + type: 'setError', + value: _( + msg`Unable to contact your service. Please check your Internet connection.`, + ), + }) + } else if (serviceInfo) { + dispatch({type: 'setServiceDescription', value: serviceInfo}) + dispatch({type: 'setError', value: ''}) + } + }, [_, serviceInfo, isError]) + + const onNextPress = React.useCallback(async () => { + if (state.activeStep === SignupStep.HANDLE) { + try { + dispatch({type: 'setIsLoading', value: true}) + + const res = await getAgent().resolveHandle({ + handle: createFullHandle(state.handle, state.userDomain), + }) + + if (res.data.did) { + dispatch({ + type: 'setError', + value: _(msg`That handle is already taken.`), + }) + return + } + } catch (e) { + // Don't have to handle + } finally { + dispatch({type: 'setIsLoading', value: false}) + } + } + + // phoneVerificationRequired is actually whether a captcha is required + if ( + state.activeStep === SignupStep.HANDLE && + !state.serviceDescription?.phoneVerificationRequired + ) { + submit() + return + } + + dispatch({type: 'next'}) + }, [ + _, + state.activeStep, + state.handle, + state.serviceDescription?.phoneVerificationRequired, + state.userDomain, + submit, + ]) + + const onBackPress = React.useCallback(() => { + if (state.activeStep !== SignupStep.INFO) { + dispatch({type: 'prev'}) + } else { + onPressBack() + } + }, [onPressBack, state.activeStep]) + + return ( + + + + + + + Step {state.activeStep + 1} of{' '} + {state.serviceDescription && + !state.serviceDescription.phoneVerificationRequired + ? '2' + : '3'} + + + {state.activeStep === SignupStep.INFO ? ( + Your account + ) : state.activeStep === SignupStep.HANDLE ? ( + Your user handle + ) : ( + Complete the challenge + )} + + + + {state.activeStep === SignupStep.INFO ? ( + + ) : state.activeStep === SignupStep.HANDLE ? ( + + ) : ( + + )} + + + + + {state.activeStep !== SignupStep.CAPTCHA && ( + <> + {isError ? ( + + ) : ( + + )} + + )} + + + + Having trouble?{' '} + + Contact support + + + + + + + + ) +} -- cgit 1.4.1