/
dmitriysturov
/
workspaces_platform
Обзор
Документация
Войти
/
dmitriysturov
/
workspaces_platform
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
frontend/src/components/ProjectFormModal.tsx
89 строк
3 KB
dmitriysturov
vkr
04 июн 2026, 22:24
04 июн 2026, 22:24
971dfdc
Код
Авторство
О чём код?
import { useState, type FormEvent } from 'react' import type { Project, ProjectCreateRequest, ProjectUpdateRequest } from '../types' import { friendlyError } from '../utils/format' import { Button } from './ui/Button' import { Modal } from './ui/Modal' type ProjectFormModalProps = { mode: 'create' | 'edit' project?: Project isSubmitting: boolean onSubmit: (data: Omit<ProjectCreateRequest, 'workspaceId'> | ProjectUpdateRequest) => Promise<void> onClose: () => void } function validate(name: string, description: string) { const trimmedName = name.trim() const trimmedDescription = description.trim() if (!trimmedName) { return 'Введите название проекта.' } if (trimmedName.length < 2 || trimmedName.length > 100) { return 'Название должно быть от 2 до 100 символов.' } if (trimmedDescription.length > 1000) { return 'Описание должно быть не длиннее 1000 символов.' } return null } export function ProjectFormModal({ mode, project, isSubmitting, onSubmit, onClose }: ProjectFormModalProps) { const [name, setName] = useState(project?.name ?? '') const [description, setDescription] = useState(project?.description ?? '') const [error, setError] = useState<string | null>(null) async function handleSubmit(event: FormEvent<HTMLFormElement>) { event.preventDefault() const validationError = validate(name, description) if (validationError) { setError(validationError) return } try { setError(null) await onSubmit({ name: name.trim(), description: description.trim() || null, }) } catch (err) { setError(friendlyError(err, 'Не удалось сохранить проект.')) } } return ( <Modal title={mode === 'create' ? 'Создать проект' : 'Изменить проект'} description="Проект будет создан внутри текущего рабочего пространства." onClose={onClose} > <form className="form modal-form" onSubmit={handleSubmit}> {error && <div className="form-error">{error}</div>} <label> Название <input value={name} onChange={(event) => setName(event.target.value)} autoFocus maxLength={100} /> </label> <label> Описание <textarea value={description} onChange={(event) => setDescription(event.target.value)} maxLength={1000} /> </label> <div className="modal-actions"> <Button type="button" variant="secondary" onClick={onClose}> Отмена </Button> <Button type="submit" isLoading={isSubmitting}> {mode === 'create' ? 'Создать' : 'Сохранить'} </Button> </div> </form> </Modal> ) }