119 lines
3.7 KiB
JavaScript
119 lines
3.7 KiB
JavaScript
import React, {
|
|
useEffect,
|
|
useRef,
|
|
useState,
|
|
forwardRef,
|
|
useImperativeHandle,
|
|
} from "react";
|
|
import { Html5Qrcode } from "html5-qrcode";
|
|
import { useDispatch } from "react-redux";
|
|
import { changeSearchedData } from "../../../../Features/BookingScreen/BookingData/BookingData.js";
|
|
|
|
const BarcodeScannerTurbo = forwardRef(
|
|
({ handleQrData, openScanner, setOpenScanner, type }, ref) => {
|
|
const dispatch = useDispatch();
|
|
const html5QrCodeRef = useRef(null);
|
|
const [isScannerActive, setIsScannerActive] = useState(false);
|
|
|
|
useImperativeHandle(ref, () => ({
|
|
stopScanner,
|
|
reinitializeCamera,
|
|
}));
|
|
|
|
useEffect(() => {
|
|
if (openScanner) {
|
|
console.log("📸 Modal opened → starting scanner...");
|
|
startScanner();
|
|
} else {
|
|
console.log("🛑 Modal closed → stopping scanner...");
|
|
stopScanner();
|
|
}
|
|
|
|
return () => {
|
|
console.log("♻️ Component unmounted → cleaning up scanner...");
|
|
stopScanner();
|
|
};
|
|
}, [openScanner]);
|
|
|
|
const startScanner = async () => {
|
|
try {
|
|
if (html5QrCodeRef.current) {
|
|
console.log("⚠️ Scanner instance already exists, stopping before restart...");
|
|
await stopScanner(); // ensure clean restart
|
|
}
|
|
|
|
const qrContainer = document.getElementById("qr-reader");
|
|
if (qrContainer) qrContainer.innerHTML = "";
|
|
|
|
html5QrCodeRef.current = new Html5Qrcode("qr-reader");
|
|
console.log("✅ Scanner instance created");
|
|
|
|
const config = { fps: 10, qrbox: { width: 250, height: 250 } };
|
|
|
|
await html5QrCodeRef.current.start(
|
|
{ facingMode: "environment" },
|
|
config,
|
|
(decodedText) => {
|
|
console.log("🎯 Barcode scanned:", decodedText);
|
|
if (type === "Search") {
|
|
dispatch(changeSearchedData(decodedText));
|
|
}
|
|
handleQrData(decodedText);
|
|
setOpenScanner(false);
|
|
}
|
|
);
|
|
|
|
setIsScannerActive(true);
|
|
console.log("🚀 Scanner started successfully");
|
|
} catch (err) {
|
|
console.error("❌ Failed to start scanner:", err);
|
|
if (err.name === 'NotAllowedError' || err?.includes('Permission denied')) {
|
|
// Camera permission denied
|
|
handleQrData('', { error: 'Camera permission denied. Please allow camera access and try again.' });
|
|
} else if (err.name === 'NotFoundError' || err?.includes('NotFoundError')) {
|
|
// No camera found
|
|
handleQrData('', { error: 'No camera found on this device.' });
|
|
} else if (err.name === 'NotReadableError' || err?.includes('NotReadableError')) {
|
|
// Camera already in use
|
|
handleQrData('', { error: 'Camera is already in use by another application.' });
|
|
} else {
|
|
// Generic error
|
|
handleQrData('', { error: 'Failed to initialize camera scanner.' });
|
|
}
|
|
|
|
}
|
|
};
|
|
|
|
const stopScanner = async () => {
|
|
if (html5QrCodeRef.current) {
|
|
try {
|
|
await html5QrCodeRef.current.stop();
|
|
await html5QrCodeRef.current.clear();
|
|
html5QrCodeRef.current = null; // important reset
|
|
setIsScannerActive(false);
|
|
console.log("🛑 Scanner stopped + cleared");
|
|
} catch (err) {
|
|
console.warn("⚠️ Error stopping scanner:", err);
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
const reinitializeCamera = () => {
|
|
console.log("🔄 Reinitializing scanner...");
|
|
stopScanner().then(() => startScanner());
|
|
};
|
|
|
|
return (
|
|
<div style={{ textAlign: "center", marginTop: "50px" }}>
|
|
<div
|
|
id="qr-reader"
|
|
style={{ width: "300px", margin: "0 auto" }}
|
|
></div>
|
|
</div>
|
|
);
|
|
}
|
|
);
|
|
|
|
export default BarcodeScannerTurbo;
|