• English
  • salon-booking-ui — Quickstart

    SalonCloud Online Booking Frontend is a consumer-facing single-page application (SPA) that lets customers self-book hair salon appointments. It is a pure frontend — there are no backend secrets, all sensitive operations happen on a separate backend API. The UI protects against abuse using Proof-of-Work (PoW) + email/SMS OTP, relying on the backend for rate limiting.


    What This Repo Contains

    AreaDescription
    Booking wizard6-step appointment flow: pick services → pick time → hold slot → verify identity → enter OTP code → confirmation
    Manage pageToken-gated self-service page for viewing, cancelling, and rescheduling existing bookings
    PoW engineBackground Web Worker that solves SHA-256 hashcash challenges before API calls
    Slot pickerDate/time picker with day chips, calendar drawer, and automatic "next available" probing
    i18nEnglish and Traditional Chinese (zh-TW), runtime switchable

    Tech Stack

    CategoryTechnology
    FrameworkReact 18 + TypeScript 5
    Build toolVite 6
    RoutingReact Router v6
    StylingTailwind CSS (minimal black-and-white theme)
    Internationalizationreact-i18next / i18next (en, zh-TW)
    Date handlingdate-fns + date-fns-tz
    UI primitivesRadix UI, vaul (drawer), input-otp, lucide-react
    TestingVitest + React Testing Library + jsdom
    DeployCloudflare Workers via @cloudflare/vite-plugin + Wrangler
    Node requirement≥ 22.15 (enforced; the Cloudflare plugin requires module.registerHooks)

    Local Development

    # Install dependencies
    npm install
    
    # Start the dev server (proxies to a local backend on localhost:8080)
    npm run dev

    The backend can be run locally with Docker Compose. The OpenAPI spec is at GET /openapi/booking.json and Swagger UI is at /docs.

    Environment variable: Only one variable is needed:

    VariableDev valuePurpose
    VITE_BOOKING_BASE_URLhttp://localhost:8080Backend base URL (without /v1/book suffix)

    Committed env files cover all modes (.env.development, .env.uat, .env.production). For local overrides, create .env.local (gitignored).


    Running Tests

    npm test            # run all tests once
    npm run test:watch  # watch mode
    npm run typecheck   # TypeScript type check (no emit)

    Tests use Vitest + jsdom. The Cloudflare plugin and PWA plugin are automatically disabled when process.env.VITEST is set, so tests work on any Node version — only running the dev server or building requires Node ≥ 22.15.


    Routing

    PathPagePurpose
    /HomePageBranded landing page, no data fetching
    /:slugBookingPageFull booking wizard for a salon identified by slug
    /manage/:tokenManageRouteManagePageToken-gated booking management (view / cancel / reschedule)

    Important: manage is a reserved word — the backend must never assign it as a merchant slug, because /manage/:token and /:slug would otherwise collide.


    Where to Go Next

    TopicPage
    App layers, component hierarchy, key design patternsArchitecture
    Booking wizard steps, state machine, ManagePage actionsBooking Flow
    API endpoints, HTTP client, PoW, error codes, storage, i18nAPI & Data
    Build commands, deploy targets, Cloudflare Workers configOperations

    Key Source Locations

    WhatWhere
    App entry pointsrc/main.tsx, src/App.tsx
    Route definitionssrc/routes.tsx
    Booking wizardsrc/features/booking/BookingWizard.tsx
    Wizard state machinesrc/features/booking/useBookingMachine.ts
    Manage pagesrc/features/manage/ManagePage.tsx
    All API callssrc/lib/api/booking.ts
    HTTP client + errorssrc/lib/api/client.ts, src/lib/api/errors.ts
    PoW enginesrc/lib/pow/
    i18n stringssrc/i18n/en.json, src/i18n/zh-TW.json
    Build + deploy configvite.config.ts, wrangler.jsonc