const kiosk = document.querySelector(".kiosk-grid"); const video = document.getElementById("cameraStream"); const canvas = document.getElementById("snapshotCanvas"); const preview = document.getElementById("snapshotPreview"); const startButton = document.getElementById("startCamera"); const captureButton = document.getElementById("capturePhoto"); const statusText = document.getElementById("cameraStatus"); const results = document.getElementById("recognitionResults"); const frame = document.querySelector(".camera-frame"); const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute("content"); let activeStream = null; let lastFaces = []; startButton.addEventListener("click", async () => { try { activeStream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: "user" }, audio: false }); video.srcObject = activeStream; frame.classList.remove("has-preview"); captureButton.disabled = false; statusText.textContent = "Camera is active."; } catch (error) { statusText.textContent = `Camera access failed: ${error.name}`; } }); captureButton.addEventListener("click", async () => { if (!video.videoWidth || !video.videoHeight) { statusText.textContent = "Camera is not ready yet."; return; } canvas.width = video.videoWidth; canvas.height = video.videoHeight; canvas.getContext("2d").drawImage(video, 0, 0, canvas.width, canvas.height); const image = canvas.toDataURL("image/png"); await identify(image); }); async function identify(image) { setLoading("Identifying faces..."); const formData = new FormData(); formData.append("image", image); const response = await fetch(kiosk.dataset.identifyUrl, { method: "POST", body: formData, credentials: "same-origin", headers: { "X-CSRFToken": csrfToken, "Accept": "application/json" }, }); const payload = await response.json(); if (!response.ok) { showError(payload.error || "Recognition failed."); return; } lastFaces = payload.faces; preview.src = payload.annotated_image; frame.classList.add("has-preview"); renderFaces(payload.faces); } function renderFaces(faces) { results.innerHTML = ""; if (!faces.length) { results.innerHTML = '
No enrolled person matched this face.
"; results.appendChild(card); return; } const confidence = face.confidence === null ? "n/a" : `${Math.round(face.confidence * 100)}%`; card.innerHTML = `${escapeHtml(face.employee_id)} - Confidence ${confidence}
${escapeHtml(face.last_presence)}