diff --git a/src/components/drinks/drink-image-upload.tsx b/src/components/drinks/drink-image-upload.tsx index 9244f81..bab344f 100644 --- a/src/components/drinks/drink-image-upload.tsx +++ b/src/components/drinks/drink-image-upload.tsx @@ -1,8 +1,9 @@ "use client" -import { useRef, useState, useCallback } from "react" -import { ImagePlus, X, Loader2 } from "lucide-react" +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 { @@ -17,7 +18,19 @@ export function DrinkImageUpload({ 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) => { @@ -76,6 +89,19 @@ export function DrinkImageUpload({ 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) { @@ -125,14 +151,30 @@ export function DrinkImageUpload({ ) : ( <> - +
+ + +

or drag and drop an image here

@@ -143,6 +185,17 @@ export function DrinkImageUpload({ {error &&

{error}

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

{error}

- @@ -103,6 +103,7 @@ export function CameraCapture({ onCapture, onClose }: CameraCaptureProps) { {/* Overlay controls */}