diff --git a/fusion_clock/__manifest__.py b/fusion_clock/__manifest__.py index 7dcc4ca7..6e5962f9 100644 --- a/fusion_clock/__manifest__.py +++ b/fusion_clock/__manifest__.py @@ -84,6 +84,7 @@ Integrates natively with Odoo's hr.attendance module for full payroll compatibil 'fusion_clock/static/src/scss/nfc_kiosk.scss', 'fusion_clock/static/src/js/fusion_clock_portal.js', 'fusion_clock/static/src/js/fusion_clock_kiosk.js', + 'fusion_clock/static/src/js/fusion_clock_nfc_kiosk.js', ], 'web.assets_backend': [ 'fusion_clock/static/src/scss/fusion_clock.scss', diff --git a/fusion_clock/static/src/js/fusion_clock_nfc_kiosk.js b/fusion_clock/static/src/js/fusion_clock_nfc_kiosk.js new file mode 100644 index 00000000..66f8e817 --- /dev/null +++ b/fusion_clock/static/src/js/fusion_clock_nfc_kiosk.js @@ -0,0 +1,131 @@ +/* @odoo-module */ + +// NFC Clock Kiosk — Web NFC + camera + state machine. +// Loaded as a frontend asset on /fusion_clock/kiosk/nfc only (the +// element #nfc_kiosk_root only exists on that page, so the module is +// inert elsewhere). + +(function() { + "use strict"; + + const root = document.getElementById("nfc_kiosk_root"); + if (!root) return; // not on the kiosk page + + const stateContainer = document.getElementById("nfc_state_container"); + const photoRequired = root.dataset.photoRequired === "1"; + const debugEnabled = root.dataset.debugEnabled === "1"; + const locationConfigured = root.dataset.locationConfigured === "1"; + + // ────────────────────────────────────────────────────────────── + // State machine + // ────────────────────────────────────────────────────────────── + const STATE = { SETUP: "setup", IDLE: "idle", PROCESSING: "processing", RESULT: "result", ENROLL: "enroll" }; + let currentState = STATE.SETUP; + + function setState(next, payload) { + currentState = next; + if (next === STATE.IDLE) renderIdle(); + else if (next === STATE.PROCESSING) renderProcessing(); + else if (next === STATE.RESULT) renderResult(payload); + else if (next === STATE.ENROLL) renderEnroll(payload); + } + + // ────────────────────────────────────────────────────────────── + // Rendering helpers + // ────────────────────────────────────────────────────────────── + function renderIdle() { + stateContainer.innerHTML = ` +