Open In App

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

kjh

Project Preview

Prerequisites

Approach to create Fashion Store E-Commerce

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):

Screenshot-2024-03-10-104441

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.geeksforgeeks.org/wp-content/uploads/20240103185713/hoodie.jpg'
            },
            {
                name: 'GFG T-shirt',
                type: 'Clothing',
                description: 'Very smooth and comfortable to wear',
                price: 25,
                image: 
'https://media.geeksforgeeks.org/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.geeksforgeeks.org/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.geeksforgeeks.org/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:

Screenshot-2024-03-21-200418Example: 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

Output:


Animation49

Fashion Store E-Commerce using MERN Stack

Article Tags :