React Ticketing Template
The react-ticketing template is a React + Vite application built around the most distinctive piece of the Theatrical stack: the event bridge. It runs a simulated cinema whose state genuinely changes — seats sell, sessions sell out, orders confirm — and the real BookingWatcher and SessionWatcher from the published @theatrical/events package poll it, diff it, and emit the typed event stream that drives the UI.
Three pages: programme → seat selection → confirmation.
Quick start
-
Scaffold the project
Terminal window npx @theatrical/cli init my-cinema --template react-ticketingcd my-cinema -
Run locally
Terminal window npm installnpm run devThe app is fully self-contained — no API key, no environment configuration. Open http://localhost:5173.
-
Deploy to Vercel
Terminal window npx vercel --prodThe included
vercel.jsonsets up SPA routing for React Router.
Application structure
Directorysrc/
- App.tsx (router + home programme grid)
- theme.ts (design tokens)
Directorylib/
- cinema.ts (the living cinema — simulated state + real event watchers)
- responsive.ts
Directorypages/
- Seats.tsx (seat map + selection)
- Confirmation.tsx (booking confirmation)
Directorycomponents/
- Chrome.tsx
- Poster.tsx
- Timeboard.tsx
- MissionControl.tsx
- CodeSeam.tsx
- index.html
- vercel.json
- .env.example
Routes: / (programme) → /book/:sessionId (seats) → /done (confirmation).
How the event bridge is wired
src/lib/cinema.ts runs a deterministic simulation (LiveCinema) that mutates session and order state over time. The watchers from @theatrical/events observe it exactly the way they would observe a real cinema platform API:
LiveCinema state ──poll──▶ BookingWatcher ──diff──▶ booking.confirmed SessionWatcher ──diff──▶ session.soldout │ typed event stream ──▶ UIThe watchers are the published package, unmodified. The timeboard and mission-control surfaces subscribe to the stream — the interface listens to the pulse, not the photo.
Customisation
Theming
The design tokens live in src/theme.ts — colours, type scale, and spacing for the whole app. Edit them directly; every component reads from the shared T object.
Pointing at a real platform
To drive the same UI from a real cinema platform API, replace the LiveCinema simulation in src/lib/cinema.ts with @theatrical/sdk calls — the watchers accept any poll function that returns order and session snapshots.