fix(next): adds client-side field validations to login and forgot-password views (#5871)
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
'use client'
|
||||
|
||||
import type { FormState, PayloadRequest } from 'payload/types'
|
||||
|
||||
import { Email } from '@payloadcms/ui/fields/Email'
|
||||
import { Form } from '@payloadcms/ui/forms/Form'
|
||||
import { FormSubmit } from '@payloadcms/ui/forms/Submit'
|
||||
import { useConfig } from '@payloadcms/ui/providers/Config'
|
||||
import { useTranslation } from '@payloadcms/ui/providers/Translation'
|
||||
import { email } from 'payload/fields/validations'
|
||||
import React, { Fragment, useState } from 'react'
|
||||
import { toast } from 'react-toastify'
|
||||
|
||||
export const ForgotPasswordForm: React.FC = () => {
|
||||
const config = useConfig()
|
||||
|
||||
const {
|
||||
admin: { user: userSlug },
|
||||
routes: { api },
|
||||
} = config
|
||||
|
||||
const { t } = useTranslation()
|
||||
const [hasSubmitted, setHasSubmitted] = useState(false)
|
||||
|
||||
const handleResponse = (res) => {
|
||||
res.json().then(
|
||||
() => {
|
||||
setHasSubmitted(true)
|
||||
},
|
||||
() => {
|
||||
toast.error(t('authentication:emailNotValid'))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
const initialState: FormState = {
|
||||
email: {
|
||||
initialValue: '',
|
||||
valid: true,
|
||||
value: undefined,
|
||||
},
|
||||
}
|
||||
|
||||
if (hasSubmitted) {
|
||||
return (
|
||||
<Fragment>
|
||||
<h1>{t('authentication:emailSent')}</h1>
|
||||
<p>{t('authentication:checkYourEmailForPasswordReset')}</p>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Form
|
||||
action={`${api}/${userSlug}/forgot-password`}
|
||||
handleResponse={handleResponse}
|
||||
initialState={initialState}
|
||||
method="POST"
|
||||
>
|
||||
<h1>{t('authentication:forgotPassword')}</h1>
|
||||
<p>{t('authentication:forgotPasswordEmailInstructions')}</p>
|
||||
<Email
|
||||
autoComplete="email"
|
||||
label={t('general:email')}
|
||||
name="email"
|
||||
required
|
||||
validate={(value) =>
|
||||
email(value, {
|
||||
name: 'email',
|
||||
type: 'email',
|
||||
data: {},
|
||||
req: { t } as PayloadRequest,
|
||||
required: true,
|
||||
siblingData: {},
|
||||
})
|
||||
}
|
||||
/>
|
||||
<FormSubmit>{t('general:submit')}</FormSubmit>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
@@ -2,12 +2,11 @@ import type { AdminViewProps } from 'payload/types'
|
||||
|
||||
import { Button } from '@payloadcms/ui/elements/Button'
|
||||
import { Translation } from '@payloadcms/ui/elements/Translation'
|
||||
import { Email } from '@payloadcms/ui/fields/Email'
|
||||
import { Form } from '@payloadcms/ui/forms/Form'
|
||||
import { FormSubmit } from '@payloadcms/ui/forms/Submit'
|
||||
import LinkImport from 'next/link.js'
|
||||
import React, { Fragment } from 'react'
|
||||
|
||||
import { ForgotPasswordForm } from './ForgotPasswordForm/index.js'
|
||||
|
||||
export { generateForgotPasswordMetadata } from './meta.js'
|
||||
|
||||
const Link = (LinkImport.default || LinkImport) as unknown as typeof LinkImport.default
|
||||
@@ -23,22 +22,9 @@ export const ForgotPasswordView: React.FC<AdminViewProps> = ({ initPageResult })
|
||||
} = initPageResult
|
||||
|
||||
const {
|
||||
admin: { user: userSlug },
|
||||
routes: { admin, api },
|
||||
serverURL,
|
||||
routes: { admin },
|
||||
} = config
|
||||
|
||||
// const handleResponse = (res) => {
|
||||
// res.json().then(
|
||||
// () => {
|
||||
// setHasSubmitted(true)
|
||||
// },
|
||||
// () => {
|
||||
// toast.error(i18n.t('authentication:emailNotValid'))
|
||||
// },
|
||||
// )
|
||||
// }
|
||||
|
||||
if (user) {
|
||||
return (
|
||||
<Fragment>
|
||||
@@ -60,34 +46,9 @@ export const ForgotPasswordView: React.FC<AdminViewProps> = ({ initPageResult })
|
||||
)
|
||||
}
|
||||
|
||||
// if (hasSubmitted) {
|
||||
// return (
|
||||
// <Fragment>
|
||||
// <h1>{i18n.t('authentication:emailSent')}</h1>
|
||||
// <p>{i18n.t('authentication:checkYourEmailForPasswordReset')}</p>
|
||||
// </Fragment>
|
||||
// )
|
||||
// }
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Form
|
||||
action={`${serverURL}${api}/${userSlug}/forgot-password`}
|
||||
// handleResponse={handleResponse}
|
||||
initialState={{
|
||||
email: {
|
||||
initialValue: '',
|
||||
valid: false,
|
||||
value: undefined,
|
||||
},
|
||||
}}
|
||||
method="POST"
|
||||
>
|
||||
<h1>{i18n.t('authentication:forgotPassword')}</h1>
|
||||
<p>{i18n.t('authentication:forgotPasswordEmailInstructions')}</p>
|
||||
<Email autoComplete="email" label={i18n.t('general:emailAddress')} name="email" required />
|
||||
<FormSubmit>{i18n.t('general:submit')}</FormSubmit>
|
||||
</Form>
|
||||
<ForgotPasswordForm />
|
||||
<Link href={`${admin}/login`}>{i18n.t('authentication:backToLogin')}</Link>
|
||||
</Fragment>
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@ import React from 'react'
|
||||
const baseClass = 'login__form'
|
||||
const Link = (LinkImport.default || LinkImport) as unknown as typeof LinkImport.default
|
||||
|
||||
import type { FormState } from 'payload/types'
|
||||
import type { FormState, PayloadRequest } from 'payload/types'
|
||||
|
||||
import { FormLoadingOverlayToggle } from '@payloadcms/ui/elements/Loading'
|
||||
import { Email } from '@payloadcms/ui/fields/Email'
|
||||
@@ -15,6 +15,7 @@ import { Form } from '@payloadcms/ui/forms/Form'
|
||||
import { FormSubmit } from '@payloadcms/ui/forms/Submit'
|
||||
import { useConfig } from '@payloadcms/ui/providers/Config'
|
||||
import { useTranslation } from '@payloadcms/ui/providers/Translation'
|
||||
import { email, password } from 'payload/fields/validations'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
@@ -57,8 +58,43 @@ export const LoginForm: React.FC<{
|
||||
>
|
||||
<FormLoadingOverlayToggle action="loading" name="login-form" />
|
||||
<div className={`${baseClass}__inputWrap`}>
|
||||
<Email autoComplete="email" label={t('general:email')} name="email" required />
|
||||
<Password autoComplete="off" label={t('general:password')} name="password" required />
|
||||
<Email
|
||||
autoComplete="email"
|
||||
label={t('general:email')}
|
||||
name="email"
|
||||
required
|
||||
validate={(value) =>
|
||||
email(value, {
|
||||
name: 'email',
|
||||
type: 'email',
|
||||
data: {},
|
||||
req: { t } as PayloadRequest,
|
||||
required: true,
|
||||
siblingData: {},
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Password
|
||||
autoComplete="off"
|
||||
label={t('general:password')}
|
||||
name="password"
|
||||
required
|
||||
validate={(value) =>
|
||||
password(value, {
|
||||
name: 'password',
|
||||
type: 'text',
|
||||
data: {},
|
||||
req: {
|
||||
payload: {
|
||||
config,
|
||||
},
|
||||
t,
|
||||
} as PayloadRequest,
|
||||
required: true,
|
||||
siblingData: {},
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<Link href={`${admin}/forgot`}>{t('authentication:forgotPasswordQuestion')}</Link>
|
||||
<FormSubmit>{t('authentication:login')}</FormSubmit>
|
||||
|
||||
@@ -6,6 +6,7 @@ export const clientTranslationKeys = [
|
||||
'authentication:backToLogin',
|
||||
'authentication:beginCreateFirstUser',
|
||||
'authentication:changePassword',
|
||||
'authentication:checkYourEmailForPasswordReset',
|
||||
'authentication:confirmGeneration',
|
||||
'authentication:confirmPassword',
|
||||
'authentication:createFirstUser',
|
||||
@@ -222,10 +223,13 @@ export const clientTranslationKeys = [
|
||||
'upload:sizesFor',
|
||||
'upload:width',
|
||||
|
||||
'validation:emailAddress',
|
||||
'validation:fieldHasNo',
|
||||
'validation:limitReached',
|
||||
'validation:longerThanMin',
|
||||
'validation:required',
|
||||
'validation:requiresAtLeast',
|
||||
'validation:shorterThanMax',
|
||||
|
||||
'version:aboutToPublishSelection',
|
||||
'version:aboutToRestore',
|
||||
|
||||
Reference in New Issue
Block a user