restaurant

Restaurant reservation site with party-size bookings, dining experiences, and Stripe checkout

resto payload reserve demo
1 / 2
resto payload reserve demo

Overview

Summary generated from the README

A fine dining restaurant site built with Payload CMS, Next.js App Router and MongoDB, using the payload-reserve plugin for table reservations. Guests pick a dining experience, space, date and time, and party size, then pay through Stripe Checkout. It includes menu, wine list, team and testimonial collections, English and French locales, and seed data. Requires MongoDB, Stripe CLI and Node 20.9 or newer.

Features

  • payload-reserve plugin configured for experiences, tables, schedules and reservations
  • Custom party size field from 1 to 20 on each reservation
  • Four-hour cancellation notice and 15-minute table turnover buffer
  • Collections for menu, wine list, chef team, dining spaces, announcements and testimonials
  • Stripe webhook handler and a task that cancels stale unpaid bookings
  • English and French routing with next-intl, plus seed script, Vitest and Playwright tests

Good for

  • Building a restaurant website with online table reservations and prepaid dining experiences
  • Learning how to extend payload-reserve with custom reservation fields and cancellation rules
  • Starting a booking site for venues with multiple spaces and seating capacities

From the author

Le Jardin Dore — payload-reserve demo: table reservations, dining experiences, party sizes

Get started

npx giget@latest gh:elghaied/payloadreserve-demos/apps/restaurant my-app

README

Le Jardin Dore — payload-reserve Demo

Live: restaurant.payloadreserve.com

A restaurant reservation app built with Payload CMS 3.x + Next.js 15 (App Router). Demonstrates party-size bookings, custom reservation fields, and short-notice cancellation — a fine dining experience where guests choose dining experiences in specific spaces.

Part of the payload-reserve-demos monorepo.


What This Demo Shows

ConceptImplementation
Custom reservation fieldspartySize (1–20) added via extraReservationFields
Short cancellation window4-hour notice period (same-day bookings friendly)
Table turnover buffer15-minute gap between seatings for cleanup
Rich content collectionsFull menu, wine list, chef team, and dining spaces
Space-based booking5 distinct dining areas with different capacities and ambiance

Tech Stack

LayerTechnology
FrameworkNext.js 15 (App Router, React 19)
CMS / APIPayload CMS 3.x
DatabaseMongoDB (via @payloadcms/db-mongodb)
Pluginpayload-reserve
PaymentsStripe Checkout
i18nnext-intl (English + French)
StylingTailwind CSS v4
TestingVitest (integration) + Playwright (e2e)

Prerequisites

  • Node.js >=20.9.0
  • pnpm >=10
  • MongoDB running locally
  • Stripe CLI installed (for webhook forwarding)

Quick Start

# From monorepo root
pnpm install
cp apps/restaurant/.env.example apps/restaurant/.env   # Fill in your values
cd apps/restaurant && pnpm seed                         # Seed sample data
pnpm dev:restaurant                                     # From root, or: cd apps/restaurant && pnpm dev

Project Structure

apps/restaurant/src/
├── app/
│   ├── (frontend)/[locale]/        # Public-facing pages
│   │   └── book/                   # Booking flow (experience → space → date/time → party size)
│   ├── (payload)/                  # Payload admin panel + REST/GraphQL API routes
│   └── api/stripe-webhook/         # Stripe checkout.session.completed handler
├── collections/
│   ├── Users.ts                    # Admin users
│   ├── Media.ts                    # Image uploads
│   ├── Menu.ts                     # Menu items (5 sections: starters, seafood, mains, cheese, desserts)
│   ├── Team.ts                     # Chef & kitchen staff profiles
│   ├── WineList.ts                 # Wine pairings by section
│   ├── Spaces.ts                   # 5 dining areas (intimate, classic, family, private, terrace)
│   ├── Announcements.ts            # Specials and seasonal events
│   └── Testimonials.ts             # Guest reviews
├── globals/                        # Homepage, SiteSettings
├── seed/
│   ├── index.ts                    # Main seed script
│   ├── dining-experiences.ts       # 5 experiences ($55–$200, 90–180 min)
│   ├── tables.ts                   # Tables per space with capacities
│   ├── schedules.ts                # Table/space availability
│   ├── menu.ts                     # Full 5-course French menu
│   ├── wine-list.ts                # Wine pairings
│   ├── team.ts                     # Chef Laurent, Sophie, Pierre
│   ├── spaces.ts                   # 5 dining spaces
│   ├── testimonials.ts             # Sample reviews
│   └── images.ts                   # Restaurant interior, dishes, staff
├── tasks/
│   └── cancelStaleReservations.ts  # Auto-cancel unpaid bookings
├── i18n/                           # next-intl routing config
├── payload.config.ts               # Main config — plugin, collections, jobs
└── payload-types.ts                # Auto-generated types

Plugin Configuration

payloadReserve({
  slugs: {
    services: 'dining-experiences',
    resources: 'tables',
    schedules: 'schedules',
    reservations: 'reservations',
  },
  defaultBufferTime: 15, // minutes — table turnover
  cancellationNoticePeriod: 4, // hours — same-day friendly
  extraReservationFields: [
    {
      name: 'partySize',
      type: 'number',
      min: 1,
      max: 20,
      defaultValue: 2,
    },
  ],
})

payload-reserve Collections

SlugDescription
dining-experiencesDining options with price, duration, and description
tablesTables/spaces linked to dining experiences
schedulesAvailability per table/space
reservationsBooking records with partySize custom field
customersGuest records (separate from admin users)

Seed Data

Dining Experiences

ExperiencePriceDuration
Classic Lunch$5590 min
Tasting Menu$120150 min
Chef's Table$150180 min
Wine Pairing Dinner$140150 min
Private Dining$200180 min

Dining Spaces

SpaceAmbiance
Le Coin IntimeIntimate (2–4 guests)
La Salle ClassiqueClassic fine dining
Le Salon FamilialFamily-friendly
Le Salon PrivePrivate dining room
La TerrasseOutdoor terrace

Team

  • Chef Laurent Beaumont — Head Chef
  • Sophie Marchand — Sous Chef
  • Pierre Delacroix — Pastry Chef

Commands

# From monorepo root
pnpm dev:restaurant          # Start dev server
pnpm build:restaurant        # Production build

# From apps/restaurant/
pnpm dev                     # Start dev server
pnpm devsafe                 # Wipe .next cache + dev
pnpm seed                    # Seed database
pnpm test                    # Run all tests
pnpm test:int                # Vitest integration tests
pnpm test:e2e                # Playwright e2e tests

URLs

URLDescription
http://localhost:3003Frontend (defaults to /en)
http://localhost:3003/frFrench locale
http://localhost:3003/adminPayload admin panel
http://localhost:3003/apiPayload REST API

More Business & agency templates

hotel screenshot

hotel

Hotel booking site with room pools, multi-night date-range reservations and Stripe checkout

0
v3
Next.js
Updated 2 months ago
events screenshot

events

Event ticketing and venue booking app built on Payload, Next.js and the payload-reserve plugin

0
v3
Next.js
Updated 2 months ago
salon screenshot

salon

Salon booking app with specialists, schedules, Stripe payments and English and French localization

0
v3
Next.js
Updated 2 months ago