Nasaq
Components

CheckInKiosk

Self check-in kiosk - scan or type a booking code, or enter a phone number on a big keypad, find the booking, and print a queue ticket with a QR and an auto reset.

PreviewOpen ↗

Code

import { CheckInKiosk } from "@fadymondy/nasaq/web";<CheckInKiosk  bookings={todaysBookings}  onCheckIn={async (request) => {    const entry = await api.checkIn(request);    return { entry, position: 3, waitMinutes: 20 };  }}/>

Bookings · beta

Live examples and controls: CheckInKiosk in the lab.

Install

npx shadcn@latest add https://docs.nasaqui.com/r/check-in-kiosk.json

For a tablet at the front door. A handheld scanner types into the focused code field like a keyboard. The camera is not used: this component has no scanner. It finds today's booking by code or phone, asks which one when there are several, says so when the person is too early, and offers a walk-in ticket.

When to use

  • Patients check themselves in.
  • A scanner or a keypad is the only input.

When not to use

  • Booking a new visit: use BookingFlow.

Import

import { CheckInRequest, CheckInResult, CheckInKiosk } from "@fadymondy/nasaq/web";
// inside this monorepo: "@nasaq/web"

Quick start

import { CheckInKiosk } from "@fadymondy/nasaq/web";

<CheckInKiosk
  bookings={todaysBookings}
  onCheckIn={async (request) => {
    const entry = await api.checkIn(request);
    return { entry, position: 3, waitMinutes: 20 };
  }}
/>

Anatomy

CheckInKiosk                  data-slot="check-in-kiosk"
├─ mode tabs                  scan a code, or phone
├─ code field or keypad
├─ result: choose one, too early, not found
└─ ticket                     queue number, QR, position, wait, reset countdown

API

Every div prop is passed through unless noted.

PropTypeDefaultDescription
bookingsKioskBooking[]requiredToday's bookings for this desk.
onCheckIn(request) => Promise<CheckInResult | { error }>requiredPut the person in the queue.
allowWalkInbooleantrueLet people without a booking join.
earlyMinutes, windowMinutesnumber60, 240How early is allowed; how far from now a booking counts.
resetSecondsnumber20Seconds the ticket stays. 0 keeps it.
defaultMode"scan" | "phone""scan"Start tab.
nownumberEpoch ms for stories.
labelsPartial<CheckInKioskLabels>Override any string.

Examples

Ticket QR

// The ticket QR holds queue:A-012, which parseTicketValue reads back.

Accessibility

  • Keys are real buttons at a touch size. Results are announced in a status region.
  • The countdown to reset is stated in text so it can be paused by tapping.

RTL & i18n

  • The keypad stays in phone order (left to right) in Arabic, as phones do.
  • Strings live in a STRINGS = { en, ar } object and any of them can be replaced with labels. The locale comes from NasaqProvider.

Styling & tokens

  • Colours, radii and type come from --nq-* tokens; nothing is a raw colour. Spacing and alignment use logical classes.
  • Target [data-slot="check-in-kiosk"] and the inner data-slot parts shown in the anatomy.

Do / Don't

  • Do keep the async callbacks honest: return { error } so the component can show the message.
  • Do pass now in tests and stories so the output stays the same.
  • Don't fetch inside the component: it is presentational and takes data and callbacks.
  • Don't rely on colour for state: every state also has a word.

Lab

https://docs.nasaqui.com/?path=/docs/components-bookings-check-in-kiosk--docs

On this page