« Back to History
attendance-punch.js
|
20260723_000646.php
Initial Domain Snapshot
Copy Code
// attendance-punch.js document.addEventListener('DOMContentLoaded', function(){ const video = document.getElementById('fc-video'); const captureBtn = document.getElementById('fc-capture-btn'); const stopBtn = document.getElementById('fc-stop-btn'); const methodSel = document.getElementById('method'); const cameraRow = document.getElementById('fc-camera-row'); const manualRow = document.getElementById('fc-manual-row'); const manualPunchBtn = document.getElementById('fc-manual-punch-btn'); const manualNote = document.getElementById('manual_note'); const resultBox = document.getElementById('fc-punch-result'); let stream = null; function logResult(msg, ok=true){ resultBox.textContent = msg; resultBox.className = ok ? 'notice notice-success' : 'notice notice-error'; } methodSel.addEventListener('change', function(){ if (methodSel.value === 'face') { cameraRow.style.display = 'block'; manualRow.style.display = 'none'; startCamera(); } else { cameraRow.style.display = 'none'; manualRow.style.display = 'block'; stopCamera(); } }); async function startCamera(){ if (stream) return; try { stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'user' }, audio: false }); video.srcObject = stream; } catch (e) { console.error('Camera error', e); logResult('Camera permission denied or not available.', false); } } function stopCamera(){ if (!stream) return; stream.getTracks().forEach(t => t.stop()); stream = null; video.srcObject = null; } stopBtn.addEventListener('click', stopCamera); captureBtn.addEventListener('click', async function(){ const employee_id = document.getElementById('employee_id').value; if (!employee_id) { logResult('Select employee first', false); return; } const direction = document.getElementById('direction').value; if (!stream) { await startCamera(); if (!stream) return; } const canvas = document.createElement('canvas'); canvas.width = video.videoWidth || 640; canvas.height = video.videoHeight || 480; const ctx = canvas.getContext('2d'); ctx.drawImage(video, 0, 0, canvas.width, canvas.height); const dataUrl = canvas.toDataURL('image/jpeg', 0.8); const payload = { employee_id: parseInt(employee_id), method: 'face', direction: direction, device_id: 'web-' + (navigator.userAgent || '').slice(0,50), photo: dataUrl }; try { const res = await fetch('/erp/api/attendance/punch.php', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify(payload) }); const j = await res.json(); if (j && j.ok) { logResult('Punch recorded ✔ (ID: ' + (j.attendance_id || '') + ')'); } else { logResult('Error: ' + (j.error || j.msg || 'unknown'), false); } } catch (err) { console.error(err); logResult('Network error while recording punch', false); } }); manualPunchBtn.addEventListener('click', async function(){ const employee_id = document.getElementById('employee_id').value; if (!employee_id) { logResult('Select employee first', false); return; } const direction = document.getElementById('direction').value; const payload = { employee_id: parseInt(employee_id), method: 'manual', direction: direction, device_id: 'web-manual-' + (navigator.userAgent || '').slice(0,40), note: manualNote.value || null }; try { const res = await fetch('/erp/api/attendance/punch.php', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify(payload) }); const j = await res.json(); if (j && j.ok) { logResult('Manual punch recorded ✔ (ID: ' + (j.attendance_id || '') + ')'); } else { logResult('Error: ' + (j.error || j.msg || 'unknown'), false); } } catch (err) { console.error(err); logResult('Network error while recording manual punch', false); } }); // Start camera automatically when page loads and method default is face if (methodSel.value === 'face') startCamera(); });