Customer Booking Flow on Tenant CMS (PL-T189)
En bref
The customer-facing booking wizard rendered on each tenant's CMS. A mobile-first multi-step flow translated into sv/en/fr/de/es with cookie override, tenant-branded via ChainWhiteLabelConfig, offline-resilient via service-worker stale-while-revalidate caching of tenant-config, resources and menu, with real-time slot-collision nudges over SSE, idempotent submits keyed by crypto.randomUUID, an upsell-prompts step driven by menu packages, and a confirmation page with ICS export and share button.
Comment ça fonctionne
The wizard ships as a tenant-CMS module, rendering through ChainWhiteLabelConfig so the operator's logo, brand color, and typography are applied via a ThemeProvider. The flow is multi-step (date → time → resource → party → upsell → contact → confirm), mobile-first by default but adapts gracefully to tablet and desktop. Multi-language support covers sv/en/fr/de/es out of the box plus a cookie override so a French visitor on a Swedish tenant CMS still gets French.
A service worker caches tenant-config, resources, opening hours, and the menu using stale-while-revalidate so a customer on patchy 4G can browse and almost-complete a booking offline — only the final submit needs network. While the user is on the time-picker step, the page subscribes to /chain/bookings/stream SSE so a slot taken by someone else turns red in real time and the customer is nudged to pick again before they hit submit. At checkout the upsell-prompts step reads from menu-package rules and offers relevant bundles.
The submit uses crypto.randomUUID() as the idempotency key so retries from a frozen tab can't double-book. On success, the confirmation page renders an ICS export the customer can drop into their calendar plus a share button that posts a deep link to messaging apps. The whole flow tracks BookingFunnelEvent rows for analytics so operators can see drop-off per step.
Capacités clés
- Multi-step mobile-first wizard with tablet/desktop responsive
- Multi-language (sv/en/fr/de/es) + cookie override
- Tenant-branded ThemeProvider via ChainWhiteLabelConfig
- Service-worker stale-while-revalidate for offline browse
- Real-time slot conflicts via SSE during time-picker step
- Idempotent submit with crypto.randomUUID + upsell-prompts step
- Confirmation with ICS export + share button
En pratique
On a rainy Friday afternoon a customer opens petanque-bar-malmo.se on their phone during a slow tram ride. The service worker has cached yesterday's resource and menu data so the wizard renders instantly even before the page finishes loading. They pick Saturday 19:00 for two on Lane 4.
Halfway through the contact step a friend's booking takes the same slot — the page nudges with a red banner and offers 19:30 as a one-tap swap. They accept, add a charcuterie sharing board from the upsell prompt (which the wizard surfaces because party-size = 2 matches the package's min-party-size), pay with Apple Pay through Stripe, and download the ICS to their calendar. Twelve hours later they walk in, the operator sees them in the upcoming-arrivals strip, and check-in is one tap.
Fonctionnalités de ce sous-système
8| ID | Status | Fonctionnalités |
|---|---|---|
| F22.07.01 | Livré | Multi-step booking wizard, mobile-first ✅ |
| F22.07.02 | Livré | Multi-language flow (sv/en/fr/de/es + cookie override) ✅ |
| F22.07.03 | Livré | Upsell prompts at checkout (consumes menu packages) ✅ |
| F22.07.04 | Livré | Tenant-branded ThemeProvider via ChainWhiteLabelConfig ✅ |
| F22.07.05 | Livré | Service-worker stale-while-revalidate for tenant-config / resources / menu ✅ |
| F22.07.06 | Livré | Real-time slot conflict via SSE on bookings.stream ✅ |
| F22.07.07 | Livré | Idempotent booking submit with crypto.randomUUID key ✅ |
| F22.07.08 | Livré | Confirmation page with ICS export and share button ✅ |