To implement a Network Self-Service Ordering System, we'll use a modern tech stack: React (Frontend), Node.js/Express (Backend), and MongoDB (Database). Below is a structured implementation guide with core components and code snippets. The system consists of three main layers:
- Frontend: User-facing interface for browsing products, managing carts, and placing orders.
- Backend: API server handling auth, product/cart/order management, and payment processing.
- Database: Stores user data, products, carts, and orders.
Backend Implementation
Key Dependencies
Install: express, mongoose, bcryptjs, jsonwebtoken, cors, dotenv.
Models
User Model (models/User.js)
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
role: { type: String, enum: ['user', 'admin'], default: 'user' },
createdAt: { type: Date, default: Date.now }
});
// Hash password before saving
userSchema.pre('save', async function(next) {
if (!this.isModified('password')) return next();
this.password = await bcrypt.hash(this.password, 10);
next();
});
// Compare password
userSchema.methods.matchPassword = async function(enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password);
};
module.exports = mongoose.model('User', userSchema);
Product Model (models/Product.js)
const mongoose = require('mongoose');
const productSchema = new mongoose.Schema({
name: { type: String, required: true },
description: { type: String, required: true },
price: { type: Number, required: true },
image: { type: String, required: true },
category: { type: String, required: true },
stock: { type: Number, required: true, default: 0 },
createdAt: { type: Date, default: Date.now }
});
module.exports = mongoose.model('Product', productSchema);
Cart Model (models/Cart.js)
const mongoose = require('mongoose');
const cartSchema = new mongoose.Schema({
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
items: [{
product: { type: mongoose.Schema.Types.ObjectId, ref: 'Product', required: true },
quantity: { type: Number, required: true, default: 1 }
}],
totalPrice: { type: Number, required: true, default: 0 }
});
module.exports = mongoose.model('Cart', cartSchema);
Order Model (models/Order.js)
const mongoose = require('mongoose');
const orderSchema = new mongoose.Schema({
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
items: [{
product: { type: Object, required: true },
quantity: { type: Number, required: true }
}],
shippingAddress: { type: Object, required: true },
paymentMethod: { type: String, required: true },
totalPrice: { type: Number, required: true },
status: { type: String, enum: ['pending', 'paid', 'shipped', 'delivered'], default: 'pending' },
createdAt: { type: Date, default: Date.now }
});
module.exports = mongoose.model('Order', orderSchema);
Backend Routes
Auth Routes (routes/authRoutes.js)
Handles user registration and login with JWT:
const express = require('express');
const router = express.Router();
const User = require('../models/User');
const jwt = require('jsonwebtoken');
// Generate JWT
const generateToken = (id, role) => {
return jwt.sign({ id, role }, process.env.JWT_SECRET, { expiresIn: '30d' });
};
// Register
router.post('/register', async (req, res) => {
const { name, email, password } = req.body;
const userExists = await User.findOne({ email });
if (userExists) return res.status(400).json({ message: 'User exists' });
const user = await User.create({ name, email, password });
res.status(201).json({
_id: user._id, name: user.name, email: user.email, role: user.role,
token: generateToken(user._id, user.role)
});
});
// Login
router.post('/login', async (req, res) => {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (!user || !(await user.matchPassword(password))) {
return res.status(401).json({ message: 'Invalid credentials' });
}
res.json({
_id: user._id, name: user.name, email: user.email, role: user.role,
token: generateToken(user._id, user.role)
});
});
module.exports = router;
Product Routes (routes/productRoutes.js)
Admins can manage products; users can browse:
const express = require('express');
const router = express.Router();
const Product = require('../models/Product');
const authMiddleware = require('../middleware/authMiddleware');
const adminMiddleware = require('../middleware/adminMiddleware');
// Get all products
router.get('/', async (req, res) => {
const products = await Product.find();
res.json(products);
});
// Get product by ID
router.get('/:id', async (req, res) => {
const product = await Product.findById(req.params.id);
res.json(product);
});
// Add product (admin only)
router.post('/', authMiddleware, adminMiddleware, async (req, res) => {
const product = await Product.create(req.body);
res.status(201).json(product);
});
// Update product (admin only)
router.put('/:id', authMiddleware, adminMiddleware, async (req, res) => {
const product = await Product.findByIdAndUpdate(req.params.id, req.body, { new: true });
res.json(product);
});
// Delete product (admin only)
router.delete('/:id', authMiddleware, adminMiddleware, async (req, res) => {
await Product.findByIdAndDelete(req.params.id);
res.json({ message: 'Product deleted' });
});
module.exports = router;
Cart Routes (routes/cartRoutes.js)
User-specific cart management:
const express = require('express');
const router = express.Router();
const Cart = require('../models/Cart');
const Product = require('../models/Product');
const authMiddleware = require('../middleware/authMiddleware');
// Get user cart
router.get('/', authMiddleware, async (req, res) => {
let cart = await Cart.findOne({ user: req.user.id }).populate('items.product');
if (!cart) cart = await Cart.create({ user: req.user.id, items: [], totalPrice: 0 });
res.json(cart);
});
// Add item to cart
router.post('/add', authMiddleware, async (req, res) => {
const { productId, quantity } = req.body;
const product = await Product.findById(productId);
let cart = await Cart.findOne({ user: req.user.id });
if (!cart) cart = new Cart({ user: req.user.id, items: [], totalPrice:0 });
const existingItem = cart.items.find(i => i.product.toString() === productId);
if (existingItem) existingItem.quantity += quantity;
else cart.items.push({ product: productId, quantity });
// Calculate total price
cart.totalPrice = cart.items.reduce((sum, item) => {
return sum + (product.price * item.quantity);
}, 0);
await cart.save();
res.json(await cart.populate('items.product'));
});
module.exports = router;
Order Routes (routes/orderRoutes.js)
Order creation and management:
const express = require('express');
const router = express.Router();
const Order = require('../models/Order');
const Cart = require('../models/Cart');
const authMiddleware = require('../middleware/authMiddleware');
const adminMiddleware = require('../middleware/adminMiddleware');
// Create order from cart
router.post('/create', authMiddleware, async (req, res) => {
const { shippingAddress, paymentMethod } = req.body;
const cart = await Cart.findOne({ user: req.user.id }).populate('items.product');
const order = await Order.create({
user: req.user.id,
items: cart.items.map(item => ({ product: item.product, quantity: item.quantity })),
shippingAddress,
paymentMethod,
totalPrice: cart.totalPrice
});
// Clear cart
await Cart.findByIdAndUpdate(cart._id, { items: [], totalPrice:0 });
res.json(order);
});
// Get user orders
router.get('/', authMiddleware, async (req, res) => {
const orders = await Order.find({ user: req.user.id });
res.json(orders);
});
// Update order status (admin only)
router.put('/:id/status', authMiddleware, adminMiddleware, async (req, res) => {
const order = await Order.findByIdAndUpdate(req.params.id, { status: req.body.status }, { new: true });
res.json(order);
});
module.exports = router;
Frontend Implementation
Key Dependencies
Install: react-router-dom, axios, jwt-decode, tailwindcss, react-hook-form.
Frontend Core Components
Auth Context (context/AuthContext.js)
Manages user auth state:
import React, { createContext, useState, useEffect } from 'react';
import axios from 'axios';
import jwtDecode from 'jwt-decode';
const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
useEffect(() => {
const token = localStorage.getItem('token');
if (token) {
const decoded = jwtDecode(token);
setUser({ id: decoded.id, role: decoded.role });
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
}
}, []);
const login = async (email, password) => {
const res = await axios.post('/api/auth/login', { email, password });
localStorage.setItem('token', res.data.token);
setUser({ id: res.data._id, role: res.data.role });
axios.defaults.headers.common['Authorization'] = `Bearer ${res.data.token}`;
};
const logout = () => {
localStorage.removeItem('token');
setUser(null);
delete axios.defaults.headers.common['Authorization'];
};
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
};
export default AuthContext;
Product List Component (components/ProductList.js)
Displays products for users:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import ProductCard from './ProductCard';
const ProductList = () => {
const [products, setProducts] = useState([]);
useEffect(() => {
axios.get('/api/products').then(res => setProducts(res.data));
}, []);
return (
<div className="grid grid-cols-1 md:cols-2 lg:cols-3 gap-6 p-4">
{products.map(p => <ProductCard key={p._id} product={p} />)}
</div>
);
};
export default ProductList;
Checkout Page (pages/CheckoutPage.js)
Handles order placement:
import React, { useContext, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import AuthContext from '../context/AuthContext';
import CartContext from '../context/CartContext';
import axios from 'axios';
const CheckoutPage = () => {
const { user } = useContext(AuthContext);
const { cart } = useContext(CartContext);
const [shippingAddress, setShippingAddress] = useState({ street: '', city: '' });
const navigate = useNavigate();
if (!user) navigate('/login');
const handleSubmit = async (e) => {
e.preventDefault();
await axios.post('/api/orders/create', { shippingAddress, paymentMethod: 'credit_card' });
navigate('/orders');
};
return (
<div className="p-4">
<h1>Checkout</h1>
<form onSubmit={handleSubmit}>
<input
type="text"
name="street"
placeholder="Street"
value={shippingAddress.street}
onChange={(e) => setShippingAddress({ ...shippingAddress, street: e.target.value })}
required
/>
<button type="submit">Place Order</button>
</form>
</div>
);
};
export default CheckoutPage;
Deployment
- Backend: Deploy to Heroku/Vercel with MongoDB Atlas.
- Frontend: Deploy to Vercel/Netlify.
- Environment Variables: Store JWT secret, MongoDB URI, and other sensitive data.
Key Features
- User Authentication: Secure login/registration with JWT.
- Product Management: Admins canTo implement# Network Self-Service Ordering System
Overview
A full-stack web application for self-service ordering, allowing users to browse products, manage carts, place orders, and admins to manage products/orders. Built with React, Node.js, Express, and MongoDB.
Tech Stack
| Layer | Technologies |
|---|---|
| Frontend | React, Tailwind CSS, React Router |
| Backend | Node.js, Express.js |
| Database | MongoDB (MongoDB Atlas) |
| Auth | JWT (JSON Web Tokens) |
| API Calls | Axios |
Core Features
User Features
- Register/Login with JWT authentication
- Browse products by category
- Add/remove/update cart items
- Place orders with shipping address
- View order history and status
- Mock payment integration
Admin Features
- Manage products (add/edit/delete)
- View and update order status
- Access to sales analytics
System Architecture
The system follows a 3-tier architecture:
- Frontend: User interface for interaction
- Backend: REST API handling business logic
- Database: Stores user, product, cart, and order data
Backend Implementation
Database Models
User Model
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
role: { type: String, enum: ['user', 'admin'], default: 'user' },
createdAt: { type: Date, default: Date.now }
});
// Hash password before saving
userSchema.pre('save', async function(next) {
if (!this.isModified('password')) return next();
this.password = await bcrypt.hash(this.password, 10);
next();
});
// Compare password
userSchema.methods.matchPassword = async function(enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password);
};
module.exports = mongoose.model('User', userSchema);
Product Model
const mongoose = require('mongoose');
const productSchema = new mongoose.Schema({
name: { type: String, required: true },
description: { type: String, required: true },
price: { type: Number, required: true },
category: { type: String, required: true },
imageUrl: { type: String, required: true },
stock: { type: Number, required: true, default: 0 },
createdAt: { type: Date, default: Date.now }
});
module.exports = mongoose.model('Product', productSchema);
Order Model
const mongoose = require('mongoose');
const orderSchema = new mongoose.Schema({
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
items: [{
product: { type: mongoose.Schema.Types.ObjectId, ref: 'Product', required: true },
quantity: { type: Number, required: true }
}],
shippingAddress: { type: Object, required: true },
totalAmount: { type: Number, required: true },
status: { type: String, enum: ['pending', 'paid', 'shipped', 'delivered'], default: 'pending' },
createdAt: { type: Date, default: Date.now }
});
module.exports = mongoose.model('Order', orderSchema);




