Skip to content

Repository files navigation

Menu Manager 🚀

A SaaS platform that lets coffee shops and restaurants create a digital menu, get a QR code, and let customers view the menu online by scanning the code — Next.js 16 · NestJS 11 · PostgreSQL · Drizzle ORM.

Menu Manager screenshot

✨ Features

  • Instant Digital Menus — Create categories and menu items with photos, prices, and descriptions from a simple dashboard.
  • 📱 Public Menu Pages — Mobile-first, server-rendered store pages at /store/[slug] that look great on any device.
  • 🧾 Smart QR Codes — Generate and download customizable QR codes (color, size) for every table, or copy the menu link.
  • 👁️ View Analytics — Track unique views per device with bot filtering and rate limiting, straight from the dashboard.
  • 🖼️ Store Profile — Upload a logo, cover photo, and up to 10 gallery images for your public menu page.
  • 🔐 Merchant Auth — JWT-based signup/login (Passport) with protected dashboard routes.
  • 🎨 Modern UI — shadcn/ui on Tailwind v4, dark mode, and a warm, conversion-optimized landing page.

🛠️ Tech Stack

Layer Tech
Frontend Next.js 16 (App Router, TypeScript)
UI shadcn/ui (Radix + Tailwind v4)
Client State Zustand
Server State TanStack Query
Forms React Hook Form + Zod
Backend NestJS 11 (TypeScript)
Database PostgreSQL
ORM Drizzle ORM
Auth JWT (Passport)
Images Cloudinary

🚀 Getting Started

Prerequisites

  • Node.js 20+
  • npm 10+
  • PostgreSQL 15+

Installation

git clone <repo-url> menu-manager
cd menu-manager
npm install

This installs dependencies for both frontend/ and backend/ via npm workspaces.

Configuration

Create backend/.env:

DATABASE_URL=postgresql://postgres:postgres@localhost:5432/menu_manager
JWT_SECRET=your-secret-key-change-this
JWT_EXPIRES_IN=7d
CLOUDINARY_CLOUD_NAME=your-cloud-name
CLOUDINARY_API_KEY=your-api-key
CLOUDINARY_API_SECRET=your-api-secret
PORT=4000
Variable Description
DATABASE_URL PostgreSQL connection string
JWT_SECRET Secret used to sign JWT tokens
JWT_EXPIRES_IN Token lifetime (e.g. 7d)
CLOUDINARY_CLOUD_NAME Cloudinary account (image uploads)
CLOUDINARY_API_KEY Cloudinary API key
CLOUDINARY_API_SECRET Cloudinary API secret
PORT Backend port (default 4000)

Note: Cloudinary is optional for local development — auth and menu CRUD work without it, but image upload will fail until you add credentials.

Create frontend/.env.local:

NEXT_PUBLIC_API_URL=http://localhost:4000/api
Variable Description
NEXT_PUBLIC_API_URL Backend API base URL

Then push the database schema (creates merchants, categories, menu_items, and qr_codes tables):

npm run db:push

Run

npm run dev

📜 Scripts

npm run dev            # start backend + frontend together
npm run dev:backend    # backend only (watch mode)
npm run dev:frontend   # frontend only
npm run build          # production build for both
npm run db:push        # push schema to database
npm run db:generate    # generate SQL migration files
npm run db:studio      # open Drizzle Studio (GUI DB viewer)

📁 Project Structure

Menu-manager/
├── frontend/                    # Next.js 16 App Router
│   └── src/
│       ├── app/                 # pages (landing, auth, dashboard, store)
│       ├── components/          # shadcn/ui + landing components
│       ├── hooks/               # TanStack Query hooks
│       ├── stores/              # Zustand stores
│       ├── providers/           # React providers
│       └── lib/                 # API client, utilities
├── backend/                     # NestJS 11 API
│   └── src/
│       ├── auth/                # signup, login, JWT
│       ├── menu/                # categories & menu items CRUD
│       ├── profile/             # store profile, logo, cover, gallery
│       ├── qr/                  # QR code generation & download
│       ├── store/               # public menu & view tracking
│       ├── upload/              # Cloudinary image upload
│       └── drizzle/             # schema & DB connection
├── .claude/                     # agent configs & plans
└── package.json                 # root workspace

☁️ Deployment

The monorepo is build-ready with npm run build. The backend (NestJS) and frontend (Next.js) deploy as separate services, both requiring their .env variables above — set DATABASE_URL, JWT_SECRET, and Cloudinary credentials on the backend, and NEXT_PUBLIC_API_URL on the frontend.

📄 License

MIT

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages