import { useRef, useState, useCallback, useEffect } from "react"; import { Camera, CameraOff, Aperture, X } from "lucide-react"; export default function CameraPanel({ onCapture, previewUrl, onReset }) { const videoRef = useRef(null); const canvasRef = useRef(null); const streamRef = useRef(null); const [isCameraOn, setIsCameraOn] = useState(false); const [cameraError, setCameraError] = useState(""); const [isVideoReady, setIsVideoReady] = useState(false); // Cleanup saat unmount useEffect(() => { return () => { stopCamera(); }; }, []); // Assign stream ke video element setelah state berubah dan element ter-render useEffect(() => { if (isCameraOn && videoRef.current && streamRef.current) { const video = videoRef.current; video.srcObject = streamRef.current; video.onloadedmetadata = () => { video.play() .then(() => setIsVideoReady(true)) .catch((err) => console.error("Video play error:", err)); }; } }, [isCameraOn]); async function startCamera() { setCameraError(""); setIsVideoReady(false); try { const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment", width: { ideal: 1280 }, height: { ideal: 720 }, }, }); streamRef.current = stream; // Set state dulu agar video element di-render, // lalu useEffect di atas akan assign stream setIsCameraOn(true); } catch (err) { console.error("Camera error:", err); if (err.name === "NotAllowedError") { setCameraError("Izin kamera ditolak. Aktifkan izin kamera pada browser."); } else if (err.name === "NotFoundError") { setCameraError("Kamera tidak ditemukan pada perangkat ini."); } else { setCameraError("Gagal mengaktifkan kamera. Coba lagi."); } } } function stopCamera() { if (streamRef.current) { streamRef.current.getTracks().forEach((track) => track.stop()); streamRef.current = null; } if (videoRef.current) { videoRef.current.srcObject = null; } setIsCameraOn(false); setIsVideoReady(false); } const captureImage = useCallback(() => { if (!videoRef.current || !canvasRef.current) return; const video = videoRef.current; const canvas = canvasRef.current; canvas.width = video.videoWidth; canvas.height = video.videoHeight; const ctx = canvas.getContext("2d"); ctx.drawImage(video, 0, 0); canvas.toBlob( (blob) => { if (blob) { const file = new File([blob], `capture_${Date.now()}.jpg`, { type: "image/jpeg", }); onCapture(file); stopCamera(); } }, "image/jpeg", 0.9 ); }, [onCapture]); return (
{cameraError && (
{cameraError}
)} {previewUrl ? (
Captured
) : isCameraOn ? (
{/* Loading indicator sebelum video ready */} {!isVideoReady && (

Memuat kamera...

)}
) : (

Gunakan kamera untuk mengambil gambar kendaraan

)}
); }