erp-platform/ui/src/views/auth/Register.tsx

184 lines
6.2 KiB
TypeScript
Raw Normal View History

2025-05-06 06:45:49 +00:00
import ActionLink from '@/components/shared/ActionLink'
import PasswordInput from '@/components/shared/PasswordInput'
import Alert from '@/components/ui/Alert'
import Button from '@/components/ui/Button'
import { FormContainer, FormItem } from '@/components/ui/Form'
import Input from '@/components/ui/Input'
2025-06-28 21:34:28 +00:00
import { ROUTES_ENUM } from '@/routes/route.constant'
2025-05-06 06:45:49 +00:00
import useAuth from '@/utils/hooks/useAuth'
import useTimeOutMessage from '@/utils/hooks/useTimeOutMessage'
import Captcha from '@/components/shared/Captcha'
import { Field, Form, Formik } from 'formik'
import { useState } from 'react'
import * as Yup from 'yup'
2025-05-29 07:56:27 +00:00
import { useLocalization } from '@/utils/hooks/useLocalization'
2025-05-06 06:45:49 +00:00
type SignUpFormSchema = {
password: string
email: string
name: string
surname: string
captchaResponse: string
}
const validationSchema = Yup.object().shape({
2025-05-29 07:56:27 +00:00
email: Yup.string().email().required(),
password: Yup.string().required(),
2025-05-06 06:45:49 +00:00
confirmPassword: Yup.string().oneOf([Yup.ref('password')], 'Your passwords do not match'),
2025-05-29 07:56:27 +00:00
name: Yup.string().required(),
surname: Yup.string().required(),
2025-05-06 06:45:49 +00:00
})
const Register = () => {
const disableSubmit = false
2025-06-28 21:34:28 +00:00
const signInUrl = ROUTES_ENUM.public.login
2025-05-06 06:45:49 +00:00
const { signUp } = useAuth()
2025-05-29 07:56:27 +00:00
const { translate } = useLocalization()
2025-05-06 06:45:49 +00:00
const [message, setMessage] = useState('')
const [error, setError] = useTimeOutMessage(10000)
const onSignUp = async (
values: SignUpFormSchema,
setSubmitting: (isSubmitting: boolean) => void,
) => {
setSubmitting(true)
const result = await signUp(values)
if (result?.status === 'failed') {
setError(result.message)
setMessage('')
} else {
2025-05-29 07:56:27 +00:00
setMessage(translate('::Abp.Account.Register.ResultMessage'))
2025-05-06 06:45:49 +00:00
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
setError('')
}
setSubmitting(false)
}
return (
<>
<div className="mb-8">
2025-05-29 07:56:27 +00:00
<h3 className="mb-1">{translate('::Abp.Account.Register.Title')}</h3>
<p>{translate('::Abp.Account.Register.Message')}</p>
2025-05-06 06:45:49 +00:00
</div>
<div>
{message && (
<Alert showIcon className="mb-4" type="success">
{message}
</Alert>
)}
{error && (
<Alert showIcon className="mb-4" type="danger">
{error}
</Alert>
)}
<Formik
initialValues={{
email: '',
password: '',
confirmPassword: '',
name: '',
surname: '',
captchaResponse: '',
}}
validationSchema={validationSchema}
onSubmit={(values, { setSubmitting }) => {
if (!disableSubmit) {
onSignUp(values, setSubmitting)
} else {
setSubmitting(false)
}
}}
>
{({ touched, errors, isSubmitting, setFieldValue }) => (
<Form>
<FormContainer>
<FormItem
2025-05-29 07:56:27 +00:00
label={translate('::Abp.Account.EmailAddress')}
2025-05-06 06:45:49 +00:00
invalid={errors.email && touched.email}
errorMessage={errors.email}
>
<Field
type="email"
autoComplete="off"
name="email"
2025-05-29 07:56:27 +00:00
placeholder={translate('::Abp.Account.EmailAddress')}
2025-05-06 06:45:49 +00:00
component={Input}
/>
</FormItem>
<FormItem
2025-05-29 07:56:27 +00:00
label={translate('::Abp.Account.Password')}
2025-05-06 06:45:49 +00:00
invalid={errors.password && touched.password}
errorMessage={errors.password}
>
<Field
autoComplete="off"
name="password"
2025-05-29 07:56:27 +00:00
placeholder={translate('::Abp.Account.Password')}
2025-05-06 06:45:49 +00:00
component={PasswordInput}
/>
</FormItem>
<FormItem
2025-05-29 07:56:27 +00:00
label={translate('::Abp.Account.ConfirmPassword')}
2025-05-06 06:45:49 +00:00
invalid={errors.confirmPassword && touched.confirmPassword}
errorMessage={errors.confirmPassword}
>
<Field
autoComplete="off"
name="confirmPassword"
2025-05-29 07:56:27 +00:00
placeholder={translate('::Abp.Account.ConfirmPassword')}
2025-05-06 06:45:49 +00:00
component={PasswordInput}
/>
</FormItem>
<FormItem
2025-05-29 07:56:27 +00:00
label={translate('::Abp.Identity.User.UserInformation.Name')}
2025-05-06 06:45:49 +00:00
invalid={errors.name && touched.name}
errorMessage={errors.name}
>
<Field
type="name"
autoComplete="off"
name="name"
2025-05-29 07:56:27 +00:00
placeholder={translate('::Abp.Identity.User.UserInformation.Name')}
2025-05-06 06:45:49 +00:00
component={Input}
/>
</FormItem>
<FormItem
2025-05-29 07:56:27 +00:00
label={translate('::Abp.Identity.User.UserInformation.Surname')}
2025-05-06 06:45:49 +00:00
invalid={errors.surname && touched.surname}
errorMessage={errors.surname}
>
<Field
type="surname"
autoComplete="off"
name="surname"
2025-05-29 07:56:27 +00:00
placeholder={translate('::Abp.Identity.User.UserInformation.Surname')}
2025-05-06 06:45:49 +00:00
component={Input}
/>
</FormItem>
<Captcha
onError={() => setFieldValue('captchaResponse', '')}
onExpire={() => setFieldValue('captchaResponse', '')}
onSuccess={(token) => setFieldValue('captchaResponse', token)}
/>
<Button block loading={isSubmitting} variant="solid" type="submit">
{isSubmitting ? 'Creating Account...' : 'Sign Up'}
</Button>
<div className="mt-4 text-center">
2025-05-29 07:56:27 +00:00
<span>{translate('::Abp.Account.Register.AlreadyHaveAnAccount')} </span>
<ActionLink to={signInUrl}>{translate('::Abp.Account.SignIn')}</ActionLink>
2025-05-06 06:45:49 +00:00
</div>
</FormContainer>
</Form>
)}
</Formik>
</div>
</>
)
}
export default Register