[Admin] Checking people in on the move — the QR scanner
For scenarios where you're moving through a crowd rather than working from a desk — trailheads, sports sidelines, outdoor meetups, queue-busting at a conference entrance — the QR scanner is the faster method. One-handed on a phone, constant-time regardless of list size. Press S on any admin page to open it.
One-tap access: Click the floating Scan button (bottom-right of any admin page), or press S on your keyboard. The scanner opens in continuous-scan mode and stays open as members filter in.
One-tap access: Click the floating Scan button (bottom-right of any admin page), or press S on your keyboard. The scanner opens in continuous-scan mode and stays open as members filter in.
What happens on each scan: 1. The QR decodes (handles our `whosin://checkin/...` schema) 2. Client-side duplicate check — same member within 60 seconds triggers a warning tone, no double-log 3. CF call with a unique `scanId` (UUID per scan — idempotent, safe to retry) 4. Backend Firestore transaction: verify membership active, waiver signed, decrement class pack if applicable, write `checkInEvents/{scanId}` record 5. Feedback in <500ms: success green flash + 880Hz beep + vibration; or red pulse + low-pitch tone + triage card
Offline mode: If wifi drops, scans queue in IndexedDB with their scanId. On reconnect, the queue flushes sequentially — backend idempotency means replays are safe. Yellow "queued (N)" indicator shows pending count.
Feedback channels: - Visual — full-screen flash + member photo + last-10-scans timeline - Audio — distinct tones per outcome (success / fail / warn) via Web Audio API - Haptic — `navigator.vibrate` on mobile devices
Failed scan triage: - Expired — orange banner with "Extend grace period" / "Manual override" actions - Paused — "Member paused on {date}. Resume?" action - Pack exhausted — "Class pack used up. Offer drop-in?" - Waiver not signed — "Member hasn't signed the current waiver. Send link?" - Invalid QR — "Manual entry" fallback form (email / phone / 6-digit code)
Manual entry: When a QR is damaged or unreadable, tap "Manual entry" and enter the member's email / phone / 6-digit code. Same validation pipeline as a scan.
Audit trail: Every scan (success or fail) writes to `checkInEvents` with scanner uid, timestamp, device info, outcome. Accessible via the per-class "Attendance log" in the admin dashboard.
Stress-tested: 20 concurrent scans across 5 members resolve correctly with zero double-decrements (verified in CI).
Tips for busy front-desk operations: - Keep the scanner open in continuous mode (don't dismiss between members) - Pin a spare phone by the door — the scanner works on any logged-in admin device - For big classes, use "Multi-scan" (default) rather than one-at-a-time - If a member forgot their phone, tap Manual entry → enter their email → done in 3 seconds