"use client"; import React, { useState, useEffect, useRef, useCallback } from "react"; import { X, Camera, AlertCircle, CheckCircle } from "lucide-react"; import { Button } from "@/components/ui/button"; interface BarcodeScannerProps { isOpen: boolean; onClose: () => void; onScan: (barcode: string) => void; } export function BarcodeScanner({ isOpen, onClose, onScan, }: BarcodeScannerProps) { const [isScanning, setIsScanning] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(false); const scannerRef = useRef(null); const qrCodeScanner = useRef(null); // Verificar se é mobile const isMobile = typeof window !== "undefined" && /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); // Verificar se é HTTPS ou localhost const isSecure = typeof window !== "undefined" && (window.location.protocol === "https:" || window.location.hostname === "localhost"); const startScanner = useCallback(async () => { try { setError(null); setIsScanning(true); // Dynamic import para carregar apenas quando necessário const { Html5QrcodeScanner } = await import("html5-qrcode"); if (!scannerRef.current) return; qrCodeScanner.current = new Html5QrcodeScanner( scannerRef.current.id, { fps: 10, qrbox: { width: 250, height: 250 }, aspectRatio: 1.0, }, false ); qrCodeScanner.current.render( (decodedText: string) => { // Validar se é um código de barras válido if (isValidBarcode(decodedText)) { setSuccess(true); setTimeout(() => { onScan(decodedText); onClose(); }, 1000); } else { setError("Código de barras inválido. Tente novamente."); } }, (error: string) => { // Ignorar erros de "No QR code found" para não spam if (!error.includes("No QR code found")) { console.warn("Erro do scanner:", error); } } ); } catch (err) { console.error("Erro ao iniciar scanner:", err); setError("Erro ao acessar a câmera. Verifique as permissões."); setIsScanning(false); } }, [onScan, onClose]); useEffect(() => { if (isOpen && isMobile && isSecure) { startScanner(); } else if (isOpen && !isMobile) { setError("Scanner de câmera disponível apenas em dispositivos móveis"); } else if (isOpen && !isSecure) { setError("Scanner de câmera requer conexão segura (HTTPS)"); } return () => { stopScanner(); }; }, [isOpen, isMobile, isSecure, startScanner]); const stopScanner = () => { if (qrCodeScanner.current) { qrCodeScanner.current.clear().catch((err: unknown) => { console.warn("Erro ao parar scanner:", err); }); qrCodeScanner.current = null; } setIsScanning(false); }; const isValidBarcode = (code: string): boolean => { const cleanCode = code.replace(/\D/g, ""); return cleanCode.length >= 8 && cleanCode.length <= 13; }; const handleClose = () => { stopScanner(); setError(null); setSuccess(false); onClose(); }; if (!isOpen) return null; return (
{/* Header */}

Scanner de Código de Barras

{/* Content */}
{!isMobile && (

Scanner de câmera disponível apenas em dispositivos móveis

Use o campo de busca para digitar o código de barras manualmente

)} {!isSecure && (

Scanner de câmera requer conexão segura (HTTPS)

Use o campo de busca para digitar o código de barras manualmente

)} {isMobile && isSecure && (
{error && (

{error}

)} {success && (

Código de barras detectado com sucesso!

)}

Aponte a câmera para o código de barras do produto

{/* Scanner Container */}
{!isScanning && !error && (

Iniciando câmera...

)}

Mantenha o código de barras dentro da área destacada

)} {/* Actions */}
{isMobile && isSecure && ( )}
); }