diff --git a/package.json b/package.json index 4333ba4..8f64cb4 100644 --- a/package.json +++ b/package.json @@ -122,4 +122,4 @@ "storybook": "^7.6.4", "webpack": "^5.89.0" } -} +} \ No newline at end of file diff --git a/src/components/Forms/AuthorizationForm/AuthorizationForm.module.scss b/src/components/Forms/AuthorizationForm/AuthorizationForm.module.scss index 231815a..38839b8 100644 --- a/src/components/Forms/AuthorizationForm/AuthorizationForm.module.scss +++ b/src/components/Forms/AuthorizationForm/AuthorizationForm.module.scss @@ -16,7 +16,7 @@ width: 100%; display: flex; flex-direction: column; - align-items: center; + align-items: start; } &__question { @include m.LinkS; @@ -28,3 +28,9 @@ margin-bottom: 32px; } } + +.error { + color: v.$error; + @include m.Description; + margin-top: 4px; +} diff --git a/src/components/Forms/AuthorizationForm/AuthorizationForm.tsx b/src/components/Forms/AuthorizationForm/AuthorizationForm.tsx index 4165dc2..bd2b452 100644 --- a/src/components/Forms/AuthorizationForm/AuthorizationForm.tsx +++ b/src/components/Forms/AuthorizationForm/AuthorizationForm.tsx @@ -4,27 +4,52 @@ import PasswordInput from 'ui-lib/Inputs/PasswordInput/PasswordInput'; import loginUserThunk from 'thunks/login-user-thunk'; import { NavLink } from 'react-router-dom'; import { UniversalButton } from 'ui-lib/Buttons'; +import { validateField } from 'utils/validateFields'; import { useDispatch } from '../../../services/hooks'; import styles from './AuthorizationForm.module.scss'; const AuthorizationForm = () => { type Values = Record; + type FormErrors = Record; const dispatch = useDispatch(); const [values, setValues] = useState({}); + const [errors, setErrors] = useState({ email: '', password: '' }); const onSubmitLogin = (event: SyntheticEvent) => { event.preventDefault(); - dispatch(loginUserThunk({ email: values.email, password: values.password })); + const newErrors: FormErrors = {}; + Object.entries(values).forEach(([name, value]) => { + const error = validateField(name, value); + if (error) { + newErrors[name] = error; + } + }); + + if (Object.keys(newErrors).length > 0) { + setErrors(newErrors); + } else { + dispatch(loginUserThunk({ email: values.email, password: values.password })); + } }; const handleChange = (event: React.ChangeEvent) => { const { target } = event; const { name, value } = target; - setValues({ ...values, [name]: value }); + const error = validateField(name, value); + setErrors((prevErrors) => ({ + ...prevErrors, + [name]: error, + })); + setValues((prevValues) => ({ + ...prevValues, + [name]: value, + })); }; return (
+ {errors.email &&
{errors.email}
} + {errors.password &&
{errors.password}
}
Забыли пароль? diff --git a/src/utils/useForm.ts b/src/utils/useForm.ts new file mode 100644 index 0000000..abf4633 --- /dev/null +++ b/src/utils/useForm.ts @@ -0,0 +1,64 @@ +import { useState, ChangeEvent, FormEvent } from 'react'; + +interface FormValues { + [key: string]: string; +} + +interface FormErrors { + [key: string]: string | null; +} + +interface UseFormProps { + initialValues: FormValues; + validationFunction: (name: string, value: string) => string | null; + onSubmit: (values: FormValues) => void; +} + +export const useForm = ({ + initialValues, + validationFunction, + onSubmit, +}: UseFormProps) => { + const [values, setValues] = useState(initialValues); + const [errors, setErrors] = useState({}); + + const handleChange = (event: ChangeEvent) => { + const { name, value } = event.target; + const error = validationFunction(name, value); + + setValues((prevValues) => ({ + ...prevValues, + [name]: value, + })); + + setErrors((prevErrors) => ({ + ...prevErrors, + [name]: error, + })); + }; + + const handleSubmit = (event: FormEvent) => { + event.preventDefault(); + const newErrors: FormErrors = {}; + + Object.entries(values).forEach(([name, value]) => { + const error = validationFunction(name, value); + if (error) { + newErrors[name] = error; + } + }); + + if (Object.keys(newErrors).length > 0) { + setErrors(newErrors); + } else { + onSubmit(values); + } + }; + + return { + values, + errors, + handleChange, + handleSubmit, + }; +}; diff --git a/src/utils/validateFields.ts b/src/utils/validateFields.ts new file mode 100644 index 0000000..13540c2 --- /dev/null +++ b/src/utils/validateFields.ts @@ -0,0 +1,18 @@ +export const validateField = (name: string, value: string): string => { + switch (name) { + case 'email': + if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)) { + return 'Email введен некорректно'; + } + break; + case 'password': + if ((value.length !== 0 && value.length < 6) || value.length > 10) { + return 'Минимум 6 и максимум 10 символов'; + } + break; + default: + return ''; + } + + return ''; +};