Spaces:
Runtime error
Runtime error
'use client'; | |
import React, { useRef, useState } from "react"; | |
import { FiTrash2 } from "react-icons/fi"; // Use trash bin icon | |
interface ImageInputProps { | |
image: File | null; | |
setImage: (f: File | null) => void; | |
classify: (input: string | Blob) => void; | |
ready: boolean | null; | |
} | |
export const ImageInput = ({ image, setImage, classify, ready }: ImageInputProps) => { | |
const inputRef = useRef<HTMLInputElement>(null); | |
const [dragOver, setDragOver] = useState(false); // NEW: Track drag-over state | |
const handleFile = (file: File) => { | |
setImage(file); | |
const reader = new FileReader(); | |
reader.onload = (ev) => { | |
classify(ev.target?.result as string); | |
}; | |
reader.readAsDataURL(file); | |
}; | |
// NEW: Handle delete image | |
const handleDelete = (e: React.MouseEvent) => { | |
e.stopPropagation(); | |
setImage(null); | |
}; | |
return ( | |
<div | |
className={`flex flex-col items-center justify-center border-2 border-dashed rounded-lg p-8 min-h-[220px] transition-all duration-300 cursor-pointer bg-gray-50 relative | |
${ready === false ? 'opacity-50 pointer-events-none' : ''} | |
${dragOver ? 'border-blue-600 bg-blue-50 scale-105 shadow-lg' : 'hover:border-blue-400'}`} | |
tabIndex={0} | |
onClick={() => inputRef.current?.click()} | |
onDrop={e => { | |
e.preventDefault(); | |
setDragOver(false); | |
if (e.dataTransfer.files.length > 0 && e.dataTransfer.files[0].type.startsWith('image/')) { | |
handleFile(e.dataTransfer.files[0]); | |
} | |
}} | |
onDragOver={e => { | |
e.preventDefault(); | |
setDragOver(true); | |
}} | |
onDragLeave={() => setDragOver(false)} | |
> | |
{image ? ( | |
<div className="relative w-full flex flex-col items-center"> | |
{/* Delete button at top-right of image container */} | |
<button | |
onClick={handleDelete} | |
className="absolute -top-3 -right-3 z-10 bg-white border border-gray-200 hover:bg-red-500 hover:text-white text-gray-700 rounded-full p-1 shadow transition-colors w-7 h-7 flex items-center justify-center" | |
aria-label="Remove image" | |
tabIndex={0} | |
type="button" | |
> | |
<FiTrash2 size={16} className="text-red-500 overflow-visible" /> | |
</button> | |
<img | |
src={URL.createObjectURL(image)} | |
alt="Uploaded" | |
className="mx-auto max-h-48 rounded-lg shadow-md mb-4 animate-fade-in" | |
/> | |
</div> | |
) : ( | |
<span className={`text-lg ${dragOver ? 'text-blue-600 animate-pulse' : 'text-gray-400 animate-pulse'}`}> | |
Drop image here, or click to select | |
</span> | |
)} | |
<input | |
ref={inputRef} | |
type="file" | |
accept="image/*" | |
style={{ display: 'none' }} | |
onChange={e => { | |
if (e.target.files && e.target.files[0]) { | |
handleFile(e.target.files[0]); | |
} | |
}} | |
/> | |
</div> | |
); | |
}; |