"use client" import { useRef, useState, useCallback, useEffect } from "react" import { Camera, ImagePlus, X, Loader2 } from "lucide-react" import { Button } from "@/components/ui/button" import { CameraCapture } from "@/components/scan/camera-capture" import { cn } from "@/lib/utils" interface DrinkImageUploadProps { imageUrl?: string | null onImageChange: (url: string | null) => void } export function DrinkImageUpload({ imageUrl, onImageChange, }: DrinkImageUploadProps) { const [isUploading, setIsUploading] = useState(false) const [dragActive, setDragActive] = useState(false) const [error, setError] = useState(null) const [showCamera, setShowCamera] = useState(false) const [hasGetUserMedia, setHasGetUserMedia] = useState(false) const fileInputRef = useRef(null) const cameraInputRef = useRef(null) // getUserMedia needs a secure context, so it is absent when the app is reached // over plain http on the LAN. Checked after mount because it is not available // during server rendering. useEffect(() => { setHasGetUserMedia( typeof navigator !== "undefined" && !!navigator.mediaDevices?.getUserMedia ) }, []) const uploadFile = useCallback( async (file: File) => { setError(null) setIsUploading(true) try { const formData = new FormData() formData.append("file", file) const res = await fetch("/api/upload", { method: "POST", body: formData, }) if (!res.ok) { const body = await res.json().catch(() => ({})) throw new Error(body.error || "Failed to upload image") } const { url } = await res.json() onImageChange(url) } catch (err) { setError(err instanceof Error ? err.message : "Failed to upload image") } finally { setIsUploading(false) } }, [onImageChange] ) const handleFile = useCallback( (file: File) => { if (!file.type.startsWith("image/")) { setError("Please select an image file") return } uploadFile(file) }, [uploadFile] ) const handleDrop = useCallback( (e: React.DragEvent) => { e.preventDefault() setDragActive(false) const file = e.dataTransfer.files[0] if (file) { handleFile(file) } }, [handleFile] ) const handleRemove = () => { onImageChange(null) setError(null) if (fileInputRef.current) fileInputRef.current.value = "" if (cameraInputRef.current) cameraInputRef.current.value = "" } if (showCamera) { return ( { setShowCamera(false) handleFile(file) }} onClose={() => setShowCamera(false)} /> ) } if (imageUrl) { return (
Drink photo
) } return (
{ e.preventDefault() setDragActive(true) }} onDragLeave={() => setDragActive(false)} onDrop={handleDrop} >
{isUploading ? ( <>

Uploading...

) : ( <>

or drag and drop an image here

)}
{error &&

{error}

} { const file = e.target.files?.[0] if (file) handleFile(file) }} /> { const file = e.target.files?.[0] if (file) handleFile(file) }} />
) }