test
This commit is contained in:
parent
18bdc192f0
commit
29d1facc83
@ -14,11 +14,8 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from
|
||||
|
||||
const TimeClockPage = () => {
|
||||
const videoRef = useRef(null);
|
||||
const streamRef = useRef(null);
|
||||
const scanFrameRef = useRef(null);
|
||||
const qrControlsRef = useRef(null);
|
||||
const { isAdmin } = useAuth();
|
||||
const [isScanning, setIsScanning] = useState(false);
|
||||
const [scanMessage, setScanMessage] = useState('');
|
||||
const [scanConflict, setScanConflict] = useState(null);
|
||||
const [conflictTime, setConflictTime] = useState(new Date().toTimeString().slice(0, 5));
|
||||
@ -163,16 +160,10 @@ const TimeClockPage = () => {
|
||||
console.warn('Arrêt du lecteur QR déjà effectué.', stopError);
|
||||
}
|
||||
|
||||
if (scanFrameRef.current) {
|
||||
cancelAnimationFrame(scanFrameRef.current);
|
||||
scanFrameRef.current = null;
|
||||
}
|
||||
streamRef.current?.getTracks().forEach((track) => track.stop());
|
||||
streamRef.current = null;
|
||||
if (videoRef.current) {
|
||||
videoRef.current.pause();
|
||||
videoRef.current.srcObject = null;
|
||||
}
|
||||
setIsScanning(false);
|
||||
};
|
||||
|
||||
const handleQrResult = async (code) => {
|
||||
@ -211,14 +202,28 @@ const TimeClockPage = () => {
|
||||
useEffect(() => () => stopScanner(), []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isScannerDialogOpen || !isScanning || !videoRef.current) {
|
||||
if (!isScannerDialogOpen) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
const reader = new BrowserQRCodeReader();
|
||||
let reader = null;
|
||||
|
||||
const startReader = async () => {
|
||||
// Attendre que Radix ait réellement monté le DialogContent
|
||||
await new Promise((resolve) => {
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(resolve);
|
||||
});
|
||||
});
|
||||
|
||||
if (cancelled || !videoRef.current) {
|
||||
console.warn('Vidéo du scanner non disponible.');
|
||||
return;
|
||||
}
|
||||
|
||||
reader = new BrowserQRCodeReader();
|
||||
|
||||
try {
|
||||
const controls = await reader.decodeFromConstraints(
|
||||
{
|
||||
@ -229,33 +234,33 @@ const TimeClockPage = () => {
|
||||
},
|
||||
videoRef.current,
|
||||
(result) => {
|
||||
if (result && !cancelled) {
|
||||
handleQrResult(result.getText());
|
||||
if (!result || cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
handleQrResult(result.getText());
|
||||
},
|
||||
);
|
||||
|
||||
if (cancelled) {
|
||||
try {
|
||||
controls.stop();
|
||||
} catch (stopError) {
|
||||
console.warn(
|
||||
'Arrêt du lecteur QR déjà effectué.',
|
||||
stopError,
|
||||
);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
||||
qrControlsRef.current = controls;
|
||||
}
|
||||
} catch (scannerError) {
|
||||
if (!cancelled) {
|
||||
if (cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.error('Erreur scanner QR:', scannerError);
|
||||
|
||||
setError(
|
||||
'Impossible d’accéder à la caméra. Vérifiez les permissions et utilisez HTTPS sur le réseau.',
|
||||
);
|
||||
console.error(scannerError);
|
||||
|
||||
stopScanner();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
startReader();
|
||||
@ -264,15 +269,27 @@ const TimeClockPage = () => {
|
||||
cancelled = true;
|
||||
|
||||
try {
|
||||
reader.reset();
|
||||
reader?.reset();
|
||||
} catch (resetError) {
|
||||
console.warn(
|
||||
'Réinitialisation du lecteur QR ignorée.',
|
||||
resetError,
|
||||
);
|
||||
}
|
||||
|
||||
const controls = qrControlsRef.current;
|
||||
qrControlsRef.current = null;
|
||||
|
||||
try {
|
||||
controls?.stop();
|
||||
} catch (stopError) {
|
||||
console.warn(
|
||||
'Arrêt du lecteur QR ignoré.',
|
||||
stopError,
|
||||
);
|
||||
}
|
||||
};
|
||||
}, [isScannerDialogOpen, isScanning]);
|
||||
}, [isScannerDialogOpen]);
|
||||
|
||||
const startScanner = () => {
|
||||
setError('');
|
||||
@ -295,7 +312,7 @@ const TimeClockPage = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsScanning(true);
|
||||
setIsScannerDialogOpen(true);
|
||||
};
|
||||
|
||||
const formatTime = (timeString) => {
|
||||
@ -366,7 +383,6 @@ const TimeClockPage = () => {
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DialogTrigger asChild>
|
||||
<Button
|
||||
onClick={startScanner}
|
||||
variant="default"
|
||||
@ -374,27 +390,34 @@ const TimeClockPage = () => {
|
||||
>
|
||||
{isAdmin ? 'Pointer avec un QR code' : 'Pointer'}
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="max-w-2xl max-h-[90vh] overflow-auto">
|
||||
|
||||
<DialogContent className="max-w-2xl">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Aperçu de la caméra</DialogTitle>
|
||||
</DialogHeader>
|
||||
{isScanning ? (
|
||||
|
||||
<div className="scanner-panel">
|
||||
<video ref={videoRef} className="scanner-video w-full h-auto" playsInline muted />
|
||||
<div className="scanner-frame" aria-hidden="true" />
|
||||
<Button onClick={stopScanner} variant="secondary" className="mt-2">
|
||||
<video
|
||||
ref={videoRef}
|
||||
className="scanner-video h-auto w-full"
|
||||
playsInline
|
||||
muted
|
||||
autoPlay
|
||||
/>
|
||||
|
||||
<div
|
||||
className="scanner-frame"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
|
||||
<Button
|
||||
onClick={() => setIsScannerDialogOpen(false)}
|
||||
variant="secondary"
|
||||
className="mt-2"
|
||||
>
|
||||
Annuler
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-center py-8">
|
||||
<p>La caméra est prête à être utilisée</p>
|
||||
<Button onClick={startScanner} variant="default" className="mt-4">
|
||||
Démarrer le scanner
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user