Skip to content

Commit

Permalink
Added cart feature
Browse files Browse the repository at this point in the history
  • Loading branch information
DeepaMittal committed Feb 19, 2024
1 parent 6e7440d commit 904e09d
Show file tree
Hide file tree
Showing 17 changed files with 326 additions and 158 deletions.
28 changes: 22 additions & 6 deletions car-ui-react/src/components/Elements/ProductCard.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
import React from 'react';
import carPicture from "../../assets/images/10001.avif"
import React, {useEffect, useState} from 'react';
import {useCart} from "../../context";


export const ProductCard = ({ product }) => {
const { brand, model, year, color, mileage, price, quantity, tax, poster, in_stock } = product;
const { cartList, addToCart, removeFromCart } = useCart();
const [inCart, setInCart] = useState(false);

useEffect(() => {
if (product) {
const productInCart = cartList.find(item => item.id === product.id);
if (productInCart) {
setInCart(true);
} else {
setInCart(false);
}
}
}, [cartList, product]);

if (!product) {
return null; // Or handle the case where product is undefined
return null;
}
const { carId, brand, model, year, color, mileage, price, quantity, tax, poster, in_stock } = product;


return (
<div className="m-3 max-w-sm bg-white rounded-lg border border-gray-200 shadow-md dark:bg-gray-800 dark:border-gray-700">
<a href="/" className="relative">
Expand Down Expand Up @@ -40,7 +55,8 @@ export const ProductCard = ({ product }) => {
<span className="text-2xl dark:text-gray-200">
<span>INR </span><span>{price}</span>
</span>
<button className='inline-flex items-center py-2 px-3 text-sm font-medium text-center text-white bg-blue-700 rounded-lg hover:bg-blue-800'>Add To Cart +</button>
{ !inCart && <button onClick={() => addToCart(product)} className={"inline-flex items-center py-2 px-3 text-sm font-medium text-center text-white bg-blue-700 rounded-lg hover:bg-blue-800"}>Add To Cart <i className="ml-1 bi bi-plus-lg"></i></button>}
{ inCart && <button onClick={() => removeFromCart(product)} className={"inline-flex items-center py-2 px-3 text-sm font-medium text-center text-white bg-red-600 rounded-lg hover:bg-red-800"}>Remove Item <i className="ml-1 bi bi-trash3"></i></button> }
</p>
</div>
</div>
Expand Down
4 changes: 3 additions & 1 deletion car-ui-react/src/components/Layout/Header.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import Logo from "../../assets/logo.png";
import {useCart} from "../../context";

export const Header = () => {
const [darkMode, setDarkMode] = useState(JSON.parse(localStorage.getItem("darkMode")) || false);
const {cartList} = useCart();

useEffect(() => {
localStorage.setItem("darkMode", JSON.stringify(darkMode));
Expand All @@ -28,7 +30,7 @@ export const Header = () => {
<span className="cursor-pointer text-xl text-gray-700 dark:text-white mr-5 bi bi-search"></span>
<Link to="/cart" className="text-gray-700 dark:text-white mr-5">
<span className="text-2xl bi bi-cart-fill relative">
<span className="text-white text-sm absolute -top-1 left-2.5 bg-rose-500 px-1 rounded-full ">0</span>
<span className="text-white text-sm absolute -top-1 left-2.5 bg-rose-500 px-1 rounded-full ">{cartList.length}</span>
</span>
</Link>
<span className="bi bi-person-circle cursor-pointer text-2xl text-gray-700 dark:text-white"></span>
Expand Down
Empty file removed car-ui-react/src/context/.gitkeep
Empty file.
68 changes: 68 additions & 0 deletions car-ui-react/src/context/CartContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { createContext, useContext, useReducer } from "react";
import { cartReducer } from "../reducers";

const cartInitialState = {
cartList: [],
total: 0
}

const CartContext = createContext(cartInitialState);

export const CartProvider = ({children}) => {
const [state, dispatch] = useReducer(cartReducer, cartInitialState);

function addToCart(product){
const updatedList = state.cartList.concat(product);
const updatedTotal = state.total + product.price;

dispatch({
type: "ADD_TO_CART",
payload: {
products: updatedList,
total: updatedTotal
}
})
}

function removeFromCart(product){
const updatedList = state.cartList.filter(item => item.id !== product.id);
const updatedTotal = state.total - product.price;

dispatch({
type: "REMOVE_FROM_CART",
payload: {
products: updatedList,
total: updatedTotal
}
})
}

function clearCart(){
dispatch({
type: "CLEAR_CART",
payload: {
products: [],
total: 0
}
})
}

const value = {
cartList: state.cartList,
total: state.total,
addToCart,
removeFromCart,
clearCart
}

return (
<CartContext.Provider value={value}>
{children}
</CartContext.Provider>
)
}

export const useCart = () => {
const context = useContext(CartContext);
return context;
}
78 changes: 78 additions & 0 deletions car-ui-react/src/context/FilterContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { createContext, useContext, useReducer } from "react"
import { filterReducer } from "../reducers";

const filterInitialState = {
productList: [],
onlyInStock: false,
bestSellerOnly: false,
sortBy: null,
ratings: null
}

const FilterContext = createContext(filterInitialState);

export const FilterProvider = ({children}) => {
const [state, dispatch] = useReducer(filterReducer, filterInitialState);

function initialProductList(products){
dispatch({
type: "PRODUCT_LIST",
payload: {
products: products
}
});
}

function bestSeller(products){
return state.bestSellerOnly ? products.filter(product => product.best_seller === true) : products;
}

function inStock(products){
return state.onlyInStock ? products.filter(product => product.in_stock === true) : products;
}

function sort(products){
if(state.sortBy === "lowtohigh"){
return products.sort((a, b) => Number(a.price) - Number(b.price));
}
if(state.sortBy === "hightolow"){
return products.sort((a, b) => Number(b.price) - Number(a.price));
}
return products;
}

function rating(products){
if(state.ratings === "4STARSABOVE"){
return products.filter(product => product.rating >= 4);
}
if(state.ratings === "3STARSABOVE"){
return products.filter(product => product.rating >= 3);
}
if(state.ratings === "2STARSABOVE"){
return products.filter(product => product.rating >= 2);
}
if(state.ratings === "1STARSABOVE"){
return products.filter(product => product.rating >= 1);
}
return products;
}

const filteredProductList = rating(sort(inStock(bestSeller(state.productList))));

const value = {
state,
dispatch,
products: filteredProductList,
initialProductList
}
return (
<FilterContext.Provider value={value}>
{children}
</FilterContext.Provider>
)
}

export const useFilter = () => {
const context = useContext(FilterContext);
return context;
}
2 changes: 2 additions & 0 deletions car-ui-react/src/context/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { useFilter, FilterProvider } from "./FilterContext";
export { useCart, CartProvider } from "./CartContext";
139 changes: 0 additions & 139 deletions car-ui-react/src/data/db.json

This file was deleted.

6 changes: 0 additions & 6 deletions car-ui-react/src/data/routes.json

This file was deleted.

7 changes: 6 additions & 1 deletion car-ui-react/src/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter as Router } from 'react-router-dom';
import {CartProvider, FilterProvider} from "./context";
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Router>
<App />
<CartProvider>
<FilterProvider>
<App />
</FilterProvider>
</CartProvider>
</Router>
</React.StrictMode>
);
Expand Down
Loading

0 comments on commit 904e09d

Please sign in to comment.