DEV Community

Cover image for Shopping Cart in React Filters, JSON Integration, and Responsive Design
Sudhanshu Gaikwad
Sudhanshu Gaikwad

Posted on Edited on

Shopping Cart in React Filters, JSON Integration, and Responsive Design

This project is a React Shopping Cart Application featuring product filtering by category and price range, dynamic product rendering from a JSON file, and a sleek responsive design using styled-components. It’s ideal for beginners and intermediates to learn React concepts and practical implementation.

The app includes:

  • Dynamic filtering by category and price range.
  • Responsive product grid design.
  • Interactive product cards with hover effects.
  • Integration of JSON data to mimic a product database.

Folder Structure:
Below is the folder structure for this project:

shopping-cart/
├── public/
   ├── index.html
   ├── favicon.ico
├── src/
   ├── Product/
      ├── Product.jsx       
      └── products.json         
   ├── App.js                
   ├── index.js              
├── package.json
├── README.md

Enter fullscreen mode Exit fullscreen mode

How to Think About and Create the Project:
1. Define the Problem:
Create a simple yet scalable shopping cart application.
Integrate a JSON file to simulate a backend.
Provide users with filters for category and price.
2. Plan the Structure:
Design components: FilterSection, ProductSection, and ProductCard.
Use React state for filters (category and price).
Ensure responsiveness with CSS grids and styled-components.
3. JSON Data Design:
Prepare a JSON file with product details such as id, name, price, category, and image.

products.json

[
  {
    "id": 1,
    "name": "Lymio Men T-Shirt || T-Shirt for Men || Polo T Shirt || T-Shirt (Polo-34-37)",
    "category": "Men",
    "price": 500,
    "image": "abc1.png"
  },
  {
    "id": 2,
    "name": "Aero Armour Retro Chopper HOP 8-BIT T-Shirt",
    "category": "Men",
    "price": 799,
    "image": "abc2.png"
  },
  {
    "id": 3,
    "name": "Aero Armour Rafale India Edition Blueprint T-Shirt",
    "category": "Men",
    "price": 799,
    "image": "abc3.png"
  },
  {
    "id": 4,
    "name": "Rangriti Women's Viscose Classic Ankle Length Dress",
    "category": "Women",
    "price": 1200,
    "image": "abc4.png"
  },
  {
    "id": 5,
    "name": "DUPATTA BAZAAR Women's Cream Lucknowi Net Dupatta with Gold Embroidery",
    "category": "Women",
    "price": 649,
    "image": "abc5.png"
  },
  {
    "id": 6,
    "name": "HELLA FASHIONS Women's Chanderi 2.25 Meter Dupatta with Zari Embroidery and Tassels",
    "category": "Women",
    "price": 499,
    "image": "abc6.png"
  },
  {
    "id": 7,
    "name": "NEW-18 Simple Winter Jacket For Boys, Casual Jacket, Regular Winter Jacket For Boys, Hot Wear,Comfortale Jacket For Baby Boys, Kids Jacket, Jacket06.",
    "category": "Child",
    "price": 800,
    "image": "abc7.png"
  },
  {
    "id": 8,
    "name": "FUNKOOL Boys Regular Fit | Polyster |Fluffy Full Sleevs |Quilted Insulation|High Neck Stand Collar|Zipper Jacket",
    "category": "Child",
    "price": 650,
    "image": "abc8.png"
  },
  {
    "id": 9,
    "name": "ADBUCKS Unisex Cotton Hooded Sweatshirt",
    "category": "Child",
    "price": 744,
    "image": "abc9.png"
  },
  {
    "id": 10,
    "name": "Lymio Men Jeans || Men Jeans Pants || Denim Jeans || Baggy Jeans for Men (Jeans-06-07-08)",
    "category": "Men",
    "price": 900,
    "image": "abc10.png"
  },
  {
    "id": 11,
    "name": "OFF LIMITS WMN Hustle Printed RN, Half Sleeve, T- Shirt, for Women",
    "category": "Women",
    "price": 499,
    "image": "abc11.png"
  },
  {
    "id": 12,
    "name": "Yash Gallery Women's Geomatrical Printed Regular Top for Women",
    "category": "Women",
    "price": 799,
    "image": "abc12.png"
  }
]


Enter fullscreen mode Exit fullscreen mode

Product.jsx

import React, { useState } from "react";
import styled from "styled-components";
import products from "./products.json"; // Static import

// Styled Components
const Container = styled.div`
  display: flex;
  flex-direction: row;
  gap: 20px;
  padding: 20px;

  @media (max-width: 768px) {
    flex-direction: column;
  }
`;

const FilterSection = styled.div`
  flex: 1;
  background-color: #f8f8f8;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.1);

  @media (max-width: 768px) {
    padding: 15px;
  }
`;

const ProductSection = styled.div`
  flex: 3;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;

  @media (max-width: 768px) {
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  }
`;

const ProductCard = styled.div`
  background: #fff;
  padding: 15px;
  border: 1px solid #ddd;
  border-radius: 8px;
  text-align: center;
  box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.05);
  transition: transform 0.3s ease, box-shadow 0.3s ease;

  &:hover {
    transform: translateY(-5px);
    box-shadow: 0px 6px 15px rgba(0, 0, 0, 0.1);
  }

  img {
    max-width: 100%;
    height: auto;
    border-radius: 8px;
  }

  h3 {
    margin: 10px 0;
    font-size: 18px;
    color: #333;
  }

  p {
    color: #777;
    font-size: 16px;
    margin: 5px 0;
  }

  button {
    margin-top: 10px;
    padding: 10px 15px;
    background-color: #007bff;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    font-size: 14px;
    transition: background-color 0.3s ease;

    &:hover {
      background-color: #0056b3;
    }
  }
`;

const RangeInput = styled.input`
  width: 100%;
  margin-top: 10px;
`;

const FilterLabel = styled.label`
  display: block;
  margin-top: 15px;
  font-size: 14px;
  color: #555;
`;

const NoProductsMessage = styled.p`
  text-align: center;
  font-size: 18px;
  color: #999;
`;

// Product Component
const Product = () => {
  const [category, setCategory] = useState("All");
  const [priceRange, setPriceRange] = useState(1000); // Default range max
  const [filteredProducts, setFilteredProducts] = useState(products);

  const handleFilter = (e) => {
    const selectedCategory = e.target.value;
    setCategory(selectedCategory);

    const filtered = products.filter(
      (p) =>
        (selectedCategory === "All" || p.category === selectedCategory) &&
        p.price <= priceRange
    );
    setFilteredProducts(filtered);
  };

  const handlePriceChange = (e) => {
    const maxPrice = Number(e.target.value);
    setPriceRange(maxPrice);

    const filtered = products.filter(
      (p) =>
        (category === "All" || p.category === category) && p.price <= maxPrice
    );
    setFilteredProducts(filtered);
  };

  return (
    <Container>
      <FilterSection>
        <h2>Filters</h2>
        <FilterLabel>Category</FilterLabel>
        <select value={category} onChange={handleFilter}>
          <option value="All">All</option>
          <option value="Men">Men</option>
          <option value="Women">Women</option>
          <option value="Child">Child</option>
        </select>
        <FilterLabel>Price Range: 0 - {priceRange}</FilterLabel>
        <RangeInput
          type="range"
          min="0"
          max="10000"
          step="500"
          value={priceRange}
          onChange={handlePriceChange}
        />
        <p>Shopping Card Create by Sudhanshu Gaikwad</p>
      </FilterSection>

      <ProductSection>
        {filteredProducts.length > 0 ? (
          filteredProducts.map((product) => (
            <ProductCard key={product.id}>
              <img src={product.image} alt={product.name} />
              <h3>{product.name}</h3>
              <p>{product.price}</p>
              <button>Buy Now</button>
            </ProductCard>
          ))
        ) : (
          <NoProductsMessage>
            No products found within the selected filters.
          </NoProductsMessage>
        )}
      </ProductSection>
    </Container>
  );
};

export default Product;
Enter fullscreen mode Exit fullscreen mode

Output:

Key Features:

Filter Functionality
Seamlessly filter products by category and price range.
JSON Integration
Load product data dynamically from a JSON file.
Responsive Design
Adaptable layout for all device sizes.
Styled-Components
Modern CSS-in-JS for dynamic styling.

How This Project Helps You Grow?

  • React State Management: Learn to handle complex state for real-world apps.
  • Frontend-Backend Simulation: Use JSON to simulate database functionality.
  • UI/UX Skills: Design user-friendly, interactive interfaces.
  • Responsive Web Development: Master layout techniques for different screen sizes.

Top comments (0)