'use client'; /* eslint-disable @typescript-eslint/no-unused-vars */ import React, { useState, useRef } from 'react'; import { Upload, X, Image as ImageIcon, AlertCircle } from 'lucide-react'; interface ImageUploadProps { value?: string; onChange: (url: string) => void; onRemove: () => void; maxSize?: number; // in MB acceptedTypes?: string[]; className?: string; } export default function ImageUpload({ value, onChange, onRemove, maxSize = 5, acceptedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'], className = '' }: ImageUploadProps) { const [isUploading, setIsUploading] = useState(false); const [error, setError] = useState(''); const [dragActive, setDragActive] = useState(false); const fileInputRef = useRef(null); const validateFile = (file: File): string | null => { // Проверка типа файла if (!acceptedTypes.includes(file.type)) { return `Неподдерживаемый тип файла. Разрешены: ${acceptedTypes.join(', ')}`; } // Проверка размера файла if (file.size > maxSize * 1024 * 1024) { return `Файл слишком большой. Максимальный размер: ${maxSize} MB`; } return null; }; const handleFileUpload = async (file: File) => { const validationError = validateFile(file); if (validationError) { setError(validationError); return; } setIsUploading(true); setError(''); try { const formData = new FormData(); formData.append('file', file); formData.append('folder', 'images'); // Если есть старое изображение, передаем его URL для удаления if (value && value.startsWith('http')) { formData.append('oldUrl', value); } const response = await fetch('/api/upload', { method: 'POST', body: formData, }); const result = await response.json(); if (!response.ok) { throw new Error(result.error || 'Ошибка при загрузке файла'); } onChange(result.data.publicUrl); setIsUploading(false); } catch (error) { setError(error instanceof Error ? error.message : 'Ошибка при загрузке файла'); setIsUploading(false); } }; const handleInputChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { handleFileUpload(file); } }; const handleDrop = (e: React.DragEvent) => { e.preventDefault(); setDragActive(false); const file = e.dataTransfer.files?.[0]; if (file) { handleFileUpload(file); } }; const handleDragOver = (e: React.DragEvent) => { e.preventDefault(); setDragActive(true); }; const handleDragLeave = (e: React.DragEvent) => { e.preventDefault(); setDragActive(false); }; const handleRemove = async () => { try { // Если файл находится в S3, удаляем его оттуда if (value && value.startsWith('http')) { await fetch(`/api/upload?url=${encodeURIComponent(value)}`, { method: 'DELETE', }); } } catch (error) { console.error('Ошибка при удалении файла:', error); // Не показываем ошибку пользователю, так как файл может быть удален из UI } onRemove(); setError(''); if (fileInputRef.current) { fileInputRef.current.value = ''; } }; const openFileDialog = () => { fileInputRef.current?.click(); }; return (
{value ? ( // Предварительный просмотр изображения
Preview {/* Overlay с действиями */}
) : ( // Область загрузки
{isUploading ? (

Загрузка...

) : (
Нажмите для выбора или перетащите файл сюда

PNG, JPG, GIF, WEBP до {maxSize} MB

)}
)} {/* Скрытый input для выбора файла */} {/* Сообщение об ошибке */} {error && (
{error}
)} {/* Информация о файле */} {value && !error && (

Изображение загружено успешно

)}
); }