/
DevDenzo
/
ERP
Обзор
Документация
Войти
/
DevDenzo
/
ERP
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/components/forms/SignUpForm/SignUpForm.jsx
271 строка
12 KB
Denis Sklyarskij
Инициализирован репозиторий
14 янв 2026, 23:32
14 янв 2026, 23:32
1df3d47
Код
Авторство
О чём код?
import React, { useState, useEffect, useContext, memo } from 'react'; import classNames from 'classnames'; import PropTypes from 'prop-types'; /** * * Отрисовывает форму с полями для ввода логина, email, пароля и его подтверждения, * а также кнопкой отправки. Поддерживает динамическую смену тем оформления * через контекст ThemesContext. */ // Импорт контекста тем для динамической смены стилей import { ThemesContext } from '../../../contexts/ThemesContext.js'; import { X } from 'react-bootstrap-icons'; // Импорт стилей формы регистрации (LESS) import './styles/_signup-form.less'; /** * Компонент формы регистрации (SignUp) с поддержкой тематического оформления * @param {Object} props - Пропсы компонента * @param {Function} props.setIsFormVisible - Функция для управления видимостью формы * (передаётся из родительского компонента, вызов с null скрывает форму) */ const SignUpForm = memo(({ setIsFormVisible }) => { // Получаем текущие настройки тем из глобального контекста const { loadedThemes } = useContext(ThemesContext); /* Создаем локальное состояние для управления полем ввода */ const [formData, setFormData] = useState({ login: '', email: '', password: '', repeatPassword: '' }); /* Локальное состояние отображения ошибки */ const [isError, setIsError] = useState({ login: false, email: false, password: false, repeatPassword: false }); /** * Эффект для автоматической валидации полей формы при их изменении. * Проверяет, какие поля остались пустыми (после обрезки пробелов), * и обновляет состояние ошибок. * * @dependency formData.email - отслеживаемое поле email * @dependency formData.login - отслеживаемое поле логина * @dependency formData.password - отслеживаемое поле пароля * @dependency formData.repeatPassword - отслеживаемое поле подтверждения пароля */ useEffect(() => { // 1. Формируем объект с результатами проверки каждого поля на пустоту const emptyFieldsError = { login: formData.login.trim() === '', email: formData.email.trim() === '', password: formData.password.trim() === '', repeatPassword: formData.repeatPassword.trim() === '' }; // 2. Обновляем состояние ошибок, передавая результаты валидации // Это активирует отображение сообщений об ошибках в интерфейсе setIsError(emptyFieldsError); }, [ formData.email, formData.login, formData.password, formData.repeatPassword ]); // Обработчик клика по кнопке закрытия формы // Передаёт null в setIsFormVisible, инициируя скрытие формы в родительском компоненте const handleHideSignUpForm = () => { setIsFormVisible(null); }; /* Обработчик изменения поля */ const handleChange = (e) => { /* Получаем текущее содержимое поля */ const { name, value } = e.target; /* Меняем содержимое поля */ setFormData(prev => ({ ...prev, [name]: value })); /* Обновляем ошибку конкретного поля ввода */ setIsError(prev => ({ ...prev, [name]: value.trim() === '' })); }; /** * Обработчик отправки формы регистрации * Предотвращает стандартную отправку формы и выполняет валидацию полей. * * @param {Event} e - Событие отправки формы (SubmitEvent) */ const handleSubmit = (e) => { // 1. Отменяем стандартное поведение браузера (отправку формы на сервер) e.preventDefault(); // 2. Создаём объект с результатами валидации каждого поля // Проверяем, что поля не пустые (с учётом обрезки пробелов) const signUpErrors = { login: formData.login.trim() === '', email: formData.email.trim() === '', password: formData.password.trim() === '', repeatPassword: formData.repeatPassword.trim() === '' }; // 3. Обновляем состояние компонента, сохраняя результаты валидации // Это позволит отобразить сообщения об ошибках рядом с соответствующими полями setIsError(signUpErrors); }; return ( <form className={classNames('signup-form', { 'signup-form--white': loadedThemes['white'], // Класс для светлой темы 'signup-form--gray': loadedThemes['gray'], // Класс для серой темы 'signup-form--dark': loadedThemes['dark'], // Класс для тёмной темы })} onSubmit={handleSubmit} > {/* Кнопка закрытия формы (крестик) */} <div className={classNames('signup-form__close', { 'signup-form__close--white': loadedThemes['white'], // Белая тема кнопки закрытия 'signup-form__close--gray': loadedThemes['gray'], // Серый тема кнопки закрытия 'signup-form__close--dark': loadedThemes['dark'], // Темная тема кнопки закрытия })} onClick={handleHideSignUpForm} // Обработчик клика для скрытия формы > <X size={22} /> </div> {/* Поле ввода логина */} <div className="mb-3 signup-form__wrapper-input"> <input className={classNames('form-control', 'signup-form__input', { 'signup-form__input--gray': loadedThemes['gray'], // Серый стиль поля ввода 'signup-form__input--dark': loadedThemes['dark'], // Тёмный стиль поля ввода })} type="text" placeholder="Логин" value={formData.login} onChange={handleChange} name="login" /> {/* Рендер сообщения об ошибке */} {isError.login && ( <div className='signup-form__error'> Поле логин не должно быть пустым </div> )} </div> {/* Поле ввода email */} <div className="mb-3 signup-form__wrapper-input"> <input className={classNames('form-control signup-form__input', { 'signup-form__input--gray': loadedThemes['gray'], 'signup-form__input--dark': loadedThemes['dark'] })} type="text" placeholder="Эл. почта" value={formData.email} onChange={handleChange} name="email" /> {isError.email && ( <div className='signup-form__error'> Поле email не может быть пустым </div> )} </div> {/* Поле ввода пароля */} <div className="mb-3 signup-form__wrapper-input"> <input className={classNames('form-control signup-form__input', { 'signup-form__input--gray': loadedThemes['gray'], 'signup-form__input--dark': loadedThemes['dark'] })} type="text" placeholder="Пароль" value={formData.password} onChange={handleChange} name="password" /> {isError.password && ( <div className='signup-form__error'> Поле пароль не может быть пустым </div> )} </div> {/* Поле подтверждения пароля */} <div className="mb-3 signup-form__wrapper-input"> <input className={classNames('form-control signup-form__input', { 'signup-form__input--gray': loadedThemes['gray'], 'signup-form__input--dark': loadedThemes['dark'] })} type="text" placeholder="Повторите пароль" value={formData.repeatPassword} onChange={handleChange} name="repeatPassword" /> {isError.repeatPassword && ( <div className='signup-form__error'> Поле повторить пароль не может быть пустым </div> )} </div> {/* Кнопка отправки формы регистрации */} <div className="mb-3 signup-form__wrapper-input"> <button type="submit" className={classNames( 'btn', 'btn-light', 'signup-form__submit', { 'signup-form__submit--disabled': isError.login || isError.email || isError.password || isError.repeatPassword, 'signup-form__submit--white': loadedThemes['white'], // Белая тема кнопки отправки 'signup-form__submit--gray': loadedThemes['gray'], // Серая тема кнопки отправки 'signup-form__submit--dark': loadedThemes['dark'], // Темная тема кнопки отправки } )} > Зарегистрироваться </button> </div> </form> ); }); // Типизация пропсов компонента // Обеспечивает проверку типов на этапе разработки и улучшает читаемость кода SignUpForm.propTypes = { /** * Функция для управления видимостью формы регистрации * Обязательный пропс, должен быть функцией */ setIsFormVisible: PropTypes.func.isRequired, }; // Экспорт компонента по умолчанию для использования в других модулях export default SignUpForm;