File size: 3,055 Bytes
3baa9da
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
'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>
  );
};