frontend/src/components/pages/SignUpPage.jsx
import React, { useRef, useState } from 'react';
import { useFormik } from 'formik';
import * as Yup from 'yup';
import { useTranslation } from 'react-i18next';
import { Form } from 'react-bootstrap';
import { useNavigate, Navigate } from 'react-router-dom';
import axios from 'axios';
import routes from '../../routes.js';
import { useAuth } from '../../hooks/index';
import Img from '../Img';
const SignUpPage = () => {
const auth = useAuth();
const inputRef = useRef();
const navigate = useNavigate();
const { t } = useTranslation();
const [isUserExists, setIsUserExists] = useState(false);
const formik = useFormik({
initialValues: {
username: '',
password: '',
passwordConfirmation: '',
},
validationSchema: Yup.object({
username: Yup.string('')
.min(3, `${t('usernameLength')}`)
.max(20, `${t('usernameLength')}`)
.required(`${t('requiredField')}`),
password: Yup.string()
.min(6, `${t('passwordLength')}`)
.required(`${t('requiredField')}`),
passwordConfirmation: Yup.string()
.required(`${t('requiredField')}`)
.oneOf(
[Yup.ref('password'), null],
`${t('passwordConfirmationMessage')}`,
),
}),
onSubmit: async (values) => {
try {
const response = await axios
.post(routes.signUpPath(), { username: values.username, password: values.password });
if (response.status === 201) {
auth.logIn(response.data);
navigate('/');
}
} catch (errors) {
formik.setSubmitting(false);
if (errors.isAxiosError && errors.response.status === 401) {
inputRef.current.select();
return;
}
if (errors.isAxiosError && errors.response.status === 409) {
inputRef.current.select();
setIsUserExists(true);
}
}
},
});
if (auth.loggedIn) {
return <Navigate to={`${routes.root()}`} />;
}
return (
<main className="main">
<div className="loginContainer">
<Img />
<fieldset disabled={formik.isSubmitting}>
<Form onSubmit={formik.handleSubmit}>
<h1 className="text-center mb-4">{t('signUp')}</h1>
<Form.Group className="form-floating mb-3">
<Form.Control
id="username"
name="username"
placeholder="username"
autoComplete="username"
onChange={formik.handleChange}
value={formik.values.username}
isInvalid={(formik.touched.username && formik.errors.username) || isUserExists}
onBlur={formik.handleBlur}
ref={inputRef}
required
autoFocus
/>
<Form.Label htmlFor="username">{t('username')}</Form.Label>
<Form.Control.Feedback type="invalid">{formik.errors.username}</Form.Control.Feedback>
</Form.Group>
<Form.Group className="form-floating mb-3">
<Form.Control
type="password"
id="password"
name="password"
placeholder="password"
onChange={formik.handleChange}
value={formik.values.password}
isInvalid={(formik.touched.password && formik.errors.password) || isUserExists}
onBlur={formik.handleBlur}
autoComplete="password"
required
/>
<Form.Label htmlFor="password">{t('password')}</Form.Label>
<Form.Control.Feedback type="invalid">{formik.errors.password}</Form.Control.Feedback>
</Form.Group>
<Form.Group className="form-floating mb-3">
<Form.Control
type="password"
id="passwordConfirmation"
name="passwordConfirmation"
placeholder="passwordConfirmation"
onChange={formik.handleChange}
value={formik.values.passwordConfirmation}
isInvalid={(formik.touched.passwordConfirmation
&& formik.errors.passwordConfirmation) || isUserExists}
onBlur={formik.handleBlur}
autoComplete="current-password"
required
/>
<Form.Label htmlFor="passwordConfirmation">{t('passwordConfirmation')}</Form.Label>
<Form.Control.Feedback type="invalid">{isUserExists ? `${t('userExistsMessage')}` : formik.errors.passwordConfirmation}</Form.Control.Feedback>
</Form.Group>
<button type="submit" className="btn-submit">{t('signUp')}</button>
</Form>
</fieldset>
</div>
</main>
);
};
export default SignUpPage;