Three-step bus booking flow for routes across Nigeria — React 19, TypeScript, Vite
# NaijaBus — Bus Booking
A three-step bus booking flow for routes across Nigeria, built with React 19, TypeScript
and Vite. Originally a vanilla HTML/CSS/JS prototype (kept under `legacy/`),
now rewritten as a typed component tree with a single reducer driving the flow.
## Flow
1. **Trip** — pick departure city, destination, travel date and seat count, then choose a bus.
2. **Passenger** — details for every seat, plus a next-of-kin emergency contact.
3. **Payment** — review the booking, see the total, and pay.
4. **Confirmation** — booking reference and ticket summary.
## Getting started
```bash
npm install
npm run dev
```
| Script | Purpose |
| ------------------- | ---------------------------------------- |
| `npm run dev` | Vite dev server with HMR |
| `npm run build` | Typecheck and build to `dist/` |
| `npm run preview` | Serve the production build locally |
| `npm run typecheck` | Typecheck only |
| `npm run lint` | ESLint (type-aware, strict) |
## Project layout
```
src/
├── domain/ Booking rules: catalog data, trip validation, fare calculation
├── state/ bookingReducer — the whole flow as one state machine
├── components/ Presentation, with one component per step under steps/
├── lib/ Currency/date formatting and select-option narrowing
└── styles/ Global stylesheet
```
Business rules live in `src/domain` and are independent of React:
- `catalog.ts` — cities, buses, seat counts and the other option lists, each also the
source of its literal type.
- `booking.ts` — `TripDraft` (may be blank) versus `TripSelection` (validated). Steps 2
and 3 only ever receive a `TripSelection`, so they cannot be rendered with a
half-filled trip.
- `fares.ts` — route fares keyed by an order-independent city pair, so each route is
priced once for both directions.
## Real payment gateway
The "Pay now" button …