Fashion Store E-Commerce using MERN Stack
This E-commerce site project uses the MERN (MongoDB, Express.js, React.js, and Node.js) stack to deliver a fully functional online shopping experience. Users can explore a diverse range of products, filter items based on criteria like price range and product type, add selected items to their cart and view the total price.
Output Preview: Let us have a look at how the final output will look like
Prerequisites
Approach to create Fashion Store E-Commerce
- Products are fetched from a MongoDB database and displayed on the front end.
- Users can filter products by price range and type .
- Products can be added or removed from the shopping cart.
- The total price of items in the cart is displayed on the navbar.
Steps to create the project:
Step 1: Ctreate a folder for the backend.
mkdir <<name of project>>
cd <<name of project>>
Step 2: Initialize the Node project using the following command.
npm init -y
Step 3: Install the required dependencies:
npm i express mongoose nodemon cors
Folder structure(Backend):
The updated Dependencies in package.json file will look like:
"dependencies": {
"cors": "^2.8.5",
"express": "^4.18.3",
"mongoose": "^8.2.1",
"nodemon": "^3.1.0"
}
Code Example: Create the required files as shown in the folder structure and add the following codes.
// index.js
const express = require('express');
const mongoose = require('mongoose');
const app = express();
const PORT = process.env.PORT || 5000;
const cors = require('cors');
mongoose.connect('Your MongoDB URI',
{
useNewUrlParser: true,
useUnifiedTopology: true
}
);
app.use(express.json());
app.use(cors());
const productSchema = new mongoose.Schema({
name: String,
type: String,
description: String,
price: Number,
image: String,
});
const Product = mongoose.model('Product', productSchema);
const seedDatabase = async () => {
try {
await Product.deleteMany();
const products = [
{
name: 'GFG Hoodie-White',
type: 'Clothing',
description: 'Comfortable to wear for the winters',
price: 50,
image:
'https://media.w3wiki.net/wp-content/uploads/20240103185713/hoodie.jpg'
},
{
name: 'GFG T-shirt',
type: 'Clothing',
description: 'Very smooth and comfortable to wear',
price: 25,
image:
'https://media.w3wiki.net/wp-content/uploads/20230407153931/gfg-tshirts.jpg'
},
{
name: 'GFG Hoodie-black',
type: 'Clothing',
description: 'Comfortable to wear for the winters',
price: 60,
image:
'https://media.w3wiki.net/wp-content/uploads/20240103185847/black-hoodie.webp'
},
{
name: 'GFG-Bag',
type: 'Stationary',
description: 'HAndy bag for keeping all your equipmements',
price: 120,
image:
'https://media.w3wiki.net/wp-content/uploads/20230407154213/gfg-bag.jpg'
},
];
await Product.insertMany(products);
console.log('Database seeded successfully');
} catch (error) {
console.error('Error seeding database:', error);
}
};
seedDatabase();
app.get('/api/products', async (req, res) => {
try {
const allProducts = await Product.find();
res.json(allProducts);
} catch (error) {
console.error(error);
res.status(500)
.json({ error: 'Internal Server Error' });
}
});
app.listen(PORT, () => {
console.log(
`Server is running on port ${PORT}`
);
});
Step 4: Start the Server
In the terminal, run the following command to start the server:
node index.js
Step 5: Set up React frontend using the command.
npx create-react-app client
cd client
Step 6: Install the required dependencies.
npm i @fortawesome/free-solid-svg-icons
npm i @fortawesome/react-fontawesome
npm i axios
Dependencies:
"dependencies": {
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.6.8",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
Folder Structure:
Example: Create the required files and write the following code.
/* App.css*/
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 20px;
background-color: #333;
color: white;
}
.ecom {
margin: 0;
}
.navbar-items {
display: flex;
align-items: center;
}
h3 {
margin: 0;
margin-right: 20px;
}
.cart-num {
display: flex;
align-items: center;
color: white;
}
.cart-items {
background-color: #FF6347;
color: white;
border-radius: 50%;
width: 25px;
height: 25px;
display: flex;
align-items: center;
justify-content: center;
margin-left: 5px;
}
.product-card {
border: 1px solid #ddd;
margin: 10px;
padding: 15px;
border-radius: 8px;
background-color: white;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
width: 30%;
}
.product-image {
max-width: 100%;
border-radius: 8px;
}
.product-details {
text-align: center;
}
button {
background-color: #4CAF50;
color: white;
border: none;
padding: 10px 15px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
margin: 5px;
cursor: pointer;
border-radius: 4px;
}
.prdt-list {
margin: 20px;
}
h2 {
color: #333;
}
.filter-btn {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}
label {
margin-right: 10px;
}
.item-card {
list-style: none;
padding: 0;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
}
.buy-now-btn {
background-color: #4CAF50;
color: white;
padding: 10px 15px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 18px;
margin-top: 20px;
cursor: pointer;
border-radius: 4px;
}
// App.js
import React from 'react';
import ProductList from './components/ProductList';
import Header from './components/Header';
import './App.css'
import CustomItemContext from './context/ItemContext';
const App = () => {
return (
<CustomItemContext>
<Header />
<ProductList />
</CustomItemContext>
);
};
export default App;
//components/Header.js
import React, { useContext } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faCartShopping } from '@fortawesome/free-solid-svg-icons'
import { itemContext } from '../context/ItemContext';
const Navbar = () => {
const { itemsInCart, totalPrice } = useContext(itemContext);
return (
<nav className='navbar'>
<div className='navbar-brand'>
<h1 className='ecom'>
Welcome To E-Medical Store
</h1>
</div>
<div className='navbar-items'>
<h3 style={{ color: "green" }}>
Total Price: {totalPrice}
</h3>
<div className='cart-num'>
<FontAwesomeIcon icon={faCartShopping} size="2x" />
<div className='cart-items'>
{itemsInCart}
</div>
</div>
</div>
</nav>
);
};
export default Navbar;
//components/ProductItem.js
import React, { useContext } from 'react';
import { itemContext } from '../context/ItemContext';
const ProductItem = ({ product }) => {
const { addToCart, removeFromCart } = useContext(itemContext)
const handleAddToCart = (product) => {
console.log(product)
addToCart(product)
};
const handleRemoveToCart = (product) => {
console.log("product removed", product)
removeFromCart(product)
};
return (
<div className="product-card">
<img className="product-image"
src={product.image}
alt={product.name} />
<div className="product-details">
<h3 style={{ fontWeight: "700" }}>
{product.name}
</h3>
<p style={{ fontWeight: "300" }}>
{product.description}
</p>
<p style={{ fontWeight: "500" }}>
Price: {product.price} Rs
</p>
<button onClick={
() => handleAddToCart(product)
}>
Add to Cart
</button>
<button onClick={
() =>
handleRemoveToCart(product)
}>
-
</button>
</div>
</div>
);
};
export default ProductItem;
//components/ProductList.js
import React, { useContext, useEffect, useState } from 'react';
import ProductItem from './ProductItem';
import { itemContext } from '../context/ItemContext';
const ProductList = () => {
const { products } = useContext(itemContext);
const [sortedProducts, setSortedProducts] =
useState([...products]);
const [minPrice, setMinPrice] = useState(0);
const [maxPrice, setMaxPrice] = useState(3000);
const [selectedType, setSelectedType] = useState('all');
useEffect(() => {
setSortedProducts([...products])
}, [products])
const handleSortByPrice = () => {
const sorted = [...sortedProducts]
.sort((a, b) => a.price - b.price);
setSortedProducts(sorted);
};
const handleFilterByPriceRange = () => {
const filtered =
products.filter(
(product) =>
product.price >= minPrice &&
product.price <= maxPrice);
setSortedProducts(filtered);
};
const handleFilterByType = () => {
if (selectedType === 'all') {
setSortedProducts([...products]);
} else {
const filtered =
products.filter(
(product) =>
product.type === selectedType);
setSortedProducts(filtered);
}
};
return (
<div className='prdt-list'>
<h2>Product List</h2>
<div className='filter-btn'>
<button onClick={handleSortByPrice}>
Sort by Price
</button>
<label>
Min Price:
<input type='number' value={minPrice}
onChange={
(e) =>
setMinPrice(Number(e.target.value))
} />
</label>
<label>
Max Price:
<input type='number' value={maxPrice}
onChange={
(e) =>
setMaxPrice(Number(e.target.value))
} />
</label>
<button onClick={() => handleFilterByPriceRange()}>
Filter by Price Range
</button>
<label>
Filter by Type:
<select value={selectedType}
onChange={
(e) =>
setSelectedType(e.target.value)
}>
<option value='all'>
All
</option>
<option value='Clothing'>Clothing</option>
<option value='Stationary'>Stationary</option>
</select>
</label>
<button onClick={handleFilterByType}>
Filter by Type
</button>
</div>
<ul className='item-card'>
{sortedProducts.map((product) => (
<ProductItem key={product._id}
product={product} />
))}
</ul>
<div className='buy-now-btn'>Buy Now</div>
</div>
);
};
export default ProductList;
//context/ItemContext.js
import {
createContext,
useEffect,
useState
} from 'react';
const itemContext = createContext();
function CustomItemContext({ children }) {
const [products, setProducts] = useState([]);
const [cart, setCart] = useState([]);
const [itemsInCart, setItemsInCart] = useState(0);
const [totalPrice, setTotalPrice] = useState(0)
useEffect(() => {
const fetchData = async () => {
const response =
await fetch('http://localhost:5000/api/products');
const products = await response.json();
setProducts(products);
};
fetchData();
}, []);
const addToCart = (product) => {
setTotalPrice(totalPrice + product.price)
setCart([...cart, product]);
setItemsInCart(itemsInCart + 1);
};
const removeFromCart = (product) => {
const index =
cart.findIndex(
(prdt) =>
prdt._id === product._id);
console.log(index);
if (index !== -1) {
const updatedCart = [...cart];
updatedCart.splice(index, 1);
setTotalPrice(totalPrice - cart[index].price);
setCart(updatedCart);
setItemsInCart(itemsInCart - 1);
} else {
console.log("Item not found in the cart");
}
};
return (
<itemContext.Provider value={
{
products, addToCart,
removeFromCart,
itemsInCart, totalPrice
}}>
{children}
</itemContext.Provider>
);
}
export { itemContext };
export default CustomItemContext;
Run the react app using the following command.
npm start
Contact Us