Interactive e-commerce platform with real-time inventory, dynamic cart UX, and a full admin dashboard.
- Product catalogue β search, filter by category / price range, pagination
- Product detail page β image gallery, live stock badge, viewer count
- Add to Cart β Qty Stepper β button transforms seamlessly into
β qty +stepper after first add, no layout shift - Real-time inventory β WebSocket (Socket.io) pushes live stock updates across tabs
- Urgency alerts β "Only X left!", live viewer bubble, back-in-stock toast
- Persistent cart (user-scoped, server-side)
- Checkout form with address & payment method
- Order confirmation and order history
- Dashboard β stats cards (total orders, products, categories, pending)
- Orders β full table with status badges + status-update modal (pending β delivered β cancelled)
- Products β CRUD table + add/edit form with multi-image upload (Cloudinary)
- Categories β inline add / edit / delete
- Role-based route guard β non-admins are redirected
| Layer | Technology |
|---|---|
| Frontend | React 19, React Router v7, Vite 7 |
| Styling | Vanilla CSS (custom design system) |
| State | React Context API (CartContext, AuthContext) |
| Real-time | Socket.io client |
| Backend | Node.js, Express 4 |
| Database | MongoDB + Mongoose |
| Auth | JWT + bcryptjs |
| File uploads | Multer + Cloudinary |
| Real-time | Socket.io server |
| CI | GitHub Actions |
- Node.js β₯ 18
- MongoDB (local or Atlas)
- Cloudinary account (for image uploads)
git clone https://github.com/mrsandy1965/EngageCart.git
cd EngageCartcd backend
cp .env.example .env # fill in MONGO_URI, JWT_SECRET, CLOUDINARY_* vars
npm install
npm run dev # starts on http://localhost:5001cd frontend
cp .env.example .env # set VITE_API_URL=http://localhost:5001/api
npm install
npm run dev # starts on http://localhost:5173cd backend
npm run seed# Backend (39 tests across 6 suites)
cd backend && npm test
# Frontend (27 tests across 4 suites)
cd frontend && npm test
# With coverage report
cd frontend && npm run test:coverage
cd backend && npm test -- --coverageFrontend
| Suite | Tests |
|---|---|
filterUtils |
Filter param stripping logic |
productService |
API endpoint calls + param forwarding |
authService |
Login, logout, token management |
AddToCartButton |
All 3 states: button / stepper / out-of-stock |
Backend
| Suite | Tests |
|---|---|
auth |
Register, login, duplicate email, wrong password |
product |
Create, list with filters, get by id, soft delete |
category |
List, create, duplicate slug, delete with guards |
cart |
Add, update qty, remove, clear |
order |
Create, cancel, status update |
app |
Server health |
| Service | What | Free tier |
|---|---|---|
| Render | Node.js backend + Socket.io | 750 hrs/month |
| Vercel | React/Vite frontend | Unlimited static |
| MongoDB Atlas | Database | 512 MB |
- Go to render.com β New β Blueprint
- Connect your GitHub repo β Render will auto-detect
render.yaml - Set the following Environment Variables in the Render dashboard (Settings β Environment):
MONGO_URI = mongodb+srv://... β from MongoDB Atlas
JWT_SECRET = a_long_random_string
CLOUDINARY_CLOUD_NAME / API_KEY / API_SECRET
FRONTEND_URL = https://your-app.vercel.app
- Copy the Deploy Hook URL (Settings β Deploy Hook) β add as
RENDER_DEPLOY_HOOK_URLin GitHub Secrets
Tip: To prevent the free-tier cold start (30s spin-up), add your Render URL to UptimeRobot with a 10-minute ping interval β it's free.
- Go to vercel.com β New Project β import your repo
- Set Root Directory to
frontend - Add environment variables:
VITE_API_URL = https://engagecart-api.onrender.com/api
VITE_SOCKET_URL = https://engagecart-api.onrender.com
- Deploy β copy your Vercel URL β set it as
FRONTEND_URLin Render
Go to GitHub β Settings β Secrets β Actions and add:
| Secret | Value |
|---|---|
RENDER_DEPLOY_HOOK_URL |
Render deploy hook URL |
VERCEL_TOKEN |
Vercel API token (get it here) |
VITE_API_URL |
https://your-app.onrender.com/api |
VITE_SOCKET_URL |
https://your-app.onrender.com |
Two workflows run on every push to main:
ci.yml β runs on every push & PR:
backend-lint β backend-test (Node 18 + Node 20) β coverage artifact
frontend-lint β frontend-test β frontend-build β coverage artifact
deploy.yml β runs only on push to main:
deploy-backend β triggers Render via deploy hook
deploy-frontend β deploys to Vercel via CLI
EngageCart/
βββ backend/
β βββ src/
β β βββ controllers/ # auth, cart, order, product, category
β β βββ middleware/ # auth, admin, upload
β β βββ models/ # User, Product, Cart, Order, Category
β β βββ routes/
β β βββ socket.js # Socket.io real-time events
β βββ tests/
βββ frontend/
β βββ src/
β β βββ components/ # Header, Cart, ProductList, AddToCartButton β¦
β β βββ context/ # AuthContext, CartContext
β β βββ hooks/ # useAuth, useCart, useProductSocket
β β βββ pages/ # Home, Products, Cart, Checkout, Orders, Admin/*
β β βββ services/ # authService, cartService, productService, adminService
β βββ src/__tests__/
βββ .github/workflows/ci.yml
PORT=5001
MONGO_URI=mongodb://localhost:27017/engagecart
JWT_SECRET=your_jwt_secret
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
NODE_ENV=developmentVITE_API_URL=http://localhost:5001/api
VITE_SOCKET_URL=http://localhost:5001MIT