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