A complete food delivery system built as a full-stack monorepo. Covers the customer ordering journey, admin back-office, cashier operations, inventory management, delivery tracking, and reporting β all powered by a Node.js REST API and a React frontend.
π Live Demo: food-delivery-nine-inky.vercel.app π¦ Repository: github.com/DangHuuLong/Food-Delivery
FoodDash is a full-stack food delivery platform designed to handle real-world operational complexity. It is structured as a monorepo containing the backend API, the frontend application, project documentation, and API testing collections.
The system supports four distinct user roles β customer, admin, cashier, and driver β each with their own application surface and access scope. The backend exposes a versioned REST API, and the frontend delivers a role-segmented multi-surface experience built for both desktop and mobile usage.
| Domain | Capability |
|---|---|
| π Authentication | Register, login, JWT auth, role-based access control |
| ποΈ Customer Storefront | Browse menu, view products, manage cart, place orders |
| π³ Checkout & Payment | Address selection, order placement, mock payment flow |
| π Delivery Tracking | Delivery assignment, GPS location, status transitions |
| π₯οΈ Admin Dashboard | KPIs, orders, products, users, inventory, reports |
| π§Ύ Cashier Workspace | POS, today's orders, order history, shift reports |
| π§ Inventory Management | Ingredients, stock entries, goods receipts, suppliers |
| ποΈ Promotions | Scheduled discounts with clone, pause, and cancel flows |
| ποΈ Staff Scheduling | Shift templates, weekly assignment schedule |
| π Reporting | Revenue timeseries, top items, order statistics |
Backend
- Production-ready REST API versioned under
/api/v1 - JWT authentication with per-request token verification
- Role-based access control across all protected routes
- Cart lifecycle with product price snapshots
- Order status state machine with validated transitions
- Delivery assignment and GPS tracking
- Inventory normalization with stock lot management
- Promotion scheduling with clone and pause support
- Cloudinary image uploads for products, categories, and promotions
- Strong input validation and business rule enforcement throughout
Frontend
- Mobile-first customer storefront (responsive down to small phones)
- Role-segmented routing with
RequireAuthguard - Redux Toolkit for cart, order, and toast state
- TanStack React Query for server-state fetching and caching
- Centralized popup orchestration system for ordering UX
- Dynamic Vietnamese province/district/ward address selector
- Data-driven admin interface with search, filters, and pagination
- Vercel SPA deployment with client-side routing support
| Layer | Technology |
|---|---|
| Runtime | Node.js (ES Modules) |
| Framework | Express.js |
| Database | MongoDB via Mongoose |
| Authentication | JSON Web Tokens (JWT) |
| Password Hashing | bcryptjs |
| File Uploads | Multer + Cloudinary |
| Dev Server | Nodemon |
| Concern | Technology |
|---|---|
| Framework | React |
| Build Tool | Vite |
| Routing | React Router |
| Server State | TanStack React Query |
| Client State | Redux Toolkit + React Redux |
| UI State | React Context |
| Styling | Tailwind CSS + CSS Modules |
| Icons | Lucide React |
| Tool | Purpose |
|---|---|
| Vercel | Frontend hosting with SPA rewrite |
| Cloudinary | Media asset storage and delivery |
| MongoDB Atlas | Managed cloud database |
| Postman | API testing collections (in-repo) |
| ESLint | Linting for React Hooks and Refresh |
ββββββββββββββββββββββββββββββββββββββββββββ
β React Frontend β
β (Vite Β· React Router Β· Redux Β· Query) β
β β
β Customer β Admin β Cashier β Auth β
ββββββββββββββββββββ¬ββββββββββββββββββββββββ
β HTTPS Β· Bearer Token
β fetch() β http() wrapper
βΌ
ββββββββββββββββββββββββββββββββββββββββββββ
β Node.js / Express API β
β REST Β· /api/v1 Β· CORS β
β β
β Route β Middleware β Controller β
β β Service β Model β MongoDB β
βββββββββββββββββ¬βββββββββββββββββββββββββββ
β
ββββββββββ΄βββββββββ
βΌ βΌ
MongoDB Cloudinary
(Atlas) (Media Storage)
The frontend uses a shared http() wrapper around the native fetch API. It automatically attaches the Bearer token from local storage, handles 401 responses by clearing auth, and normalizes error payloads. Each backend domain has a corresponding API module in src/api/, keeping integration concerns cleanly separated from UI logic.
All protected routes on the backend require a valid JWT. The middleware re-queries the user from the database on each request, verifying active status before granting access. On the frontend, a RequireAuth guard handles unauthenticated redirects and role-mismatch redirects. After login, users are routed to their role-appropriate area:
| Role | Default Route |
|---|---|
ADMIN |
/admin/dashboard |
CASHIER |
/cashier |
DRIVER |
/home |
CUSTOMER |
/home |
The customer-facing storefront is designed mobile-first. It supports browsing the menu with category filters, viewing product details, managing a cart (with real-time price snapshots), completing checkout with a dynamic address picker, and tracking orders post-placement. Promotions and special offers are surfaced on dedicated pages.
A comprehensive back-office dashboard under /admin. Sections include:
- Dashboard β KPIs, revenue timeseries, top-selling items, order status overview
- Products & Categories β full CRUD with image uploads
- Orders β filterable order management with status transitions
- Inventory β ingredient stock table with lot-level visibility
- Goods Receipts β supplier-linked inbound stock with auto stock entry creation
- Users β employee management with lock/unlock and password reset
- Promotions β grouped by status with clone, pause, and cancel schedule actions
- Shifts β shift templates and weekly assignment schedule
- Reports β revenue and order charts with tabular summaries
An operational workspace under /cashier for POS-style order creation, viewing today's orders, browsing order history, and accessing shift reports.
Drivers access delivery-task views showing assigned jobs, individual job details, and a daily summary of completed deliveries.
Food-Delivery/
βββ backend/ # Node.js / Express REST API
β βββ src/
β β βββ constants/ # Domain enums (roles, statuses, types)
β β βββ controllers/ # Request/response handlers
β β βββ middlewares/ # Auth, role checks, file uploads
β β βββ models/ # Mongoose schemas
β β βββ routes/ # Express route definitions
β β βββ services/ # Business logic
β β βββ utils/ # Shared helpers
β β βββ validators/ # Input validation
β βββ .env.example
β βββ package.json
β βββ server.js
β
βββ frontend/ # React / Vite application
β βββ src/
β β βββ api/ # Domain-based API client modules
β β βββ app/ # Router and route guards
β β βββ components/ # Shared UI components
β β βββ context/ # Popup, MenuFilter, Cart contexts
β β βββ layouts/ # Role-based layout shells
β β βββ pages/ # Page components by area
β β β βββ admin/
β β β βββ auth/
β β β βββ cashier/
β β β βββ customer/
β β βββ redux/ # Store, slices (cart / order / toast)
β β βββ utils/ # Auth storage, formatters, helpers
β βββ index.html
β βββ vite.config.js
β βββ package.json
β βββ vercel.json
β
βββ docs/ # Project documentation and reports
βββ .postman/ # Postman environment files
βββ postman/globals/ # Postman global variables
βββ .gitignore
βββ package.json # Root workspace scripts
βββ README.md
- Node.js v18 or higher
- MongoDB Atlas cluster (or local MongoDB)
- Cloudinary account
- npm
git clone https://github.com/DangHuuLong/Food-Delivery.git
cd Food-Delivery# Server
PORT=5000
# Database
MONGO_URI=mongodb+srv://<user>:<password>@cluster.mongodb.net
DB_NAME=fooddash
# JWT
JWT_SECRET=your_jwt_secret_here
JWT_EXPIRES_IN=7d
# Cloudinary
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secretCORS is pre-configured to allow
http://localhost:5173and the deployed Vercel frontend domain. Adjust as needed for your environment.
VITE_API_URL=http://localhost:5000If
VITE_API_URLis not set, the frontend falls back tohttp://localhost:3000.
cd backend
# Install dependencies
npm install
# Copy and configure environment variables
cp .env.example .env
# (Optional) Seed the admin account
npm run seed:admin
# Start development server with hot reload
npm run devThe API will be available at http://localhost:5000.
Health check: GET http://localhost:5000/api/v1/health
cd frontend
# Install dependencies
npm install
# Copy and configure environment variables
cp .env.example .env
# Start development server
npm run devThe app will be available at http://localhost:5173.
| Script | Description |
|---|---|
npm run dev |
Start development server (Nodemon) |
npm start |
Start production server |
npm run seed:admin |
Seed the initial admin account |
| Script | Description |
|---|---|
npm run dev |
Start Vite development server |
npm run build |
Build for production |
npm run preview |
Preview the production build locally |
npm run lint |
Run ESLint |
The frontend and backend are fully decoupled. The frontend communicates exclusively through the versioned REST API:
Frontend (React/Vite) βββΊ http://localhost:5000/api/v1/...
All API modules in frontend/src/api/ correspond directly to backend domain modules:
auth Β· cart Β· category Β· delivery Β· driver Β· goodsReceipt Β· goodsReceiptItem Β· ingredient Β· order Β· orderStats Β· payment Β· product Β· promotion Β· shift Β· shiftAssignment Β· stockEntry Β· supplier Β· user
The frontend is deployed on Vercel with an SPA rewrite rule:
// frontend/vercel.json
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}Set VITE_API_URL in your Vercel project environment settings to point to the deployed backend.
π Live: food-delivery-nine-inky.vercel.app
The backend can be deployed to any Node.js-compatible hosting provider (Railway, Render, Fly.io, etc.). Ensure all required environment variables are set in the deployment environment.
Postman collections and environment files are included in the repository:
.postman/ # Postman environment configurations
postman/globals/ # Postman global variable definitions
Import these into Postman to explore and test all API endpoints locally or against the deployed backend.
- Integrate a real payment gateway (e.g. VNPay, Stripe)
- Add WebSocket / SSE support for real-time order and delivery status updates
- Complete the frontend password recovery flow with full backend integration
- Add refresh token support for longer-lived sessions
- Consolidate cart state into a single Redux-first approach
- Add rate limiting and structured request logging to the backend
- Extend test coverage β unit and integration tests for both layers
- Add i18n support for a multi-language customer storefront
- Introduce loading skeletons for improved perceived performance
This project is licensed under the MIT License.
Built with β€οΈ by DangHuuLong using Node.js, Express, React, and MongoDB
Live Demo Β·
Repository