Spaces:
Sleeping
Sleeping
Download frontend/src/components/UploadPanel.jsx from haisyam/PlatDetect: direct link, hf CLI and curl.
- Browser
- Download file 2.91 kB
-
https://huggingface.co/spaces/haisyam/PlatDetect/resolve/main/frontend/src/components/UploadPanel.jsx
- Command line
-
hf download hf://spaces/haisyam/PlatDetect/frontend/src/components/UploadPanel.jsx
-
curl -L -o UploadPanel.jsx https://huggingface.co/spaces/haisyam/PlatDetect/resolve/main/frontend/src/components/UploadPanel.jsx
2.91 kB
| import { useRef } from "react"; | |
| import { Upload, X, ImagePlus } from "lucide-react"; | |
| import { isValidImageFile, isFileSizeValid, formatFileSize } from "../utils/formatters"; | |
| export default function UploadPanel({ onFileSelect, selectedFile, previewUrl, onReset }) { | |
| const fileInputRef = useRef(null); | |
| function handleFileChange(e) { | |
| const file = e.target.files?.[0]; | |
| if (!file) return; | |
| if (!isValidImageFile(file)) { | |
| alert("File harus berupa gambar JPG, PNG, JPEG, atau WEBP."); | |
| return; | |
| } | |
| if (!isFileSizeValid(file)) { | |
| alert("Ukuran gambar maksimal 10MB."); | |
| return; | |
| } | |
| onFileSelect(file); | |
| } | |
| function handleDrop(e) { | |
| e.preventDefault(); | |
| const file = e.dataTransfer.files?.[0]; | |
| if (!file) return; | |
| if (!isValidImageFile(file)) { | |
| alert("File harus berupa gambar JPG, PNG, JPEG, atau WEBP."); | |
| return; | |
| } | |
| if (!isFileSizeValid(file)) { | |
| alert("Ukuran gambar maksimal 10MB."); | |
| return; | |
| } | |
| onFileSelect(file); | |
| } | |
| function handleDragOver(e) { | |
| e.preventDefault(); | |
| } | |
| return ( | |
| <div className="space-y-4"> | |
| {!previewUrl ? ( | |
| <div | |
| onClick={() => fileInputRef.current?.click()} | |
| onDrop={handleDrop} | |
| onDragOver={handleDragOver} | |
| className="border-2 border-dashed border-slate-300 rounded-xl p-8 md:p-12 text-center cursor-pointer hover:border-blue-400 hover:bg-blue-50/50 transition-all duration-200 group" | |
| > | |
| <ImagePlus className="w-10 h-10 text-slate-400 mx-auto mb-3 group-hover:text-blue-500 transition-colors" /> | |
| <p className="text-sm font-medium text-slate-600 mb-1"> | |
| Klik atau seret gambar ke sini | |
| </p> | |
| <p className="text-xs text-slate-400"> | |
| JPG, JPEG, PNG, WEBP • Maks 10MB | |
| </p> | |
| </div> | |
| ) : ( | |
| <div className="relative"> | |
| <img | |
| src={previewUrl} | |
| alt="Preview" | |
| className="w-full rounded-xl border border-slate-200 object-contain max-h-72" | |
| /> | |
| <button | |
| onClick={onReset} | |
| className="absolute top-2 right-2 bg-red-500 hover:bg-red-600 text-white rounded-full p-1.5 shadow-md transition-colors cursor-pointer" | |
| > | |
| <X className="w-4 h-4" /> | |
| </button> | |
| {selectedFile && ( | |
| <div className="mt-2 flex items-center gap-2 text-xs text-slate-500"> | |
| <Upload className="w-3.5 h-3.5" /> | |
| <span className="truncate">{selectedFile.name}</span> | |
| <span className="text-slate-400">({formatFileSize(selectedFile.size)})</span> | |
| </div> | |
| )} | |
| </div> | |
| )} | |
| <input | |
| ref={fileInputRef} | |
| type="file" | |
| accept=".jpg,.jpeg,.png,.webp" | |
| onChange={handleFileChange} | |
| className="hidden" | |
| /> | |
| </div> | |
| ); | |
| } | |