Song Siwattanasombat

Loading portfolio

Back to projects

An online school facility booking platform that centralises facility discovery, availability, reservations, payments, and booking history.

  • Next.js 16
  • React 19
  • TypeScript
  • Tailwind CSS 4
  • Sanity
  • NextAuth.js
  • Stripe
  • Vitest
  • Playwright
  • Vercel

Facility Booking Platform is a portfolio demonstration for students, staff, community members, and administrators. It combines facility discovery, availability, fixed-slot reservations, Stripe payments, booking history, and content management in one workflow.

Core Requirements

  • Facility search
  • Authentication
  • Availability checks
  • Duplicate protection
  • Stripe payments
  • Booking history
  • Admin content

The booking rules are fixed and visible so availability remains predictable.

  • Users can search facilities, check capacity and availability, then review booking and payment history.
  • Email/password and OAuth authentication protect bookings; Sanity Studio protects administration.
  • Three daily slots run at 09:00–12:00, 14:00–17:00, and 18:00–21:00 in Australia/Sydney time.
  • A pending booking holds a slot for 31 minutes while duplicate reservations are blocked.
  • Sanity, Stripe, and OAuth credentials are required; this is not an official school platform.

From Planning to Deployment

  1. 1Requirements and User Flows
  2. 2Data Structure and UI Design
  3. 3Next.js and TypeScript Development
  4. 4Connect Sanity, NextAuth, and Stripe
  5. 5Add Validation and Booking Protection
  6. 6Vitest and Playwright Testing
  7. 7Fix Bugs and Mobile Layout
  8. 8Deploy to Vercel

Development progressed from requirements to integration, validation, testing, and deployment.

Booking Journey

Browse or search facilities
Select a facility
Signed in?

No

Sign in or create an account

↩ Return to Select a facility

Yes

Select date, time, and attendees
Check capacity and availability
Slot available?

No

↩ Return to Select date, time, and attendees

Yes

Create pending booking · 31-minute hold
Open Stripe Checkout
Payment result

Expired or failed

Delete pending booking

Paid

Stripe webhook confirms booking
Display in My Bookings

Capacity and availability are checked before a 31-minute hold; only a signed Stripe webhook confirms the booking.

The core stack keeps application code, data models, and content management in one workflow.

  • Next.js 16 and React 19 combine pages, components, and route handlers in one codebase.
  • TypeScript catches errors across booking, user, and payment states.
  • Tailwind CSS 4 provides responsive styling and dark mode without a fixed component theme.
  • Sanity and GROQ provide structured data and a ready-made administration Studio.

Managed services reduce security-sensitive custom code and deployment work.

  • NextAuth handles credentials, Google OAuth, sessions, and protected routes.
  • Stripe Checkout reduces card-data handling and confirms payment through signed webhooks.
  • Vitest covers unit logic; Playwright checks real flows and viewport sizes.
  • Vercel supports Next.js previews, environment variables, and serverless deployment.

Architecture Map

User Browser
Next.js App RouterPages and Components

App Router connects authentication and backend routes

NextAuthAuthentication and Session
Next.js Route Handlers

Route Handlers →

Sanity CMSFacilities, Users, Bookings

↩ Returns data to Next.js

Route Handlers →

Stripe Checkout
Signed Stripe Webhook

↩ Returns to Route Handlers

Administrator
Protected Sanity Studio

Sanity Studio connects to NextAuth and Sanity CMS

Next.js route handlers coordinate NextAuth sessions, Sanity data, and Stripe checkout and webhooks.

The main risks were time accuracy, booking conflicts, payment trust, and reliable navigation.

  • Sydney booking times are converted to UTC before storage to handle daylight saving.
  • Conflict checks, deterministic slot IDs, and expired-hold cleanup prevent duplicate bookings.
  • Signed Stripe webhooks protect status changes; callback URLs return users after sign-in.
  • Responsive styling prevents mobile horizontal overflow.

Test Results

  • 9/9 Playwright checks
  • 3/3 Vitest tests
  • 0 console issues
  • Desktop verified
  • Mobile verified

Automated and browser checks passed for the implemented portfolio scope.

  • Playwright smoke checks: 9/9 passed with no console issues; Vitest: 3/3 passed.
  • Desktop 1600×900 and mobile 390×844 showed no overflow; dark mode, search, validation, empty states, and auth redirects worked.
  • Real login, Google OAuth, booking confirmation, and payment were not tested because they require accounts and may create external data.
  • Session loading causes a small layout shift, and mobile navigation still needs a hamburger menu.

Production readiness requires broader testing, a complete booking lifecycle, and stronger operations tooling.

  • Add reusable end-to-end tests and GitHub Actions beyond the current three unit tests.
  • Support cancellations, refunds, notifications, and recurring bookings.
  • Add an operations dashboard and usage reports beyond Sanity Studio.
  • Update dependencies and automate security checks for Sanity, Stripe, and OAuth integrations.