All work

Jungleland

Timed-slot booking and deposits for a children's play centre

Visit junglelandbooking.com
  • Real customers, real payments
  • Multi-step flow that survives a refresh
  • Staff-managed dates and capacity

Jungleland is a children's play centre in Telford. Until 2021 it had no booking system at all — families simply turned up. Social distancing ended that: entry had to be capped per session, so the whole thing had to be built from nothing. Timed slots with hard capacity limits, a deposit taken at the point of booking, and a way for staff to open and close dates themselves without calling me.

It has been running and taking bookings ever since.

The booking flow

A parent booking a party is usually doing it one-handed. The flow is deliberately linear — pick a date, pick a slot, pay a deposit, get a confirmation — and each step is its own route:

/book
  → /book/[date]
    → /book/[date]/[timeslot]
      → /deposit/[id]
        → /confirmation/[id]

Booking state lives in a Pinia store persisted to localStorage, so a half-finished booking survives a refresh, a backgrounded tab, or a phone that decides to lock mid-payment. That single decision removed the most common support complaint from the first version.

Capacity is the hard part

Everything else follows from not overselling a slot. The data model is deliberately narrow — Date → TimeSlot → Booking in AppSync/GraphQL over DynamoDB — with capacity held on the timeslot rather than derived at read time. Abandoned bookings expire on their own through DynamoDB TTLs rather than needing a cleanup job, so a parent who bails at the payment step releases their slot without anyone intervening.

Payments and mail

Deposits go through Stripe, with the checkout session created server-side in a Nitro route so no key is ever exposed to the client. Confirmations are sent through AWS SES. Both are boring, on purpose — this is somebody's actual revenue.

Admin

Staff get a JWT-authenticated admin area to create bookable dates, set slot capacity, and see what has been booked. It is intentionally plain: the people using it are running a play centre, not learning software.

What I'd change

The repo has no automated tests and no linting — it grew from something built quickly under a reopening deadline and never had that debt paid down. If I picked it up again today, capacity logic is the first thing I'd put under test, because it is the part that costs real money when it is wrong.