File size: 4,067 Bytes
cb2d036
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247aad4
cb2d036
 
 
 
 
 
 
 
 
247aad4
 
 
 
cb2d036
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247aad4
 
 
 
cb2d036
 
 
 
 
 
 
 
 
 
 
 
247aad4
 
cb2d036
 
 
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import { useState, useCallback, useRef } from "react";
import GlassButton from "./GlassButton";
import GlassContainer from "./GlassContainer";
import { GLASS_EFFECTS } from "../constants";

interface ImageUploadProps {
  onImagesUploaded: (files: File[]) => void;
  isAnalyzing: boolean;
}

export default function ImageUpload({ onImagesUploaded, isAnalyzing }: ImageUploadProps) {
  const [dragActive, setDragActive] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const handleFiles = useCallback(
    (files: FileList | null) => {
      if (!files) return;
      
      const imageFiles = Array.from(files).filter(file =>
        file.type.startsWith("image/")
      );
      
      if (imageFiles.length > 0) {
        onImagesUploaded(imageFiles);
      }
    },
    [onImagesUploaded]
  );

  const handleDrag = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
  }, []);

  const handleDragIn = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    if (e.dataTransfer?.items && e.dataTransfer.items.length > 0) {
      setDragActive(true);
    }
  }, []);

  const handleDragOut = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setDragActive(false);
  }, []);

  const handleDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault();
      e.stopPropagation();
      setDragActive(false);
      
      if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {
        handleFiles(e.dataTransfer.files);
      }
    },
    [handleFiles]
  );

  const handleFileInputChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      handleFiles(e.target.files);
    },
    [handleFiles]
  );

  const handleClick = useCallback(() => {
    if (!isAnalyzing) {
      fileInputRef.current?.click();
    }
  }, [isAnalyzing]);

  return (
    <div className="absolute inset-0 flex items-center justify-center">
      <div
        className={`p-8 rounded-2xl border-2 border-dashed transition-all duration-300 cursor-pointer max-w-md mx-4 ${
          dragActive ? "border-blue-400 scale-105" : "border-white/30"
        } ${isAnalyzing ? "opacity-50 pointer-events-none" : "hover:border-white/50"}`}
        onDragEnter={handleDragIn}
        onDragLeave={handleDragOut}
        onDragOver={handleDrag}
        onDrop={handleDrop}
        onClick={handleClick}
      >
        <GlassContainer
          bgColor={dragActive ? GLASS_EFFECTS.COLORS.BUTTON_BG : GLASS_EFFECTS.COLORS.DEFAULT_BG}
          className="rounded-2xl"
        >
        <div className="text-center text-white">
          <div className="mb-4">
            <svg
              className="mx-auto w-16 h-16 text-white/60"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={1.5}
                d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
              />
            </svg>
          </div>
          
          <h3 className="text-xl font-semibold mb-2">Upload Images</h3>
          <p className="text-white/80 mb-4">
            Drag and drop images here, or click to select files
          </p>
          <p className="text-sm text-white/60 mb-6">
            Supports JPG, PNG, GIF, WebP formats. Multiple files allowed.
          </p>
          
          <GlassButton 
            onClick={handleClick}
            disabled={isAnalyzing}
          >
            {isAnalyzing ? "Analyzing..." : "Choose Files"}
          </GlassButton>
        </div>
        
        <input
          ref={fileInputRef}
          type="file"
          multiple
          accept="image/*"
          onChange={handleFileInputChange}
          className="hidden"
        />
        </GlassContainer>
      </div>
    </div>
  );
}