Booking Calendar UI (PL-T191)
I korthet
The operator's primary planning surface for chain venues — a day/week/month booking calendar with multi-resource swim-lanes, color-coded type chips drawn from booking tokens, drag-and-drop reschedule and resize, real-time SSE updates with sub-second repaint, optimistic edits with 409-revert and toast, a month-view utilization heatmap, URL-driven view state for deep-linking and bookmarks, keyboard navigation, and a BookingDetailDrawer with inline confirm/check-in/cancel actions.
Så fungerar det
The calendar is a swim-lane grid where each row is a BookableResource and each column is a time slice (15 min for day view, 1 h for week view, 1 day for month view). Bookings render as type-colored chips drawn from the booking-color tokens — court_play green, table_dining warm, event_corporate blue, etc. — so an operator can read the day at a glance. Drag-and-drop reschedules a booking to a new time or moves it to a different resource; resize handles change duration.
On drop the front-end writes optimistically and PATCHes the booking. If the server returns 409 (conflict) the chip snaps back and a toast explains why; otherwise the new state is confirmed by the server response. Real-time updates flow from /chain/bookings/stream SSE — when another operator confirms, cancels, or moves something, every connected calendar repaints within a few hundred milliseconds.
URL-driven view/date/location/resource_type means a deep-link or bookmark restores exactly the same configuration, and the keyboard shortcuts (← → to step, t for today, Esc to clear selection) keep the operator's hands off the mouse. The month view overlays a green-alpha utilization heatmap (8% to 50% saturation) so a manager can spot under-booked Mondays at a glance. Clicking a chip opens BookingDetailDrawer — a side-panel with confirm, check-in, cancel, modify, and message-customer buttons inline.
The drawer is the same component used in the operator console, so muscle memory transfers across surfaces.
Centrala funktioner
- Day / week / month grid with multi-resource swim-lanes
- Drag-and-drop reschedule + resize with optimistic 409-revert
- Color-coded type chips from booking-color tokens
- Real-time SSE updates with sub-second repaint
- Month-view utilization heatmap (8%–50% green alpha)
- Keyboard nav (← → t Esc) + URL-driven view state
- BookingDetailDrawer with inline confirm/check-in/cancel
I praktiken
Monday morning the venue manager opens Calendar at /calendar?view=week&date=2026-04-27. The week renders with all eight lanes as rows. She spots a corporate group on Lane 3 Wednesday 18:00-20:00 that should really be on adjacent lanes 5-6 for a better atmosphere.
She drags the chip from Lane 3 onto Lane 5 — the chip moves optimistically, the PATCH returns 200, the change broadcasts on SSE, and the front-of-house tablet behind the bar updates simultaneously. She switches to month view and sees a pale-green Monday on the heatmap; clicking it drills back to that day's swim-lanes — only 12% utilization, so she schedules a Monday-night promotion via the marketing automation system to lift it.
Features i detta subsystem
9| ID | Status | Funktioner |
|---|---|---|
| F22.09.01 | Levererad | Day / week / month grid with multi-resource swim-lanes ✅ |
| F22.09.02 | Levererad | Drag-and-drop reschedule + resize ✅ |
| F22.09.03 | Levererad | Color-coded booking-type chips (booking-colors.mjs tokens) ✅ |
| F22.09.04 | Levererad | Real-time updates via SSE (/chain/bookings/stream) ✅ |
| F22.09.05 | Levererad | Month-view utilization heatmap (8% – 50% green alpha) ✅ |
| F22.09.06 | Levererad | Optimistic update + 409 revert with toast ✅ |
| F22.09.07 | Levererad | Keyboard nav (← → t Esc) ✅ |
| F22.09.08 | Levererad | URL-driven view/date/location/resource_type ✅ |
| F22.09.09 | Levererad | BookingDetailDrawer — confirm / check-in / cancel inline ✅ |