BookingManage
A patient's own booking page - QR ticket with code, add to calendar, reschedule in a dialog and cancel with the late fee stated, all following a cancel and reschedule policy.
Code
import { BookingManage } from "@fadymondy/nasaq/web";<BookingManage booking={booking} policy={{ cancelHours: 24, lateFeePercent: 50 }} getSlots={() => api.slots(booking)} onReschedule={(start) => api.reschedule(booking.id, start)} onCancel={() => api.cancel(booking.id)}/>Bookings · beta
Live examples and controls: BookingManage in the lab.
Install
npx shadcn@latest add https://docs.nasaqui.com/r/booking-manage.jsonWhat the patient sees after booking and when they come back to change it. BookingTicket is the ticket on its own: a QR that holds booking:CODE, the code as text, the details, a .ics download and a Google Calendar link.
When to use
- A booking confirmation page or a manage link in an email.
- Enforcing a cancellation window and a late fee.
When not to use
- Staff tools: use BookingPipeline.
- Booking for the first time: use BookingFlow.
Import
import { BookingTicket, BookingManage } from "@fadymondy/nasaq/web";
// inside this monorepo: "@nasaq/web"Quick start
import { BookingManage } from "@fadymondy/nasaq/web";
<BookingManage
booking={booking}
policy={{ cancelHours: 24, lateFeePercent: 50 }}
getSlots={() => api.slots(booking)}
onReschedule={(start) => api.reschedule(booking.id, start)}
onCancel={() => api.cancel(booking.id)}
/>Anatomy
BookingManage data-slot="booking-manage"
├─ BookingTicket QR, code, details, calendar links
├─ policy text
├─ Reschedule button opens a Dialog with BookingSlots
└─ Cancel button ConfirmButton; the fee is stated firstAPI
Every div prop is passed through unless noted.
| Prop | Type | Default | Description |
|---|---|---|---|
booking | BookingRecord | required | The booking shown. |
policy | { cancelHours, rescheduleHours?, lateFeePercent? } | required | Free cancellation window, reschedule window and the late fee. |
getSlots | (booking) => Promise<BookingSlot[]> | required | Times to move to, called when the dialog opens. |
onReschedule | (start) => Promise<void | { error? }> | required | Move the booking. |
onCancel | () => Promise<void | { error? }> | required | Cancel it. |
now | Date | the clock | For stories and tests. |
labels | Partial<BookingManageLabels> | Override any string. |
Examples
The ticket alone
import { BookingTicket } from "@fadymondy/nasaq/web";
<BookingTicket booking={booking} />Accessibility
- The QR has an accessible name and the code is also plain text.
- Cancel names the fee before the patient confirms.
- Buttons that the policy disables say why in text.
RTL & i18n
- Codes and phone numbers are left to right; the dialog and buttons mirror.
- Strings live in a
STRINGS = { en, ar }object and any of them can be replaced withlabels. The locale comes fromNasaqProvider.
Styling & tokens
- Colours, radii and type come from
--nq-*tokens; nothing is a raw colour. Spacing and alignment use logical classes. - Target
[data-slot="booking-manage"]and the innerdata-slotparts shown in the anatomy.
Do / Don't
- Do keep the async callbacks honest: return
{ error }so the component can show the message. - Do pass
nowin 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.
Related
Lab
https://docs.nasaqui.com/?path=/docs/components-bookings-booking-manage--docs
BookingFlow
Online booking flow with branch, service, doctor with ratings, day and time grid, guest or signed-in details, notes and files, payment choice, review and a QR ticket confirmation.
BookingPipeline
Staff status pipeline for a booking - requested, confirmed, checked in, in visit and done, with next-action buttons, confirm on no-show and cancel, and a timeline of every move.