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
|