'use client' import { useState, useRef } from 'react' import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogTrigger, } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' import { uploadImageAction } from '@/lib/actions/upload' import { ImagePlus, X, UploadCloud, Loader2, CheckCircle2, AlertCircle } from 'lucide-react' interface ImageUploadModalProps { onUploadComplete: (urls: string[]) => void multiple?: boolean triggerText?: string folderName?: string } export function ImageUploadModal({ onUploadComplete, multiple = false, triggerText = "Resim Yükle", folderName = "starapart" }: ImageUploadModalProps) { const [open, setOpen] = useState(false) const [selectedFiles, setSelectedFiles] = useState([]) const [previews, setPreviews] = useState([]) const [isUploading, setIsUploading] = useState(false) const [progress, setProgress] = useState(0) // 0 to total files const [error, setError] = useState(null) const fileInputRef = useRef(null) const resetState = () => { setSelectedFiles([]) previews.forEach(p => URL.revokeObjectURL(p)) setPreviews([]) setIsUploading(false) setProgress(0) setError(null) } const handleOpenChange = (newOpen: boolean) => { if (isUploading) return // Prevent closing while uploading setOpen(newOpen) if (!newOpen) { resetState() } } const handleFileChange = (e: React.ChangeEvent) => { if (!e.target.files?.length) return const files = Array.from(e.target.files) const newFiles = multiple ? [...selectedFiles, ...files] : [files[0]] setSelectedFiles(newFiles) // Create preview URLs const newPreviews = newFiles.map(file => URL.createObjectURL(file)) if (!multiple) { previews.forEach(p => URL.revokeObjectURL(p)) // cleanup old previews setPreviews(newPreviews) } else { setPreviews([...previews, ...newPreviews]) } setError(null) // Reset file input so same file can be selected again if removed if (fileInputRef.current) { fileInputRef.current.value = '' } } const removeFile = (index: number) => { const newFiles = [...selectedFiles] newFiles.splice(index, 1) const newPreviews = [...previews] URL.revokeObjectURL(newPreviews[index]) newPreviews.splice(index, 1) setSelectedFiles(newFiles) setPreviews(newPreviews) } const handleUpload = async () => { if (!selectedFiles.length) return setIsUploading(true) setError(null) setProgress(0) const uploadedUrls: string[] = [] try { // Upload one by one to prevent timeout and body size limits for (let i = 0; i < selectedFiles.length; i++) { const file = selectedFiles[i] const fd = new FormData() fd.append('file', file) fd.append('folder', folderName) const res = await uploadImageAction(fd) if (res.success && res.url) { uploadedUrls.push(res.url) } else { throw new Error(res.error || `${file.name} yüklenemedi.`) } setProgress(i + 1) } onUploadComplete(uploadedUrls) setOpen(false) resetState() } catch (err: any) { setError(err.message || "Yükleme sırasında bir hata oluştu.") setIsUploading(false) } } return ( {triggerText} } /> Resim Yükle {multiple ? "Birden fazla resim seçip yükleyebilirsiniz." : "Odanın ana görselini seçin."}
{!isUploading && (
)} {error && (
{error}
)} {previews.length > 0 && (

Seçilen Resimler ({selectedFiles.length})

{previews.map((preview, idx) => (
preview {!isUploading && ( )} {isUploading && idx < progress && (
)} {isUploading && idx === progress && (
)}
))}
)} {isUploading && (
Yükleniyor... {progress} / {selectedFiles.length}
)}
) }