diff --git a/src/components/upload/EntityMultiImageUploader.tsx b/src/components/upload/EntityMultiImageUploader.tsx index 2cab51a1..faf728d0 100644 --- a/src/components/upload/EntityMultiImageUploader.tsx +++ b/src/components/upload/EntityMultiImageUploader.tsx @@ -1,6 +1,6 @@ import React, { useState, useRef } from 'react'; import { Button } from '@/components/ui/button'; -import { Upload, Star, CreditCard, Trash2 } from 'lucide-react'; +import { Upload, Star, CreditCard, Trash2, ImagePlus } from 'lucide-react'; import { Badge } from '@/components/ui/badge'; import { ContextMenu, @@ -9,6 +9,7 @@ import { ContextMenuSeparator, ContextMenuTrigger, } from '@/components/ui/context-menu'; +import { DragDropZone } from './DragDropZone'; export interface UploadedImage { url: string; @@ -39,12 +40,8 @@ export function EntityMultiImageUploader({ entityType = 'entity' }: EntityMultiImageUploaderProps) { const maxImages = mode === 'create' ? 5 : 3; - const fileInputRef = useRef(null); - - const handleFileSelect = (e: React.ChangeEvent) => { - const files = e.target.files; - if (!files || files.length === 0) return; + const handleFilesAdded = (files: File[]) => { const currentCount = value.uploaded.length; const availableSlots = maxImages - currentCount; @@ -52,7 +49,7 @@ export function EntityMultiImageUploader({ return; } - const filesToAdd = Array.from(files).slice(0, availableSlots); + const filesToAdd = files.slice(0, availableSlots); const newImages: UploadedImage[] = filesToAdd.map(file => ({ url: URL.createObjectURL(file), file, @@ -81,11 +78,6 @@ export function EntityMultiImageUploader({ } onChange(updatedValue); - - // Reset input - if (fileInputRef.current) { - fileInputRef.current.value = ''; - } }; const handleAssignRole = (index: number, role: 'banner' | 'card') => { @@ -217,49 +209,65 @@ export function EntityMultiImageUploader({ return parts.join(' • '); }; + // Empty state: show large drag & drop zone + if (value.uploaded.length === 0) { + return ( +
+ +
+

• Right-click images to set as banner or card

+

• Images will be uploaded when you submit the form

+
+
+ ); + } + + // With images: show grid + compact upload area return (
- + {/* Image Grid */} +
+ {value.uploaded.map((image, index) => renderImageCard(image, index))} +
- - - {value.uploaded.length > 0 && ( -
-
- {value.uploaded.map((image, index) => renderImageCard(image, index))} + {/* Compact Upload Area */} + {value.uploaded.length < maxImages && ( + +
+ +

Add More Images

+

+ Drag & drop or click to browse ({value.uploaded.length}/{maxImages}) +

- -
-

{getHelperText()}

-
-

- Banner: Main header image for the {entityType} detail page - {value.banner_assignment !== null && value.banner_assignment !== undefined && ` (Image ${value.banner_assignment + 1})`} -

-

- Card: Thumbnail in {entityType} listings and search results - {value.card_assignment !== null && value.card_assignment !== undefined && ` (Image ${value.card_assignment + 1})`} -

-
-
-
+ )} + + {/* Helper Text */} +
+

{getHelperText()}

+
+

+ Banner: Main header image for the {entityType} detail page + {value.banner_assignment !== null && value.banner_assignment !== undefined && ` (Image ${value.banner_assignment + 1})`} +

+

+ Card: Thumbnail in {entityType} listings and search results + {value.card_assignment !== null && value.card_assignment !== undefined && ` (Image ${value.card_assignment + 1})`} +

+
+
); }