201 lines
6.7 KiB
JavaScript
201 lines
6.7 KiB
JavaScript
import { yupResolver } from '@hookform/resolvers/yup';
|
|
import _ from '@lodash';
|
|
import Button from '@mui/material/Button';
|
|
import Checkbox from '@mui/material/Checkbox';
|
|
import FormControl from '@mui/material/FormControl';
|
|
import FormControlLabel from '@mui/material/FormControlLabel';
|
|
import FormHelperText from '@mui/material/FormHelperText';
|
|
import Paper from '@mui/material/Paper';
|
|
import TextField from '@mui/material/TextField';
|
|
import Typography from '@mui/material/Typography';
|
|
import { Controller, useForm } from 'react-hook-form';
|
|
import { withTranslation } from 'react-i18next';
|
|
import { Link } from 'react-router-dom';
|
|
import * as yup from 'yup';
|
|
import LeftSideCanvas from '../shared-components/LeftSideCanvas';
|
|
|
|
const defaultValues = {
|
|
name: '',
|
|
email: '',
|
|
password: '',
|
|
passwordConfirm: '',
|
|
acceptTermsConditions: false,
|
|
};
|
|
|
|
function SignUpPage({ t }) {
|
|
const schema = yup.object().shape({
|
|
name: yup.string().required(t('name_error')),
|
|
email: yup.string().email(t('email_error')).required(t('email_error')),
|
|
password: yup.string().required(t('password_error')).min(8, t('password_error')),
|
|
passwordConfirm: yup.string().oneOf([yup.ref('password'), null], t('password_confirm_error')),
|
|
acceptTermsConditions: yup.boolean().oneOf([true], t('accept_terms_error')),
|
|
});
|
|
|
|
const { control, formState, handleSubmit, reset } = useForm({
|
|
mode: 'onChange',
|
|
defaultValues,
|
|
resolver: yupResolver(schema),
|
|
});
|
|
|
|
const { isValid, dirtyFields, errors } = formState;
|
|
|
|
function onSubmit() {
|
|
reset(defaultValues);
|
|
}
|
|
|
|
return (
|
|
<div className="h-full flex flex-col sm:flex-row items-center md:items-start sm:justify-center md:justify-start flex-auto min-w-0">
|
|
<LeftSideCanvas title={t('title')} subtitle={t('subtitle')} text={t('text')} />
|
|
|
|
<Paper
|
|
className="h-full w-full sm:h-auto md:flex md:h-full py-32 px-16 sm:p-48 md:p-40 md:px-96 sm:rounded-2xl md:rounded-none sm:shadow md:shadow-none rtl:border-r-1 ltr:border-l-1"
|
|
sx={{ background: (theme) => theme.palette.background?.authPaper }}
|
|
>
|
|
<div className="w-full mx-auto sm:mx-0">
|
|
<Typography className="text-4xl font-extrabold tracking-tight leading-tight">
|
|
{t('sign_up')}
|
|
</Typography>
|
|
<div className="flex items-baseline mt-10 font-medium">
|
|
<Typography>{t('have_account')}</Typography>
|
|
<Link className="ml-4 text-indigo-400 underline" to="/sign-in">
|
|
{t('sign_in')}
|
|
</Link>
|
|
</div>
|
|
|
|
<form
|
|
name="signupForm"
|
|
noValidate
|
|
className="flex flex-col justify-center w-full mt-48"
|
|
onSubmit={handleSubmit(onSubmit)}
|
|
>
|
|
<Controller
|
|
name="name"
|
|
control={control}
|
|
render={({ field }) => (
|
|
<TextField
|
|
{...field}
|
|
className="mb-28"
|
|
label={t('name')}
|
|
autoFocus
|
|
type="name"
|
|
error={!!errors.name}
|
|
helperText={errors?.name?.message}
|
|
variant="outlined"
|
|
required
|
|
fullWidth
|
|
InputProps={{
|
|
sx: {
|
|
background: (theme) => theme.palette.background.paper,
|
|
},
|
|
}}
|
|
/>
|
|
)}
|
|
/>
|
|
|
|
<Controller
|
|
name="email"
|
|
control={control}
|
|
render={({ field }) => (
|
|
<TextField
|
|
{...field}
|
|
className="mb-28"
|
|
label={t('email')}
|
|
type="email"
|
|
error={!!errors.email}
|
|
helperText={errors?.email?.message}
|
|
variant="outlined"
|
|
required
|
|
fullWidth
|
|
InputProps={{
|
|
sx: {
|
|
background: (theme) => theme.palette.background.paper,
|
|
},
|
|
}}
|
|
/>
|
|
)}
|
|
/>
|
|
|
|
<Controller
|
|
name="password"
|
|
control={control}
|
|
render={({ field }) => (
|
|
<TextField
|
|
{...field}
|
|
className="mb-28"
|
|
label={t('password')}
|
|
type="password"
|
|
error={!!errors.password}
|
|
helperText={errors?.password?.message}
|
|
variant="outlined"
|
|
required
|
|
fullWidth
|
|
InputProps={{
|
|
sx: {
|
|
background: (theme) => theme.palette.background.paper,
|
|
},
|
|
}}
|
|
/>
|
|
)}
|
|
/>
|
|
|
|
<Controller
|
|
name="passwordConfirm"
|
|
control={control}
|
|
render={({ field }) => (
|
|
<TextField
|
|
{...field}
|
|
className="mb-28"
|
|
label={t('password_confirm')}
|
|
type="password"
|
|
error={!!errors.passwordConfirm}
|
|
helperText={errors?.passwordConfirm?.message}
|
|
variant="outlined"
|
|
required
|
|
fullWidth
|
|
InputProps={{
|
|
sx: {
|
|
background: (theme) => theme.palette.background.paper,
|
|
},
|
|
}}
|
|
/>
|
|
)}
|
|
/>
|
|
|
|
<Controller
|
|
name="acceptTermsConditions"
|
|
control={control}
|
|
render={({ field }) => (
|
|
<FormControl className="items-start" error={!!errors.acceptTermsConditions}>
|
|
<FormControlLabel
|
|
label={t('accept_terms')}
|
|
control={
|
|
<Checkbox {...field} sx={{ color: (theme) => theme.palette.border.light }} />
|
|
}
|
|
/>
|
|
<FormHelperText>{errors?.acceptTermsConditions?.message}</FormHelperText>
|
|
</FormControl>
|
|
)}
|
|
/>
|
|
|
|
<div className="flex justify-center w-full">
|
|
<Button
|
|
variant="contained"
|
|
color="secondary"
|
|
className="max-w-320 mt-32 text-base uppercase rounded-xl"
|
|
aria-label={t('sign_up_btn')}
|
|
disabled={_.isEmpty(dirtyFields) || !isValid}
|
|
type="submit"
|
|
size="large"
|
|
>
|
|
{t('sign_up_btn')}
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</Paper>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default withTranslation('signUpPage')(SignUpPage);
|