'use client'; import React, { useState, useRef } from 'react'; import { Upload, Loader2, Images } from 'lucide-react'; import { toast } from 'sonner'; import { getAccessToken } from '@/services/api/client'; import { API_BASE_URL } from '@/services/api/config'; interface BulkImageUploadProps { entityType: string; onUploadBatch: (urls: string[]) => void; className?: string; } export const BulkImageUpload: React.FC = ({ entityType, onUploadBatch, className = '', }) => { const [uploading, setUploading] = useState(false); const [isDragOver, setIsDragOver] = useState(false); const fileInputRef = useRef(null); const handleFiles = async (fileList: FileList | File[]) => { const files = Array.from(fileList); if (files.length === 0) return; const allowedExtensions = ['jpg', 'jpeg', 'png', 'webp']; const validFiles = files.filter((f) => { const ext = f.name.split('.').pop()?.toLowerCase() || ''; return (f.type && f.type.startsWith('image/')) || allowedExtensions.includes(ext); }); if (validFiles.length === 0) { toast.error('Only JPG, JPEG, PNG, or WebP images are supported.'); return; } setUploading(true); const token = getAccessToken(); const headers: Record = {}; if (token) { headers['Authorization'] = `Bearer ${token}`; } try { const uploads = await Promise.all( validFiles.map(async (file) => { const formData = new FormData(); formData.append('file', file); formData.append('entity_type', entityType); formData.append('entity_id', 'temp_' + Math.random().toString(36).substring(2, 11)); const res = await fetch(`${API_BASE_URL}/api/v1/files/upload`, { method: 'POST', headers, body: formData, }); if (res.ok) { const data = await res.json(); const rawPath = data?.webp_path || data?.storage_path || data?.raw_path || data?.url || ''; if (rawPath) { return rawPath.startsWith('/') ? rawPath : `/${rawPath}`; } } return null; }) ); const uploadedUrls = uploads.filter((u): u is string => Boolean(u)); if (uploadedUrls.length > 0) { toast.success(`Successfully uploaded ${uploadedUrls.length} image(s)!`); onUploadBatch(uploadedUrls); } else { toast.error('Failed to upload image(s).'); } } catch (err) { console.error('Bulk image upload error:', err); toast.error('Bulk image upload failed.'); } finally { setUploading(false); } }; return (
{ e.preventDefault(); setIsDragOver(true); }} onDragLeave={() => setIsDragOver(false)} onDrop={(e) => { e.preventDefault(); setIsDragOver(false); if (e.dataTransfer.files) handleFiles(e.dataTransfer.files); }} onClick={() => fileInputRef.current?.click()} className={`relative border-2 border-dashed rounded-xl p-4 transition-all cursor-pointer flex items-center justify-center text-center select-none ${ isDragOver ? 'border-red-500 bg-red-500/10' : 'border-slate-700 hover:border-slate-600 bg-slate-800/40 hover:bg-slate-800/80' } ${className}`} > e.target.files && handleFiles(e.target.files)} className="hidden" />
{uploading ? ( ) : (
)}

{uploading ? 'Uploading multiple images...' : 'Bulk Drag & Drop Images'}

Drag & drop multiple files or click to multi-select PNG, JPG, WEBP

); };