import { useRef, useState } from "react"; import { apiUpload } from "../lib/api"; interface ImageUploadProps { value: string | null; onChange: (filename: string | null) => void; } const MAX_SIZE_BYTES = 5 * 1024 * 1024; // 5MB const ACCEPTED_TYPES = ["image/jpeg", "image/png", "image/webp"]; export function ImageUpload({ value, onChange }: ImageUploadProps) { const [uploading, setUploading] = useState(false); const [error, setError] = useState(null); const inputRef = useRef(null); async function handleFileChange(e: React.ChangeEvent) { const file = e.target.files?.[0]; if (!file) return; setError(null); if (!ACCEPTED_TYPES.includes(file.type)) { setError("Please select a JPG, PNG, or WebP image."); return; } if (file.size > MAX_SIZE_BYTES) { setError("Image must be under 5MB."); return; } setUploading(true); try { const result = await apiUpload<{ filename: string }>("/api/images", file); onChange(result.filename); } catch { setError("Upload failed. Please try again."); } finally { setUploading(false); // Reset input so the same file can be re-selected if (inputRef.current) inputRef.current.value = ""; } } function handleRemove(e: React.MouseEvent) { e.stopPropagation(); onChange(null); } return (
{/* Hero image area */}
inputRef.current?.click()} className="relative w-full aspect-[4/3] rounded-xl overflow-hidden cursor-pointer group" > {value ? ( <> Item {/* Remove button */} ) : (
{/* ImagePlus icon */} Click to add photo
)} {/* Upload spinner overlay */} {uploading && (
)}
{error &&

{error}

}
); }