osg / static /js /register.js
devindia's picture
Upload 29 files
df53738 verified
Raw
History Blame Contribute Delete
5.14 kB
const video = document.getElementById('videoFeed');
const empIdInput = document.getElementById('empId');
const empNameInput = document.getElementById('empName');
const btnRegister = document.getElementById('btnRegister');
const statusText = document.getElementById('statusText');
const progressCircle = document.getElementById('progressCircle');
const spoofToast = document.getElementById('spoofToast');
const spoofToastMessage = document.getElementById('spoofToastMessage');
let capturedFrames = [];
let isCapturing = false;
const REQUIRED_FRAMES = 5;
let toastDismissTimer = null;
// Start Camera
navigator.mediaDevices.getUserMedia({ video: { facingMode: 'user', width: 640, height: 480 } })
.then(stream => { video.srcObject = stream; })
.catch(err => console.error(err));
// Monitor inputs to enable capture
[empIdInput, empNameInput].forEach(input => {
input.addEventListener('input', checkInputs);
});
function checkInputs() {
const valid = empIdInput.value.trim().length > 0 && empNameInput.value.trim().length > 0;
if (valid && !isCapturing && capturedFrames.length === 0) {
btnRegister.disabled = false;
btnRegister.textContent = "START CAPTURE";
btnRegister.onclick = startCaptureProcess;
} else if (capturedFrames.length === REQUIRED_FRAMES) {
btnRegister.disabled = false;
btnRegister.textContent = "Register";
btnRegister.onclick = submitRegistration;
} else {
btnRegister.disabled = true;
}
}
function startCaptureProcess() {
isCapturing = true;
btnRegister.disabled = true;
capturedFrames = [];
statusText.textContent = "Keep face steady...";
let count = 0;
const interval = setInterval(() => {
if (count >= REQUIRED_FRAMES) {
clearInterval(interval);
finishCapture();
return;
}
const canvas = document.createElement('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0);
capturedFrames.push(canvas.toDataURL('image/jpeg', 0.8));
count++;
updateProgress(count / REQUIRED_FRAMES);
statusText.textContent = `Scanning... ${Math.round((count/REQUIRED_FRAMES)*100)}%`;
}, 600);
}
function updateProgress(percent) {
const offset = 113 - (113 * percent);
progressCircle.style.strokeDashoffset = offset;
}
function finishCapture() {
isCapturing = false;
statusText.textContent = "Face captured ✓";
statusText.style.color = "var(--color-primary)";
checkInputs(); // Re-enable button for submit
}
async function submitRegistration() {
btnRegister.disabled = true;
btnRegister.textContent = "REGISTERING...";
const payload = {
employee_id: empIdInput.value.trim(),
name: empNameInput.value.trim(),
frames: capturedFrames
};
try {
const res = await fetch('/api/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
const data = await res.json();
if (data.status === 'registered') {
document.getElementById('registerForm').style.display = 'none';
document.getElementById('successState').style.display = 'block';
document.getElementById('successChip').textContent = `${payload.name}${payload.employee_id}`;
} else if (data.status === 'spoof') {
showSpoofToast(data);
btnRegister.disabled = false;
btnRegister.textContent = "Register";
} else {
// Duplicate user or other error → snackbar
var msg = data.message || "Unknown error";
if (msg.indexOf("already registered") !== -1 || msg.indexOf("already registered to") !== -1) {
if (typeof showSnackbar === 'function') showSnackbar("Duplicate registration — this face is already registered.", 'error');
} else if (msg.indexOf("No face detected") !== -1 || msg.indexOf("no face") !== -1) {
if (typeof showSnackbar === 'function') showSnackbar("Clear photo — ensure your face is visible and well lit.", 'info');
} else {
if (typeof showSnackbar === 'function') showSnackbar(msg, 'error');
}
btnRegister.disabled = false;
btnRegister.textContent = "Register";
}
} catch (e) {
if (typeof showSnackbar === 'function') showSnackbar("Network error. Please try again.", 'error');
btnRegister.disabled = false;
btnRegister.textContent = "Register";
}
}
function showSpoofToast(data) {
const msg = data.reason || data.message || "Use a live face, not a photo or screen.";
spoofToastMessage.textContent = msg;
spoofToast.classList.add('show');
if (toastDismissTimer) clearTimeout(toastDismissTimer);
toastDismissTimer = setTimeout(() => {
spoofToast.classList.remove('show');
toastDismissTimer = null;
}, 4500);
}