Skip to content

Commit

Permalink
[C-3515] Fix desktop sign up page transitions (#7084)
Browse files Browse the repository at this point in the history
  • Loading branch information
dylanjeffers authored Jan 5, 2024
1 parent dcd6c7d commit 3e22ea8
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 156 deletions.
109 changes: 56 additions & 53 deletions packages/web/src/components/form-fields/HarmonyTextField.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect } from 'react'
import { Ref, forwardRef, useEffect } from 'react'

import { useDebouncedCallback } from '@audius/common'
import { TextInput, TextInputProps } from '@audius/harmony'
Expand All @@ -19,59 +19,62 @@ export type HarmonyTextFieldProps = TextInputProps & {
}

// TODO: rename to TextField and replace old usages
export const HarmonyTextField = (props: HarmonyTextFieldProps) => {
const {
name,
clearErrorOnChange = true,
transformValueOnChange,
transformValueOnBlur,
debouncedValidationMs = 0,
helperText,
...other
} = props
const [field, { touched, error }, { setError }] = useField(name)
const { value } = field
const { validateField, submitCount } = useFormikContext()
export const HarmonyTextField = forwardRef(
(props: HarmonyTextFieldProps, ref: Ref<HTMLInputElement>) => {
const {
name,
clearErrorOnChange = true,
transformValueOnChange,
transformValueOnBlur,
debouncedValidationMs = 0,
helperText,
...other
} = props
const [field, { touched, error }, { setError }] = useField(name)
const { value } = field
const { validateField, submitCount } = useFormikContext()

const debouncedValidateField = useDebouncedCallback(
(field: string) => validateField(field),
[validateField],
debouncedValidationMs
)
const debouncedValidateField = useDebouncedCallback(
(field: string) => validateField(field),
[validateField],
debouncedValidationMs
)

useEffect(() => {
if (debouncedValidationMs) {
debouncedValidateField(name)
}
}, [debouncedValidationMs, debouncedValidateField, name, value])
useEffect(() => {
if (debouncedValidationMs) {
debouncedValidateField(name)
}
}, [debouncedValidationMs, debouncedValidateField, name, value])

const hasError = Boolean(touched && error && submitCount > 0)
const hasError = Boolean(touched && error && submitCount > 0)

return (
<TextInput
{...field}
error={hasError}
helperText={helperText ?? (hasError ? error : undefined)}
onChange={(e) => {
if (clearErrorOnChange) {
setError(undefined)
}
if (transformValueOnChange) {
e.target.value = transformValueOnChange(e.target.value)
}
field.onChange(e)
}}
onBlur={(e) => {
if (clearErrorOnChange) {
setError(undefined)
}
if (transformValueOnBlur) {
e.target.value = transformValueOnBlur(e.target.value)
}
field.onChange(e)
field.onBlur(e)
}}
{...other}
/>
)
}
return (
<TextInput
ref={ref}
{...field}
error={hasError}
helperText={helperText ?? (hasError ? error : undefined)}
onChange={(e) => {
if (clearErrorOnChange) {
setError(undefined)
}
if (transformValueOnChange) {
e.target.value = transformValueOnChange(e.target.value)
}
field.onChange(e)
}}
onBlur={(e) => {
if (clearErrorOnChange) {
setError(undefined)
}
if (transformValueOnBlur) {
e.target.value = transformValueOnBlur(e.target.value)
}
field.onChange(e)
field.onBlur(e)
}}
{...other}
/>
)
}
)
16 changes: 10 additions & 6 deletions packages/web/src/components/form-fields/PasswordField.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { Ref, forwardRef } from 'react'

import { PasswordInput, PasswordInputProps } from '@audius/harmony'
import { useField } from 'formik'

export type PasswordFieldProps = PasswordInputProps & {
name: string
}

export const PasswordField = (props: PasswordFieldProps) => {
const { name, ...other } = props
const [field, { touched, error }] = useField(name)
export const PasswordField = forwardRef(
(props: PasswordFieldProps, ref: Ref<HTMLInputElement>) => {
const { name, ...other } = props
const [field, { touched, error }] = useField(name)

const hasError = Boolean(touched && error)
const hasError = Boolean(touched && error)

return <PasswordInput {...field} error={hasError} {...other} />
}
return <PasswordInput ref={ref} {...field} error={hasError} {...other} />
}
)
9 changes: 4 additions & 5 deletions packages/web/src/pages/sign-in-page/SignInPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { HarmonyTextField } from 'components/form-fields/HarmonyTextField'
import PreloadImage from 'components/preload-image/PreloadImage'
import { useMedia } from 'hooks/useMedia'
import { ForgotPasswordHelper } from 'pages/sign-on/components/desktop/ForgotPasswordHelper'
import { Heading } from 'pages/sign-up-page/components/layout'
import { Heading, ScrollView } from 'pages/sign-up-page/components/layout'
import { useSelector } from 'utils/reducer'
import { SIGN_UP_PAGE } from 'utils/route'

Expand Down Expand Up @@ -61,14 +61,13 @@ export const SignInPage = () => {
<meta name='description' content={messages.metaDescription} />
</Helmet>
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
<Flex
flex={1}
<ScrollView
direction='column'
justifyContent='space-between'
h='100%'
p='2xl'
pt='unit20'
pb={!isMobile ? 'unit14' : undefined}
gap='l'
>
<Flex as={Form} direction='column' gap='2xl'>
<Box alignSelf='center'>
Expand Down Expand Up @@ -120,7 +119,7 @@ export const SignInPage = () => {
<Link to={SIGN_UP_PAGE}>{messages.createAccount}</Link>
</Button>
) : null}
</Flex>
</ScrollView>
</Formik>
<ForgotPasswordHelper
isOpen={showForgotPassword}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { RefObject } from 'react'

import { Flex } from '@audius/harmony'

import { PasswordField } from 'components/form-fields/PasswordField'
Expand All @@ -9,10 +11,19 @@ const messages = {
confirmPasswordLabel: 'Confirm Password'
}

export const EnterPasswordSection = () => {
type EnterPasswordSectionProps = {
inputRef?: RefObject<HTMLInputElement>
}

export const EnterPasswordSection = (props: EnterPasswordSectionProps) => {
const { inputRef } = props
return (
<Flex direction='column' gap='l'>
<PasswordField name='password' label={messages.passwordLabel} autoFocus />
<PasswordField
name='password'
label={messages.passwordLabel}
ref={inputRef}
/>
<PasswordField
name='confirmPassword'
label={messages.confirmPasswordLabel}
Expand Down
133 changes: 68 additions & 65 deletions packages/web/src/pages/sign-up-page/components/HandleField.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useContext } from 'react'
import { Ref, forwardRef, useCallback, useContext } from 'react'

import {
MAX_HANDLE_LENGTH,
Expand Down Expand Up @@ -39,76 +39,79 @@ type HandleFieldProps = Partial<HarmonyTextFieldProps> & {
onErrorSocialMediaLogin?: () => void
}

export const HandleField = (props: HandleFieldProps) => {
const {
onCompleteSocialMediaLogin,
onErrorSocialMediaLogin,
onStartSocialMediaLogin,
...other
} = props
const [{ value: handle }, { error }] = useField('handle')
export const HandleField = forwardRef(
(props: HandleFieldProps, ref: Ref<HTMLInputElement>) => {
const {
onCompleteSocialMediaLogin,
onErrorSocialMediaLogin,
onStartSocialMediaLogin,
...other
} = props
const [{ value: handle }, { error }] = useField('handle')

const { toast } = useContext(ToastContext)
const { toast } = useContext(ToastContext)

const handleVerifyHandleError = useCallback(() => {
toast(socialMediaMessages.verificationError)
onErrorSocialMediaLogin?.()
}, [onErrorSocialMediaLogin, toast])
const handleVerifyHandleError = useCallback(() => {
toast(socialMediaMessages.verificationError)
onErrorSocialMediaLogin?.()
}, [onErrorSocialMediaLogin, toast])

const handleLoginSuccess = useCallback(
({
handle,
requiresReview,
platform
}: {
requiresReview: boolean
handle: string
platform: 'twitter' | 'instagram' | 'tiktok'
}) => {
toast(socialMediaMessages.socialMediaLoginSucess(platform))
onCompleteSocialMediaLogin?.({
const handleLoginSuccess = useCallback(
({
handle,
requiresReview,
platform
})
},
[onCompleteSocialMediaLogin, toast]
)
}: {
requiresReview: boolean
handle: string
platform: 'twitter' | 'instagram' | 'tiktok'
}) => {
toast(socialMediaMessages.socialMediaLoginSucess(platform))
onCompleteSocialMediaLogin?.({
handle,
requiresReview,
platform
})
},
[onCompleteSocialMediaLogin, toast]
)

const AuthComponent = error ? handleAuthMap[error] : undefined
const AuthComponent = error ? handleAuthMap[error] : undefined

const helperText =
handle && error ? (
<>
{error}{' '}
{onCompleteSocialMediaLogin &&
onStartSocialMediaLogin &&
onErrorSocialMediaLogin &&
AuthComponent ? (
<TextLink variant='visible' asChild>
<AuthComponent
onStart={onStartSocialMediaLogin}
onFailure={handleVerifyHandleError}
onSuccess={handleLoginSuccess}
>
<span>{messages.linkToClaim}</span>
</AuthComponent>
</TextLink>
) : null}
</>
) : null
const helperText =
handle && error ? (
<>
{error}{' '}
{onCompleteSocialMediaLogin &&
onStartSocialMediaLogin &&
onErrorSocialMediaLogin &&
AuthComponent ? (
<TextLink variant='visible' asChild>
<AuthComponent
onStart={onStartSocialMediaLogin}
onFailure={handleVerifyHandleError}
onSuccess={handleLoginSuccess}
>
<span>{messages.linkToClaim}</span>
</AuthComponent>
</TextLink>
) : null}
</>
) : null

return (
<HarmonyTextField
name='handle'
label={messages.handle}
helperText={helperText}
maxLength={MAX_HANDLE_LENGTH}
startAdornmentText='@'
placeholder={messages.handle}
transformValueOnChange={(value) => value.replace(/\s/g, '')}
debouncedValidationMs={1000}
{...other}
/>
)
}
return (
<HarmonyTextField
ref={ref}
name='handle'
label={messages.handle}
helperText={helperText}
maxLength={MAX_HANDLE_LENGTH}
startAdornmentText='@'
placeholder={messages.handle}
transformValueOnChange={(value) => value.replace(/\s/g, '')}
debouncedValidationMs={1000}
{...other}
/>
)
}
)
Loading

0 comments on commit 3e22ea8

Please sign in to comment.