Horje
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

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

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.

JavaScript
// 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.

CSS
/* 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;
}
JavaScript
// 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;
JavaScript
//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;
JavaScript
//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;
JavaScript
//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;
JavaScript
//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




Reffered: https://www.geeksforgeeks.org


Dev Scripter

Related
Simple Journal App with MERN Stack Simple Journal App with MERN Stack
Comparative Analysis of React, lit-element, and lit-html in Frontend Development Comparative Analysis of React, lit-element, and lit-html in Frontend Development
How Do We Design for High Availability? How Do We Design for High Availability?
Product Review Platform using MEAN Stack Product Review Platform using MEAN Stack
Community Forum Page using MEAN Stack Community Forum Page using MEAN Stack

Type:
Geek
Category:
Coding
Sub Category:
Tutorial
Uploaded by:
Admin
Views:
14