End-to-end demo app where users explore travel experiences, pick slots, and complete bookings.
- Frontend: TBA (deploy on Vercel)
- Backend API: TBA (deploy on Render/Railway)
- Frontend: React + TypeScript + Vite, TailwindCSS, React Router, Axios
- Backend: Node.js + Express (ESM), TypeScript, Mongoose, MongoDB
Prereqs: Node 18+, MongoDB (local or Atlas), pnpm or npm.
- Clone and install
# from repo root
cd server; npm install; cd ..
cd client; npm install; cd ..- Configure database
Create a MongoDB database (local or Atlas) and set the connection string in server/.env:
PORT=4000
HOST=127.0.0.1
CORS_ORIGIN=http://localhost:5173
MONGODB_URI="mongodb://127.0.0.1:27017/bookit"- Seed data
# from server/
npm run seed- Run both apps
# terminal A
cd server; npm run dev
# terminal B
cd client; npm run devOpen http://localhost:5173 and test the flow:
- Home → Details → Checkout → Result
- Try promo codes:
SAVE10,FLAT100,OFF5 - Try to book a nearly sold-out slot twice to see the Sold Out error.
- GET /experiences
- GET /experiences/:id (includes
slots) - POST /promo/validate { code }
- POST /bookings { slot_id, user_name, user_email, promo_code }
- Backend: Render or Railway (Node + MongoDB). Set envs and run
npm run seedonce. - Frontend: Vercel (Vite). Set
VITE_API_BASE_URLto your backend URL.
- Atomic sold-out check uses a single conditional findOneAndUpdate with $inc to prevent double-booking.
- Prices are stored as numbers; frontend handles display to two decimals.
- The Tailwind theme is minimal; tune colors/fonts to match Figma exactly in
client/tailwind.config.js.