A full-stack e-commerce catalog application built with Next.js (frontend) and Node.js with Express (backend).
- Product Catalog: Browse products with grid layout
- Product Details: View detailed information about each product by slug
- Search & Filter: Search products by title/description, filter by category, price range, and sort
- Add Products: Create new products through modal dialog with Formik form
- Edit/Delete Products: Update or delete products from detail page
- Related Products: View 3-4 related products from same category
- Responsive Design: Modern, mobile-friendly UI with SASS styling
- RESTful API: Complete CRUD operations for products
- Next.js 14 (App Router)
- React 18
- TypeScript
- SASS
- Redux Toolkit Query
- Formik
- Node.js
- Express.js
- MongoDB with Mongoose
- RESTful API
Choose one of the following methods to run the application:
- Node.js (v18 or higher)
- MongoDB (local or cloud instance)
- npm or yarn
- Clone the repository:
git clone <repository-url>
cd shop-catalog-test- Install dependencies for all projects:
npm run install:allOr install separately:
# Root dependencies
npm install
# Client dependencies
cd client
npm install
# Server dependencies
cd ../server
npm install- Set up environment variables:
Create server/.env file:
PORT=5000
MONGODB_URI=mongodb://localhost:27017/shop-catalog
NODE_ENV=developmentCreate client/.env.local file (optional):
NEXT_PUBLIC_API_URL=http://localhost:5000/api- Start MongoDB (if running locally):
mongod- Seed the database with sample data:
cd server
npm run seedDevelopment Mode:
Run both client and server concurrently:
npm run devOr run separately:
Terminal 1 - Start the server:
cd server
npm run devTerminal 2 - Start the client:
cd client
npm run dev- Client will run on: http://localhost:3000
- Server API will run on: http://localhost:5000
Production Mode:
- Build the client:
cd client
npm run build- Start the server:
cd server
npm start- Docker (v20 or higher)
- Docker Compose (v2 or higher)
- Clone the repository:
git clone <repository-url>
cd shop-catalog-test- Configure the API URL (IMPORTANT):
YOUR_SERVER_IP with your actual server IP address or domain in the following files:
docker-compose.yml(line 39)docker-compose.dev.yml(line 40 and 46)client/Dockerfile(line 6)client/Dockerfile.dev(line 6)
Examples:
- For local development: Replace
YOUR_SERVER_IPwithlocalhost - For server with IP: Replace
YOUR_SERVER_IPwith192.168.1.100 - For domain: Replace
YOUR_SERVER_IPwithapi.yourdomain.com
Example replacement:
# Before:
- NEXT_PUBLIC_API_URL=http://YOUR_SERVER_IP:5000/api
# After (for localhost):
- NEXT_PUBLIC_API_URL=http://localhost:5000/api
# After (for IP 192.168.1.100):
- NEXT_PUBLIC_API_URL=http://192.168.1.100:5000/api- Run with Docker Compose:
For Production:
docker-compose up --buildFor Development (with hot reload):
docker-compose -f docker-compose.dev.yml up --buildImportant Notes:
- Replace
YOUR_SERVER_IPwith your actual server IP address or domain MONGODB_URI=mongodb://mongodb:27017/shop-catalogshould NOT be changed -mongodbis the Docker service name and is correct for internal container communication
- Seed the database with sample data:
In a new terminal, execute the seed script:
# For production
docker-compose exec server npm run seed
# For development
docker-compose -f docker-compose.dev.yml exec server npm run seed- Access the application:
- Client: http://localhost:3000
- Server API: http://localhost:5000
- MongoDB: localhost:27017
Useful Docker Commands:
# Stop containers
docker-compose down
# Stop and remove volumes (clears database)
docker-compose down -v
# View logs
docker-compose logs -f
# Rebuild specific service
docker-compose build client
docker-compose up -d clientGET /api/products- Get all products- Query params:
category,search,page,limit,minPrice,maxPrice,sort - Sort options:
price-asc,price-desc,title-asc,title-desc
- Query params:
GET /api/products/slug/:slug- Get single product by slugGET /api/products/:id- Get single product by IDGET /api/products/price-range- Get min and max pricesGET /api/products/related/:slug- Get related products (same category)POST /api/products- Create new product (slug auto-generated from title)PUT /api/products/:id- Update productDELETE /api/products/:id- Delete product
GET /api/health- Server health check
shop-catalog-test/
├── client/ # Next.js frontend
│ ├── src/
│ │ ├── app/ # Next.js app directory
│ │ │ ├── page.tsx # Home page (product listing)
│ │ │ ├── products/ # Product detail pages
│ │ │ │ └── [slug]/ # Dynamic slug route
│ │ │ └── globals.scss
│ │ ├── components/
│ │ │ └── AddProductModal.tsx # Product form modal
│ │ └── lib/
│ │ ├── store.ts # Redux Toolkit Query API
│ │ └── store-provider.tsx # Redux Provider
│ ├── public/
│ │ └── images/ # Product images (SVG)
│ ├── Dockerfile
│ ├── Dockerfile.dev
│ └── package.json
├── server/ # Node.js backend
│ ├── src/
│ │ ├── models/ # MongoDB models
│ │ ├── routes/ # API routes
│ │ ├── server.js # Express server
│ │ └── seed.js # Database seeder
│ ├── Dockerfile
│ ├── Dockerfile.dev
│ └── package.json
├── docker-compose.yml # Production Docker setup
├── docker-compose.dev.yml # Development Docker setup
└── package.json # Root package.json
{
title: String (required),
description: String (required),
image: String (required),
category: String (required, enum: ['Clothing', 'Shoes', 'Electronics', 'Home & Kitchen', 'Sports & Fitness', 'Accessories']),
price: Number (required, min: 0),
availability: Boolean (required),
slug: String (required, unique),
createdAt: Date,
updatedAt: Date
}- All code comments and documentation are in English
- The application uses TypeScript for type safety
- SASS is used for component styling
- Redux Toolkit Query is used for API state management
- Formik is used for form handling with Yup validation
- MongoDB is used as the database
- The API uses RESTful conventions
- Product images are stored as SVG files in
client/public/images/ - Product slugs are auto-generated from titles
- MongoDB connection error: Make sure MongoDB is running and the connection string in
server/.envis correct - Port already in use: Change the PORT in environment variables or stop the process using the port
- Module not found: Run
npm installin the respective directory (client or server)
- Container won't start: Check logs with
docker-compose logs - Database connection fails: Ensure MongoDB container is running and healthy
- Images not loading: Check that the
public/imagesfolder is properly mounted - Changes not reflecting: In development mode, ensure volumes are properly mounted
MIT