added form validation
This commit is contained in:
parent
8622f9e9db
commit
3912bc0044
8 changed files with 120 additions and 56 deletions
|
|
@ -79,7 +79,6 @@ export const authUser = async (data: IAuthData) => {
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
});
|
});
|
||||||
const responseData = await handleResponse(response);
|
const responseData = await handleResponse(response);
|
||||||
console.log("Полный ответ сервера:", responseData);
|
|
||||||
|
|
||||||
const token = responseData.accessToken || responseData.token;
|
const token = responseData.accessToken || responseData.token;
|
||||||
if (token) {
|
if (token) {
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,30 @@
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 88%;
|
line-height: 88%;
|
||||||
color: #000000; /* Цвет текста по умолчанию */
|
color: #000000;
|
||||||
outline: none;
|
outline: none;
|
||||||
border: none;
|
border: none;
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.2); /* Нижняя граница с прозрачностью */
|
border-bottom: 2px solid rgba(0, 0, 0, 0.2);
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
opacity: 1; /* Установите opacity в 1 для input, а для placeholder используйте opacity */
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password_container{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password_container .error{
|
||||||
|
border-bottom: 2px solid rgba(192, 35, 31, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.errorMessage{
|
||||||
|
text-align: left;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 88%;
|
||||||
|
color: #C0231F;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input::placeholder {
|
.input::placeholder {
|
||||||
|
|
@ -42,21 +60,20 @@
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 88%;
|
line-height: 88%;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
opacity: 0.2; /* Прозрачность placeholder */
|
opacity: 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input:focus::placeholder {
|
.input:focus::placeholder {
|
||||||
opacity: 0; /* Убираем placeholder при фокусе */
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Отключаем стиль для input, когда в нём есть данные */
|
|
||||||
.input:not(:placeholder-shown) {
|
.input:not(:placeholder-shown) {
|
||||||
color: black;
|
color: black;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input:focus {
|
.input:focus {
|
||||||
border-bottom: 1px solid black; /* Чёрная граница при фокусе */
|
border-bottom: 2px solid black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.signIn{
|
.signIn{
|
||||||
|
|
|
||||||
|
|
@ -10,24 +10,33 @@ const LoginForm = () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
|
||||||
const emailRef = useRef<HTMLInputElement>(null); // ref для поля email
|
const emailRef = useRef<HTMLInputElement>(null);
|
||||||
const passwordRef = useRef<HTMLInputElement>(null); // ref для поля password
|
const passwordRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const email = emailRef.current?.value || '';
|
const email = emailRef.current?.value ?? '';
|
||||||
const password = passwordRef.current?.value || '';
|
const password = passwordRef.current?.value ?? '';
|
||||||
|
setError(null);
|
||||||
|
|
||||||
try{
|
try{
|
||||||
const responseData = await authUser({email, password});
|
const responseData = await authUser({email, password});
|
||||||
if (responseData && !responseData.error)
|
if (responseData && !responseData.error)
|
||||||
navigate('/my-surveys');
|
navigate('/my-surveys');
|
||||||
else
|
else
|
||||||
console.error('Ошибка аутентификации:', responseData);
|
setError('Неверный логин или пароль')
|
||||||
}
|
}
|
||||||
catch(err){
|
catch(err){
|
||||||
console.error('Ошибка при отправке запроса:', err);
|
console.error('Ошибка при отправке запроса:', err);
|
||||||
|
setError('Неверный логин или пароль')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChange = () => {
|
||||||
|
if (error) {
|
||||||
|
setError(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,19 +49,24 @@ const LoginForm = () => {
|
||||||
type={'email'}
|
type={'email'}
|
||||||
placeholder='Почта'
|
placeholder='Почта'
|
||||||
ref={emailRef}
|
ref={emailRef}
|
||||||
|
onChange={handleChange}
|
||||||
onFocus={() => setFocused({ ...focused, email: true })}
|
onFocus={() => setFocused({ ...focused, email: true })}
|
||||||
onBlur={() => setFocused({ ...focused, email: false })}
|
onBlur={() => setFocused({ ...focused, email: false })}
|
||||||
style={{ color: focused.email ? 'black' : 'inherit' }}
|
style={{ color: focused.email ? 'black' : 'inherit' }}
|
||||||
/>
|
/>
|
||||||
|
<div className={styles.password_container}>
|
||||||
<input
|
<input
|
||||||
className={`${styles.input} ${styles.password}`}
|
className={`${styles.input} ${styles.password} ${error ? styles.error : ''}`}
|
||||||
type='password'
|
type='password'
|
||||||
placeholder='Пароль'
|
placeholder='Пароль'
|
||||||
ref={passwordRef}
|
ref={passwordRef}
|
||||||
|
onChange={handleChange}
|
||||||
onFocus={() => setFocused({ ...focused, password: true })}
|
onFocus={() => setFocused({ ...focused, password: true })}
|
||||||
onBlur={() => setFocused({ ...focused, password: false })}
|
onBlur={() => setFocused({ ...focused, password: false })}
|
||||||
style={{ color: focused.password ? 'black' : 'inherit' }}
|
style={{ color: focused.password ? 'black' : 'inherit' }}
|
||||||
/>
|
/>
|
||||||
|
{error && <p className={styles.errorMessage}>{error}</p>}
|
||||||
|
</div>
|
||||||
<button className={styles.signIn} type="submit">Войти</button>
|
<button className={styles.signIn} type="submit">Войти</button>
|
||||||
</form>
|
</form>
|
||||||
<p className={styles.recommendation}>Еще не с нами?
|
<p className={styles.recommendation}>Еще не с нами?
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,12 @@
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 88%;
|
line-height: 88%;
|
||||||
color: #000000; /* Цвет текста по умолчанию */
|
color: #000000;
|
||||||
outline: none;
|
outline: none;
|
||||||
border: none;
|
border: none;
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.2); /* Нижняя граница с прозрачностью */
|
border-bottom: 1px solid rgba(0, 0, 0, 0.2);
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
opacity: 1; /* Установите opacity в 1 для input, а для placeholder используйте opacity */
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input::placeholder {
|
.input::placeholder {
|
||||||
|
|
@ -41,11 +41,11 @@
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 88%;
|
line-height: 88%;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
opacity: 0.2; /* Прозрачность placeholder */
|
opacity: 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input:focus::placeholder {
|
.input:focus::placeholder {
|
||||||
opacity: 0; /* Убираем placeholder при фокусе */
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Отключаем стиль для input, когда в нём есть данные */
|
/* Отключаем стиль для input, когда в нём есть данные */
|
||||||
|
|
@ -82,3 +82,22 @@
|
||||||
color: #3788D6;
|
color: #3788D6;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.emailContainer{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emailContainer .error{
|
||||||
|
border-bottom: 2px solid rgba(192, 35, 31, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.errorMessage{
|
||||||
|
text-align: left;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 88%;
|
||||||
|
color: #C0231F;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
@ -11,6 +11,8 @@ const RegisterForm = () => {
|
||||||
password: false
|
password: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
|
||||||
const nameRef = useRef<HTMLInputElement>(null);
|
const nameRef = useRef<HTMLInputElement>(null);
|
||||||
const surnameRef = useRef<HTMLInputElement>(null);
|
const surnameRef = useRef<HTMLInputElement>(null);
|
||||||
const emailRef = useRef<HTMLInputElement>(null);
|
const emailRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
@ -20,15 +22,16 @@ const RegisterForm = () => {
|
||||||
|
|
||||||
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const firstName = nameRef.current?.value || '';
|
const firstName = nameRef.current?.value ?? '';
|
||||||
const lastName = surnameRef.current?.value || '';
|
const lastName = surnameRef.current?.value ?? '';
|
||||||
const email = emailRef.current?.value || '';
|
const email = emailRef.current?.value ?? '';
|
||||||
const password = passwordRef.current?.value || '';
|
const password = passwordRef.current?.value ?? '';
|
||||||
const username = firstName + lastName || '';
|
const username = firstName + lastName || '';
|
||||||
|
|
||||||
|
setError(null);
|
||||||
|
|
||||||
try{
|
try{
|
||||||
const responseData = await registerUser({username, firstName, lastName, email, password});
|
const responseData = await registerUser({username, firstName, lastName, email, password});
|
||||||
console.log(responseData); //проверка вывода данных
|
|
||||||
if (responseData && !responseData.error) {
|
if (responseData && !responseData.error) {
|
||||||
console.log('Регистрация успешна');
|
console.log('Регистрация успешна');
|
||||||
localStorage.setItem("user", JSON.stringify({
|
localStorage.setItem("user", JSON.stringify({
|
||||||
|
|
@ -37,15 +40,28 @@ const RegisterForm = () => {
|
||||||
}));
|
}));
|
||||||
navigate('/my-surveys');
|
navigate('/my-surveys');
|
||||||
}
|
}
|
||||||
else {
|
else if (responseData.status === 409){
|
||||||
console.error(`Ошибка регистрации: ${responseData}`);
|
setError('Аккаунт с такой почтой уже зарегистрирован');
|
||||||
console.log('Регистраиця не удалась');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
console.error(`Ошибка при отправке запроса ${err}`);
|
if (err instanceof Error) {
|
||||||
|
if (err.message.includes('409')) {
|
||||||
|
setError('Аккаунт с такой почтой уже зарегистрирован');
|
||||||
|
} else {
|
||||||
|
setError('Произошла ошибка при регистрации');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setError('Неизвестная ошибка');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleEmailChange = () => {
|
||||||
|
if (error) {
|
||||||
|
setError(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.registerContainer}>
|
<div className={styles.registerContainer}>
|
||||||
|
|
@ -69,15 +85,19 @@ const RegisterForm = () => {
|
||||||
onBlur={() => setFocused({ ...focused, lastName: false })}
|
onBlur={() => setFocused({ ...focused, lastName: false })}
|
||||||
style={{ color: focused.lastName ? 'black' : 'inherit' }}
|
style={{ color: focused.lastName ? 'black' : 'inherit' }}
|
||||||
/>
|
/>
|
||||||
|
<div className={styles.emailContainer}>
|
||||||
<input
|
<input
|
||||||
className={`${styles.input} ${styles.email}`}
|
className={`${styles.input} ${styles.email} ${error ? styles.error : ''}`}
|
||||||
type={'email'}
|
type={'email'}
|
||||||
placeholder='Почта'
|
placeholder='Почта'
|
||||||
ref={emailRef}
|
ref={emailRef}
|
||||||
|
onChange={handleEmailChange}
|
||||||
onFocus={() => setFocused({ ...focused, email: true })}
|
onFocus={() => setFocused({ ...focused, email: true })}
|
||||||
onBlur={() => setFocused({ ...focused, email: false })}
|
onBlur={() => setFocused({ ...focused, email: false })}
|
||||||
style={{ color: focused.email ? 'black' : 'inherit' }}
|
style={{ color: focused.email ? 'black' : 'inherit' }}
|
||||||
/>
|
/>
|
||||||
|
{error && <p className={styles.errorMessage}>{error}</p>}
|
||||||
|
</div>
|
||||||
<input
|
<input
|
||||||
className={`${styles.input} ${styles.password}`}
|
className={`${styles.input} ${styles.password}`}
|
||||||
type='password'
|
type='password'
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
.survey_page{
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ import {useEffect, useState} from "react";
|
||||||
import {getSurveyById, ISurvey} from "../../api/SurveyApi.ts";
|
import {getSurveyById, ISurvey} from "../../api/SurveyApi.ts";
|
||||||
import {useParams} from "react-router-dom";
|
import {useParams} from "react-router-dom";
|
||||||
import {getListQuestions} from "../../api/QuestionApi.ts";
|
import {getListQuestions} from "../../api/QuestionApi.ts";
|
||||||
|
import styles from "./SurveyPage.module.css";
|
||||||
|
|
||||||
export const SurveyPage: React.FC = () => {
|
export const SurveyPage: React.FC = () => {
|
||||||
const [survey, setSurvey] = useState<ISurvey | null>(null);
|
const [survey, setSurvey] = useState<ISurvey | null>(null);
|
||||||
|
|
@ -50,7 +51,7 @@ export const SurveyPage: React.FC = () => {
|
||||||
if (!survey) return <div>Опрос не найден</div>;
|
if (!survey) return <div>Опрос не найден</div>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="survey-page">
|
<div className={styles.survey_page}>
|
||||||
<SurveyInfo
|
<SurveyInfo
|
||||||
titleSurvey={survey.title}
|
titleSurvey={survey.title}
|
||||||
descriptionSurvey={survey.description}
|
descriptionSurvey={survey.description}
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,6 @@ import {useLocation} from "react-router-dom";
|
||||||
|
|
||||||
|
|
||||||
const AuthForm = () => {
|
const AuthForm = () => {
|
||||||
// const location = useLocation();
|
|
||||||
// const isLogin = location.pathname === '/login';
|
|
||||||
//
|
|
||||||
// return (
|
|
||||||
// <div className={`${isLogin ? styles.pageLogin : styles.page}`}>
|
|
||||||
// {isLogin ? <LoginForm /> : <RegisterForm/>}
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const isLoginPage = location.pathname === '/login';
|
const isLoginPage = location.pathname === '/login';
|
||||||
const isRegisterPage = location.pathname === '/register';
|
const isRegisterPage = location.pathname === '/register';
|
||||||
|
|
@ -24,7 +15,7 @@ const AuthForm = () => {
|
||||||
} else if (isRegisterPage) {
|
} else if (isRegisterPage) {
|
||||||
content = <RegisterForm />;
|
content = <RegisterForm />;
|
||||||
} else {
|
} else {
|
||||||
content = <LoginForm />; // По умолчанию показываем LoginForm
|
content = <LoginForm />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue