From 49ec452c961589739c697e789dbd331b84449d9e Mon Sep 17 00:00:00 2001 From: isaacclad Date: Sun, 28 Jun 2026 21:44:06 +0000 Subject: [PATCH] Redesign employee kiosk sign-in to match visitor check-in polish. Split staff identify into two steps with progress header, labeled fields, and icon mode cards; remove uppercase styling on employee code input. Co-authored-by: Cursor --- resources/js/kiosk-flow.js | 89 ++++++- .../views/frontdesk/kiosk/index.blade.php | 233 ++++++++++++++---- 2 files changed, 269 insertions(+), 53 deletions(-) diff --git a/resources/js/kiosk-flow.js b/resources/js/kiosk-flow.js index 8457167..90c931c 100644 --- a/resources/js/kiosk-flow.js +++ b/resources/js/kiosk-flow.js @@ -13,6 +13,7 @@ export function registerKioskFlow(Alpine) { staffQrScanning: false, staffQrScanned: false, staffQrError: '', + staffFormStep: 1, staffEmployee: null, staffMessage: '', staffBranchWarning: '', @@ -181,6 +182,18 @@ export function registerKioskFlow(Alpine) { async goBack() { if (this.step === 'staff_identify') { + if (this.staffFormStep === 2) { + this.staffFormStep = 1; + this.staffForm.pin = ''; + this.errorMessage = ''; + if (this.staffIdentifyMode === 'badge' && ! this.staffQrScanned) { + await this.$nextTick(); + await this.startStaffQrScanner(); + } + this.resetTimer(); + + return; + } await this.stopStaffQrScanner(true); } if (this.step === 'type') { @@ -225,6 +238,7 @@ export function registerKioskFlow(Alpine) { this.staffForm = { employee_code: '', qr_token: '', pin: '' }; this.staffQrScanned = false; this.staffQrError = ''; + this.staffFormStep = 1; this.staffStepOut = { step_out_reason: 'lunch', destination: '', notes: '', expected_return_at: '' }; this.form = { full_name: '', company: '', phone: '', email: '', host_id: '', @@ -253,18 +267,70 @@ export function registerKioskFlow(Alpine) { this.step = 'staff_identify'; this.errorMessage = ''; this.staffIdentifyMode = 'code'; + this.staffFormStep = 1; this.staffForm = { employee_code: '', qr_token: '', pin: '' }; this.staffQrScanned = false; this.staffQrError = ''; this.resetTimer(); }, + staffIdentifyStepLabel() { + return this.staffFormStep === 1 ? 'Identify yourself' : 'Enter your PIN'; + }, + + validateStaffIdentifyStep1() { + if (this.staffIdentifyMode === 'code') { + if (! String(this.staffForm.employee_code || '').trim()) { + this.showError('Please enter your employee code.'); + + return false; + } + } else if (! String(this.staffForm.qr_token || '').trim()) { + this.showError('Scan your badge to continue.'); + return false; + } + + this.errorMessage = ''; + + return true; + }, + + async nextStaffIdentifyStep() { + if (! this.validateStaffIdentifyStep1()) { + return; + } + + await this.stopStaffQrScanner(false); + this.staffFormStep = 2; + this.errorMessage = ''; + this.resetTimer(); + }, + + async prevStaffIdentifyStep() { + if (this.staffFormStep === 2) { + this.staffFormStep = 1; + this.staffForm.pin = ''; + this.errorMessage = ''; + if (this.staffIdentifyMode === 'badge' && ! this.staffQrScanned) { + await this.$nextTick(); + await this.startStaffQrScanner(); + } + this.resetTimer(); + + return; + } + + await this.goBack(); + }, + async setStaffIdentifyMode(mode) { if (this.staffIdentifyMode === mode) { return; } await this.stopStaffQrScanner(true); this.staffIdentifyMode = mode; + this.staffFormStep = 1; + this.staffForm.pin = ''; this.staffQrError = ''; if (mode === 'badge') { await this.$nextTick(); @@ -289,7 +355,7 @@ export function registerKioskFlow(Alpine) { }, async startStaffQrScanner() { - if (this.staffQrScanning || this.staffQrScanned || this.staffIdentifyMode !== 'badge') { + if (this.staffQrScanning || this.staffQrScanned || this.staffIdentifyMode !== 'badge' || this.staffFormStep !== 1) { return; } @@ -329,12 +395,15 @@ export function registerKioskFlow(Alpine) { this.staffQrScanned = true; this.errorMessage = ''; await this.stopStaffQrScanner(false); + this.staffFormStep = 2; this.resetTimer(); }, async rescanStaffBadge() { this.staffQrScanned = false; this.staffForm.qr_token = ''; + this.staffForm.pin = ''; + this.staffFormStep = 1; this.staffQrError = ''; await this.$nextTick(); await this.startStaffQrScanner(); @@ -406,16 +475,24 @@ export function registerKioskFlow(Alpine) { }, async staffIdentify() { - const hasCode = this.staffIdentifyMode === 'code' && this.staffForm.employee_code.trim(); - const hasBadge = this.staffIdentifyMode === 'badge' && this.staffForm.qr_token.trim(); - if ((!hasCode && !hasBadge) || !/^\d{4,6}$/.test(this.staffForm.pin)) { - this.showError('Enter your employee code or scan your badge, plus your PIN.'); + if (this.staffFormStep === 1) { + await this.nextStaffIdentifyStep(); + return; } + + if (! /^\d{4,6}$/.test(this.staffForm.pin)) { + this.showError('Enter a 4–6 digit PIN.'); + + return; + } + try { await this.stopStaffQrScanner(false); const data = await this.staffPost('identify'); - if (!data) return; + if (! data) { + return; + } this.staffEmployee = data.employee; this.step = 'staff_actions'; this.resetTimer(); diff --git a/resources/views/frontdesk/kiosk/index.blade.php b/resources/views/frontdesk/kiosk/index.blade.php index 0d1a756..f7ea8d3 100644 --- a/resources/views/frontdesk/kiosk/index.blade.php +++ b/resources/views/frontdesk/kiosk/index.blade.php @@ -288,37 +288,142 @@ @include('frontdesk.partials.kiosk-back')
-

Employee sign-in

-

Enter your employee code and PIN, or scan your badge with the camera.

-

-
- - +
+
+ Staff sign-in + +
+
+
+
+

-
- - + + {{-- Step 2: PIN --}} + + +
+
-
@@ -329,18 +434,29 @@
@include('frontdesk.partials.kiosk-back')
-
-

-

-

+
+
+ +

+

+

+
+

-
+ +

What would you like to do?

+
@@ -354,18 +470,41 @@ @include('frontdesk.partials.kiosk-back')
-

Where are you going?

-

Let reception know you're stepping out.

-

-
- - - - +
+
+ + Step out +
+
+
+
+

Where are you going?

+

Reception will know you're away from your desk.

+
+ +

+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +