"use client"; import { useCallback, useRef, useState } from "react"; import { Upload, ImageIcon, Link2, Check, Loader2, X, Copy, } from "lucide-react"; interface UploadedPhoto { id: string; url: string; originalName: string; } export function UploadZone() { const [isDragging, setIsDragging] = useState(false); const [isUploading, setIsUploading] = useState(false); const [uploaded, setUploaded] = useState(null); const [error, setError] = useState(null); const [copied, setCopied] = useState(false); const inputRef = useRef(null); const uploadFile = useCallback(async (file: File) => { if (!file.type.startsWith("image/")) { setError("Можно загружать только изображения"); return; } if (file.size > 10 * 1024 * 1024) { setError("Максимальный размер файла — 10 МБ"); return; } setError(null); setIsUploading(true); setUploaded(null); const formData = new FormData(); formData.append("file", file); try { const res = await fetch("/api/upload", { method: "POST", body: formData, }); if (!res.ok) { const data = await res.json(); throw new Error(data.error || "Ошибка загрузки"); } const photo = await res.json(); setUploaded(photo); window.dispatchEvent(new CustomEvent("photo-uploaded", { detail: photo })); } catch (err) { setError(err instanceof Error ? err.message : "Ошибка загрузки"); } finally { setIsUploading(false); } }, []); const handleDrop = useCallback( (e: React.DragEvent) => { e.preventDefault(); setIsDragging(false); const file = e.dataTransfer.files[0]; if (file) uploadFile(file); }, [uploadFile] ); const handleCopy = async () => { if (!uploaded) return; const fullUrl = `${window.location.origin}${uploaded.url}`; await navigator.clipboard.writeText(fullUrl); setCopied(true); setTimeout(() => setCopied(false), 2000); }; const reset = () => { setUploaded(null); setError(null); setCopied(false); }; return (
{ e.preventDefault(); setIsDragging(true); }} onDragLeave={() => setIsDragging(false)} onDrop={handleDrop} onClick={() => !isUploading && !uploaded && inputRef.current?.click()} className={`group relative cursor-pointer rounded-3xl border-2 border-dashed p-12 text-center transition-all duration-300 ${ isDragging ? "border-indigo-400 bg-indigo-500/10 glow" : "border-border hover:border-indigo-500/50 hover:bg-surface/50" } ${uploaded ? "cursor-default border-emerald-500/30 bg-emerald-500/5" : ""}`} > { const file = e.target.files?.[0]; if (file) uploadFile(file); e.target.value = ""; }} /> {isUploading ? (

Загрузка...

) : uploaded ? (

Фото загружено!

{uploaded.originalName}

) : (

Перетащите фото сюда

или нажмите для выбора файла

JPG, PNG, GIF, WebP до 10 МБ
)}
{error && (
{error}
)}
); }