A full-featured online store built with the MERN-adjacent stack (React, Node.js, Express, MongoDB) — product catalog, cart, checkout with a mock payment flow, order tracking, and a role-protected admin dashboard.
No registration needed to look around — the sign-in page has one-click "Log in as User" / "Log in as Admin" buttons that drop you straight in with real-looking products and order history already there. (Same accounts, manually: demo@shopwave.app / DemoPass123 and admin@shopwave.app / AdminPass123.)
Storefront
- Product catalog with search, category filtering, and pagination
- Product detail pages with stock-aware quantity selection
- Persistent cart (localStorage) that survives page reloads
- Checkout with a shipping form and a demo card-payment flow (no real gateway — validates card format client & server side, then "charges" and issues a mock transaction ID)
- Order confirmation and a per-order tracking page with a visual pending → paid → shipped → delivered stepper
- Order history for logged-in customers
Admin Dashboard (role-gated)
- Revenue, monthly revenue, product count, and customer count at a glance
- Recent orders and top-selling products
- Full product CRUD (create, edit, delete)
- Order list with status filtering and inline status updates
Backend
- JWT-based authentication with
customer/adminroles - Stock is decremented atomically per order line (
findOneAndUpdatewith astock >= quantityguard) with automatic rollback of any already-decremented items if a later line fails — so concurrent checkouts can never oversell a product - Orders store a price/name snapshot per line item, so catalog price changes never alter historical orders
- Frontend: React 18, React Router, Tailwind CSS, Axios, Vite
- Backend: Node.js, Express, Mongoose (MongoDB), JWT, bcryptjs
- Payments: Mocked — no external gateway is called; this is a portfolio/demo checkout, not a production payment integration
├── backend/
│ ├── config/db.js # MongoDB connection
│ ├── models/ # User, Product, Order (Mongoose schemas)
│ ├── controllers/ # auth, product, order, admin logic
│ ├── routes/ # Express routers per resource
│ ├── middleware/ # JWT auth guard, admin guard, error handler
│ ├── utils/ # token generation, async handler, seed script
│ └── server.js
├── frontend/
│ ├── src/pages/ # Home, ProductDetail, Cart, Checkout, Orders, Login/Register
│ ├── src/pages/admin/ # Dashboard, Products, Orders
│ ├── src/components/ # Navbar, Footer, ProductCard, AdminLayout, route guards
│ ├── src/context/ # AuthContext (JWT/session), CartContext (localStorage cart)
│ └── src/api/client.js # Axios instance with auth interceptor
cd backend
npm install
cp .env.example .env # edit MONGO_URI if not using local default
npm run seed # creates an admin account + sample products
npm run devSeeded admin login: admin@example.com / admin123
cd frontend
npm install
cp .env.example .env # points at the backend API, defaults to localhost:5000
npm run devThe app runs at http://localhost:5173 and expects the API at http://localhost:5000/api by default.
Checkout does not call a real payment provider. It validates the card number, expiry, and CVV format, then records a mock transactionId and marks the order paid — this keeps the project runnable without any external API keys while still exercising a realistic checkout → order → tracking flow end to end.
Live on Vercel as two separate projects from this repo (Root Directory backend and frontend respectively), with MongoDB Atlas for the database. The backend is a plain Express app (app.js exports it, api/index.js re-exports it as the Vercel serverless entry, vercel.json rewrites every /api/* request there); the frontend has its own vercel.json rewrite so client-side routes like /login or /orders don't 404 on a direct visit or refresh. backend/utils/seed.js seeds the demo accounts, products, and sample orders — run it with node utils/seed.js against your own MONGO_URI.