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
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"
}
]
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;
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)