import React, { ChangeEvent, useCallback, useState } from 'react'; import Modal from '@/components/ui/Modal'; import Button from '@/components/ui/Button'; import api from '@/lib/api'; interface Props { /** Управляет открытием/закрытием модального окна */ isOpen: boolean; /** Колбэк, вызываемый, когда пользователь закрыл окно без сохранения */ onClose: () => void; /** Колбэк, срабатывающий после успешной загрузки файла */ onSuccess: (uploaded: UploadedImage) => void; } /** * Тип данных, которые реально уходят на бэкенд. * Поля, которые не требуются при самой первой загрузке, * объявлены с ?. Компилятор теперь не требует заполнять их * каждый раз. */ export interface ImageBody { file: File; /** Если файл уже загружен, бэкенд может вернуть готовый URL */ url?: string; title_ru?: string; title_en?: string; description_ru?: string; description_en?: string; } /** Ответ от сервера после успешной загрузки */ export interface UploadedImage { id: string; url: string; title_ru?: string; title_en?: string; description_ru?: string; description_en?: string; } const ImageUploaderModal: React.FC = ({ isOpen, onClose, onSuccess }) => { const [file, setFile] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const onFileChange = useCallback((e: ChangeEvent) => { setError(null); const chosen = e.target.files?.[0]; if (chosen) { setFile(chosen); } }, []); const resetState = () => { setFile(null); setError(null); setLoading(false); }; const handleClose = () => { if (!loading) { resetState(); onClose(); } }; const upload = async () => { if (!file) { setError('Выберите изображение перед загрузкой.'); return; } setLoading(true); try { const body: ImageBody = { file }; // ничего лишнего не добавляем // Формируем FormData, чтобы отправить файл «как есть» const form = new FormData(); form.append('file', body.file); // Если вам нужно сразу отправлять title/description, // их можно добавить в form.append(...) при наличии const { data } = await api.post('/images', form, { headers: { 'Content-Type': 'multipart/form-data' } }); onSuccess(data); handleClose(); } catch (err) { console.error(err); setError('Не удалось загрузить файл. Попробуйте ещё раз.'); } finally { setLoading(false); } }; return (
{error &&

{error}

}
); }; export default ImageUploaderModal;