Skip to content

Commit

Permalink
Make sure the sign in form doesn’t get submitted when pressing enter
Browse files Browse the repository at this point in the history
  • Loading branch information
paales committed Jan 4, 2024
1 parent c502d27 commit 7c6578c
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 95 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TextFieldElement, emailPattern } from '@graphcommerce/ecommerce-ui'
import { FormAutoSubmit, TextFieldElement, emailPattern } from '@graphcommerce/ecommerce-ui'
import { useApolloClient } from '@graphcommerce/graphql'
import {
ActionCard,
Expand All @@ -13,8 +13,7 @@ import {
import { Trans } from '@lingui/react'
import { Box, CircularProgress, Link, SxProps, Theme, Typography } from '@mui/material'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import { CustomerDocument, useFormIsEmailAvailable } from '../../hooks'
import { CustomerDocument, useAccountSignInUpForm } from '../../hooks'
import { useCustomerQuery } from '../../hooks/useCustomerQuery'
import { ApolloCustomerErrorAlert } from '../ApolloCustomerError'
import { SignInForm } from '../SignInForm/SignInForm'
Expand All @@ -25,98 +24,87 @@ export type AccountSignInUpFormProps = { sx?: SxProps<Theme> }
const parts = ['root', 'titleContainer'] as const
const { classes } = extendableComponent('AccountSignInUpForm', parts)

const titleContainerSx: SxProps<Theme> = (theme) => ({
typography: 'body1',
marginBottom: theme.spacings.xs,
})

export function AccountSignInUpForm(props: AccountSignInUpFormProps) {
const { sx = [] } = props
const customerQuery = useCustomerQuery(CustomerDocument)

const { email, firstname = '' } = customerQuery.data?.customer ?? {}

const { mode, form, autoSubmitting, submit } = useFormIsEmailAvailable()
const { mode, form, submit } = useAccountSignInUpForm()
const { formState, watch, control, error } = form
const disableFields = formState.isSubmitting && !autoSubmitting

const { setValue, trigger } = form
const router = useRouter()
useEffect(() => {
const emailFromParams = router.query.email as string
if (!email && emailFromParams) {
setValue('email', emailFromParams)
// eslint-disable-next-line @typescript-eslint/no-floating-promises
trigger('email')
}
}, [email, router.query.email, setValue, trigger])

const client = useApolloClient()

return (
<FormDiv sx={sx} className={classes.root}>
{mode === 'email' && (
<Box className={classes.titleContainer} sx={titleContainerSx}>
<LayoutTitle variant='h2' gutterBottom={false}>
<Trans id='Sign in or create an account!' />
</LayoutTitle>
<Typography variant='h6' align='center'>
<Trans id='Fill in your e-mail to login or create an account' />
</Typography>
</Box>
)}
<Box
className={classes.titleContainer}
sx={(theme) => ({ typography: 'body1', marginBottom: theme.spacings.xs })}
>
{mode === 'email' && (
<>
<LayoutTitle variant='h2' gutterBottom={false}>
<Trans id='Sign in or create an account!' />
</LayoutTitle>
<Typography variant='h6' align='center'>
<Trans id='Fill in your e-mail to login or create an account' />
</Typography>
</>
)}

{mode === 'signin' && (
<Box className={classes.titleContainer} sx={titleContainerSx}>
<LayoutTitle variant='h2' gutterBottom={false}>
<Trans id='Welcome back!' />
</LayoutTitle>
<Typography variant='h6' align='center'>
<Trans id='Fill in your password' />
</Typography>
</Box>
)}
{mode === 'signin' && (
<>
<LayoutTitle variant='h2' gutterBottom={false}>
<Trans id='Sign in' />
</LayoutTitle>
<Typography variant='h6' align='center'>
<Trans id='Fill in your password' />
</Typography>
</>
)}

{mode === 'signup' && (
<Box className={classes.titleContainer} sx={titleContainerSx}>
<LayoutTitle variant='h2' gutterBottom={false}>
<Trans id='Create account!' />
</LayoutTitle>
<Typography variant='h6' align='center'>
<Trans id='Create a password and tell us your name' />
</Typography>
</Box>
)}
{mode === 'signup' && (
<>
<LayoutTitle variant='h2' gutterBottom={false}>
<Trans id='Create account!' />
</LayoutTitle>
<Typography variant='h6' align='center'>
<Trans id='Create a password and tell us your name' />
</Typography>
</>
)}

{mode === 'signedin' && (
<Box className={classes.titleContainer} sx={titleContainerSx}>
<LayoutTitle variant='h2' gutterBottom={false}>
<Trans id='Hi {firstname}! You’re now logged in!' values={{ firstname }} />
</LayoutTitle>
<Typography variant='h6' align='center'>
<Link href='/account' underline='hover' color='secondary'>
<Trans id='View your account' />
</Link>
</Typography>

<FormActions>
<Button onClick={() => router.back()} variant='pill' color='secondary' size='large'>
<Trans id='Continue shopping' />
</Button>
</FormActions>
</Box>
)}
{mode === 'signedin' && (
<>
<LayoutTitle variant='h2' gutterBottom={false}>
<Trans id='Hi {firstname}! You’re now logged in!' values={{ firstname }} />
</LayoutTitle>
<Typography variant='h6' align='center'>
<Link href='/account' underline='hover' color='secondary'>
<Trans id='View your account' />
</Link>
</Typography>

<FormActions>
<Button onClick={() => router.back()} variant='pill' color='secondary' size='large'>
<Trans id='Continue shopping' />
</Button>
</FormActions>
</>
)}

{mode === 'session-expired' && (
<Box className={classes.titleContainer} sx={titleContainerSx}>
<LayoutTitle variant='h2' gutterBottom={false}>
<Trans id='Your session is expired' />
</LayoutTitle>
<Typography variant='h6' align='center'>
<Trans id='Log in to continue shopping' />
</Typography>
</Box>
)}
{mode === 'session-expired' && (
<>
<LayoutTitle variant='h2' gutterBottom={false}>
<Trans id='Your session is expired' />
</LayoutTitle>
<Typography variant='h6' align='center'>
<Trans id='Log in to continue shopping' />
</Typography>
</>
)}
</Box>

{!import.meta.graphCommerce.enableGuestCheckoutLogin &&
(mode === 'signin' || mode === 'signup' || mode === 'email') && (
Expand Down Expand Up @@ -146,6 +134,7 @@ export function AccountSignInUpForm(props: AccountSignInUpFormProps) {

{mode !== 'signedin' && (
<form onSubmit={submit}>
<FormAutoSubmit {...form} submit={submit} />
<Box>
<FormRow>
<TextFieldElement
Expand All @@ -160,7 +149,6 @@ export function AccountSignInUpForm(props: AccountSignInUpFormProps) {
}}
error={formState.isSubmitted && !!formState.errors.email}
label={<Trans id='Email' />}
disabled={disableFields}
InputProps={{
endAdornment:
mode === 'session-expired' ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export function SignInForm(props: SignInFormProps) {
variant='pill'
size='large'
>
<Trans id='Log in' />
<Trans id='Sign in' />
</Button>
</FormControl>
</FormActions>
Expand Down
2 changes: 1 addition & 1 deletion packages/magento-customer/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export * from './CustomerToken.gql'
export * from './IsEmailAvailable.gql'
export * from './useCustomerQuery'
export * from './useCustomerSession'
export * from './useFormIsEmailAvailable'
export * from './useAccountSignInUpForm'
export * from './useGuestQuery'
export { default as useOrderCardItemImages } from './useOrderCardItemImages'
export * from './UseOrderCardItemImages.gql'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useApolloClient, useMutation, useQuery } from '@graphcommerce/graphql'
import { useFormAutoSubmit, useFormGqlQuery } from '@graphcommerce/react-hook-form'
import { SignOutFormDocument } from '../components/SignOutForm/SignOutForm.gql'
import { useQuery } from '@graphcommerce/graphql'
import { useFormGqlQuery } from '@graphcommerce/react-hook-form'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import { CustomerDocument } from './Customer.gql'
import {
IsEmailAvailableDocument,
Expand All @@ -17,7 +18,7 @@ export type AccountSignInUpState = 'email' | 'signin' | 'signup' | 'signedin' |

export const isToggleMethod = !import.meta.graphCommerce.enableGuestCheckoutLogin

export function useFormIsEmailAvailable(props: UseFormIsEmailAvailableProps = {}) {
export function useAccountSignInUpForm(props: UseFormIsEmailAvailableProps = {}) {
const { onSubmitted } = props
const { token, valid } = useCustomerSession()

Expand All @@ -31,24 +32,32 @@ export function useFormIsEmailAvailable(props: UseFormIsEmailAvailableProps = {}
IsEmailAvailableDocument,
{
experimental_useV2: true,
mode: 'onChange',
mode: 'onBlur',
values: { email: cachedEmail ?? '' },
defaultValues: { requestedMode: 'signin' },
},
{ fetchPolicy: 'cache-and-network' },
)
const { formState, data, handleSubmit } = form
const { isSubmitSuccessful, isValid } = formState

const submit = isToggleMethod ? () => Promise.resolve() : handleSubmit(onSubmitted || (() => {}))
const router = useRouter()
useEffect(() => {
const emailFromParams = router.query.email as string

const autoSubmitting = useFormAutoSubmit({
form,
submit,
forceInitialSubmit: true,
disabled: isToggleMethod,
})
if (!cachedEmail && emailFromParams) {
form.setValue('email', emailFromParams)
// eslint-disable-next-line @typescript-eslint/no-floating-promises
form.trigger('email')
}
}, [cachedEmail, router.query.email, form])

const { isSubmitSuccessful, isValid } = formState
const submit = isToggleMethod
? async (e?: React.BaseSyntheticEvent) => {
e?.preventDefault()
await form.trigger('email')
}
: handleSubmit(onSubmitted || (() => {}))

const hasAccount = data?.isEmailAvailable?.is_email_available === false

Expand All @@ -64,5 +73,5 @@ export function useFormIsEmailAvailable(props: UseFormIsEmailAvailableProps = {}
if (isValid && isSubmitSuccessful) mode = hasAccount ? 'signin' : 'signup'
}

return { mode, form, submit, autoSubmitting, hasAccount }
return { mode, form, submit }
}

0 comments on commit 7c6578c

Please sign in to comment.