Spaces:
Build error
Build error
| import { useState, useCallback } from 'react' | |
| export default function ImageUpload({ onImageUpload, uploadedImage, onRemove }) { | |
| const [isDragActive, setIsDragActive] = useState(false) | |
| const onDrop = useCallback((e) => { | |
| e.preventDefault() | |
| setIsDragActive(false) | |
| const file = e.dataTransfer.files[0] | |
| if (file) { | |
| onImageUpload(file) | |
| } | |
| }, [onImageUpload]) | |
| const onDragOver = useCallback((e) => { | |
| e.preventDefault() | |
| setIsDragActive(true) | |
| }, []) | |
| const onDragLeave = useCallback(() => { | |
| setIsDragActive(false) | |
| }, []) | |
| const handleFileChange = (e) => { | |
| const file = e.target.files[0] | |
| if (file) { | |
| onImageUpload(file) | |
| } | |
| } | |
| return ( | |
| <div className="relative"> | |
| {!uploadedImage ? ( | |
| <div | |
| onDrop={onDrop} | |
| onDragOver={onDragOver} | |
| onDragLeave={onDragLeave} | |
| className={`border-2 border-dashed rounded-lg p-2 transition-colors ${ | |
| isDragActive | |
| ? 'border-blue-500 bg-blue-50' | |
| : 'border-gray-300 bg-gray-50 hover:bg-gray-100' | |
| }`} | |
| > | |
| <input | |
| type="file" | |
| accept="image/*" | |
| onChange={handleFileChange} | |
| className="hidden" | |
| id="image-upload" | |
| /> | |
| <label | |
| htmlFor="image-upload" | |
| className="cursor-pointer flex items-center justify-center text-sm text-gray-600" | |
| > | |
| <span className="mr-2">π·</span> | |
| {isDragActive ? 'Drop image here' : 'Add image'} | |
| </label> | |
| </div> | |
| ) : ( | |
| <div className="relative"> | |
| <img | |
| src={uploadedImage.preview} | |
| alt="Preview" | |
| className="w-20 h-20 object-cover rounded-lg border border-gray-300" | |
| /> | |
| <button | |
| onClick={onRemove} | |
| 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" | |
| aria-label="Remove image" | |
| > | |
| Γ | |
| </button> | |
| </div> | |
| )} | |
| </div> | |
| ) | |
| } |