feat(fusion_clock): always-available kiosk photo action + compact manager PIN pad

NFC kiosk:
- Add "📷 Photo" action to every Manage-page employee row and to the
  post-enroll result card, so a manager can set/replace a profile photo
  at any time (previously only surfaced when the employee had no image).
- Slim the Manager PIN pad: dedicated --pin panel variant (max-width 360px,
  reduced padding) with a tighter numpad, removing the oversized whitespace.

Deployed live to entech (LXC 111) as 19.0.3.11.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-30 17:38:34 -04:00
parent 55898dd1d4
commit 5a488ae86e
3 changed files with 14 additions and 8 deletions

View File

@@ -306,7 +306,7 @@
let pin = "";
stateContainer.innerHTML = `
<div class="nfc-kiosk__enroll-overlay">
<div class="nfc-kiosk__enroll-panel">
<div class="nfc-kiosk__enroll-panel nfc-kiosk__enroll-panel--pin">
<h2>${escapeHtml(opts.title || "Enter PIN")}</h2>
<div class="pin-display" id="nfc_pin_display"></div>
<div class="numpad">
@@ -415,6 +415,7 @@
? `<button class="m-btn m-danger" data-act="delok" data-id="${e.id}">Confirm delete</button>
<button class="m-btn" data-act="delno" data-id="${e.id}">Cancel</button>`
: `<button class="m-btn" data-act="assign" data-id="${e.id}" data-name="${escapeHtml(e.name)}">${e.card_uid ? "Re-tag" : "Assign"}</button>
<button class="m-btn" data-act="photo" data-id="${e.id}" data-name="${escapeHtml(e.name)}">📷 Photo</button>
${e.card_uid ? `<button class="m-btn" data-act="clear" data-id="${e.id}">Clear tag</button>` : ""}
<button class="m-btn m-danger" data-act="del" data-id="${e.id}">Delete</button>`;
return `<div class="manager-row">
@@ -430,6 +431,8 @@
enrollSelectedEmployee = { id, name: btn.dataset.name };
pendingEnrollUid = null;
renderEnroll({ phase: "tap" });
} else if (act === "photo") {
openPhotoCapture(id, btn.dataset.name, () => renderEnroll({ phase: "manager" }));
} else if (act === "clear") {
try { await postJson("/fusion_clock/kiosk/nfc/clear_tag", { employee_id: id, enroll_password: enrollPassword }); } catch (e) {}
refresh();
@@ -566,14 +569,14 @@
<div class="nfc-kiosk__enroll-panel" style="text-align:center">
<h2 style="color:${ok ? "var(--nfc-success)" : "var(--nfc-error)"}">${msg}</h2>
<div class="actions" style="justify-content:center">
${ok && payload.needs_photo && payload.employee_id ? `<button class="confirm" id="enroll_photo">📷 Take photo</button>` : ""}
${ok && payload.employee_id ? `<button class="confirm" id="enroll_photo">📷 Take photo</button>` : ""}
<button class="confirm" id="enroll_another">Enroll another</button>
<button class="cancel" id="enroll_done">Done</button>
</div>
</div>
</div>
`;
if (ok && payload.needs_photo && payload.employee_id) {
if (ok && payload.employee_id) {
document.getElementById("enroll_photo").addEventListener("click", () => {
openPhotoCapture(payload.employee_id, payload.employee_name, () => {
if (enrollPassword) renderEnroll({ phase: "manager" }); else exitEnrollMode();