akhaliq HF Staff commited on
Commit
d4f52d9
·
verified ·
1 Parent(s): d870750

Upload components/ImageUpload.jsx with huggingface_hub

Browse files
Files changed (1) hide show
  1. components/ImageUpload.jsx +78 -0
components/ImageUpload.jsx ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState, useCallback } from 'react'
2
+
3
+ export default function ImageUpload({ onImageUpload, uploadedImage, onRemove }) {
4
+ const [isDragActive, setIsDragActive] = useState(false)
5
+
6
+ const onDrop = useCallback((e) => {
7
+ e.preventDefault()
8
+ setIsDragActive(false)
9
+
10
+ const file = e.dataTransfer.files[0]
11
+ if (file) {
12
+ onImageUpload(file)
13
+ }
14
+ }, [onImageUpload])
15
+
16
+ const onDragOver = useCallback((e) => {
17
+ e.preventDefault()
18
+ setIsDragActive(true)
19
+ }, [])
20
+
21
+ const onDragLeave = useCallback(() => {
22
+ setIsDragActive(false)
23
+ }, [])
24
+
25
+ const handleFileChange = (e) => {
26
+ const file = e.target.files[0]
27
+ if (file) {
28
+ onImageUpload(file)
29
+ }
30
+ }
31
+
32
+ return (
33
+ <div className="relative">
34
+ {!uploadedImage ? (
35
+ <div
36
+ onDrop={onDrop}
37
+ onDragOver={onDragOver}
38
+ onDragLeave={onDragLeave}
39
+ className={`border-2 border-dashed rounded-lg p-2 transition-colors ${
40
+ isDragActive
41
+ ? 'border-blue-500 bg-blue-50'
42
+ : 'border-gray-300 bg-gray-50 hover:bg-gray-100'
43
+ }`}
44
+ >
45
+ <input
46
+ type="file"
47
+ accept="image/*"
48
+ onChange={handleFileChange}
49
+ className="hidden"
50
+ id="image-upload"
51
+ />
52
+ <label
53
+ htmlFor="image-upload"
54
+ className="cursor-pointer flex items-center justify-center text-sm text-gray-600"
55
+ >
56
+ <span className="mr-2">📷</span>
57
+ {isDragActive ? 'Drop image here' : 'Add image'}
58
+ </label>
59
+ </div>
60
+ ) : (
61
+ <div className="relative">
62
+ <img
63
+ src={uploadedImage.preview}
64
+ alt="Preview"
65
+ className="w-20 h-20 object-cover rounded-lg border border-gray-300"
66
+ />
67
+ <button
68
+ onClick={onRemove}
69
+ className="absolute -top-2 -right-2 bg-red-500 text-white rounded-full w-6 h-6 flex items-center justify-center hover:bg-red-600 transition-colors"
70
+ aria-label="Remove image"
71
+ >
72
+ ×
73
+ </button>
74
+ </div>
75
+ )}
76
+ </div>
77
+ )
78
+ }