| import React, { useRef } from 'react'; |
| import UploadIcon from './icons/UploadIcon'; |
|
|
| interface ImageUploaderProps { |
| onImageUpload: (files: File[]) => void; |
| isProcessing: boolean; |
| } |
|
|
| const ImageUploader: React.FC<ImageUploaderProps> = ({ onImageUpload, isProcessing }) => { |
| const fileInputRef = useRef<HTMLInputElement>(null); |
|
|
| const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => { |
| if (event.target.files) { |
| const files = Array.from(event.target.files); |
| if (files.length > 0) { |
| onImageUpload(files); |
| } |
| } |
| }; |
|
|
| const handleClick = () => { |
| fileInputRef.current?.click(); |
| }; |
|
|
| const handleDrop = (event: React.DragEvent<HTMLLabelElement>) => { |
| event.preventDefault(); |
| event.stopPropagation(); |
| if (isProcessing) return; |
| if (event.dataTransfer.files) { |
| const files = Array.from(event.dataTransfer.files); |
| if (files.length > 0) { |
| onImageUpload(files); |
| } |
| } |
| }; |
|
|
| const handleDragOver = (event: React.DragEvent<HTMLLabelElement>) => { |
| event.preventDefault(); |
| event.stopPropagation(); |
| }; |
|
|
| return ( |
| <div className="w-full"> |
| <label |
| onDrop={handleDrop} |
| onDragOver={handleDragOver} |
| className={`w-full flex flex-col items-center justify-center p-8 border-4 border-dashed rounded-2xl transition-colors duration-300 ${isProcessing ? 'border-gray-600 cursor-not-allowed' : 'border-gray-500 hover:border-blue-500 hover:bg-gray-800 cursor-pointer'}`} |
| > |
| <UploadIcon className="w-16 h-16 mb-4 text-gray-500" /> |
| <span className="text-xl font-semibold text-gray-300">Drag & Drop or Click to Upload</span> |
| <span className="mt-1 text-gray-400">Upload up to 10 images (PNG, JPG, WEBP)</span> |
| <input |
| ref={fileInputRef} |
| type="file" |
| accept="image/png, image/jpeg, image/webp" |
| className="hidden" |
| onChange={handleFileChange} |
| onClick={(e) => { (e.target as HTMLInputElement).value = '' }} // Allow re-uploading the same file |
| disabled={isProcessing} |
| multiple |
| /> |
| </label> |
| <button |
| onClick={handleClick} |
| disabled={isProcessing} |
| className="w-full mt-4 py-3 px-4 bg-gray-700 rounded-lg font-semibold hover:bg-gray-600 transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed" |
| > |
| Or Select File(s) |
| </button> |
| </div> |
| ); |
| }; |
|
|
| export default ImageUploader; |