├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── public
├── assets
│ └── main.png.jpg
├── favicon.ico
├── index.html
└── robots.txt
└── src
├── components
├── Footer.jsx
├── Navbar.jsx
├── Products.jsx
├── index.js
└── main.jsx
├── index.js
├── pages
├── AboutPage.jsx
├── Cart.jsx
├── Checkout.jsx
├── ContactPage.jsx
├── Home.jsx
├── Login.jsx
├── PageNotFound.jsx
├── Product.jsx
├── Products.jsx
├── Register.jsx
└── index.js
└── redux
├── action
└── index.js
├── reducer
├── handleCart.js
└── index.js
└── store.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # E-Commerce Website
2 |
3 | A Ecommerce Website made with React.js Framework.
4 |
5 |
6 | ## Demo
7 |
8 | https://reactjs-ecommerce-app.vercel.app/
9 |
10 |
11 | ## Features
12 |
13 | - Easy to integrate with Backend
14 | - Fully Responsive
15 |
16 |
17 | ## Run Locally
18 |
19 | Clone the project
20 |
21 | ```bash
22 | git clone https://github.com/ssahibsingh/React_E-Commerce
23 | ```
24 |
25 | Go to the project directory
26 |
27 | ```bash
28 | cd React_E-Commerce
29 | ```
30 |
31 | Install dependencies
32 |
33 | ```bash
34 | npm install
35 | ```
36 |
37 | Start the server
38 |
39 | ```bash
40 | npm start
41 | ```
42 |
43 |
44 | ## Screenshots
45 |
46 | 
47 |
48 |
49 | ## Tech Stack
50 |
51 | * [React](https://reactjs.org/)
52 | * [Redux](https://redux.js.org/)
53 | * [Bootstrap](https://getbootstrap.com/)
54 | * [Fake Store API](https://fakestoreapi.com/)
55 |
56 |
57 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ecommerce",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@reduxjs/toolkit": "^1.8.5",
7 | "@testing-library/jest-dom": "^5.16.5",
8 | "@testing-library/react": "^13.4.0",
9 | "@testing-library/user-event": "^13.5.0",
10 | "bootstrap": "^5.2.1",
11 | "font-awesome": "^4.7.0",
12 | "react": "^18.2.0",
13 | "react-dom": "^18.2.0",
14 | "react-fast-marquee": "^1.3.5",
15 | "react-loading-skeleton": "^3.1.0",
16 | "react-redux": "^8.0.2",
17 | "react-router-dom": "^6.4.0",
18 | "react-scripts": "5.0.1",
19 | "redux": "^4.2.0",
20 | "web-vitals": "^2.1.4"
21 | },
22 | "scripts": {
23 | "start": "react-scripts start",
24 | "build": "react-scripts build",
25 | "test": "react-scripts test",
26 | "eject": "react-scripts eject"
27 | },
28 | "eslintConfig": {
29 | "extends": [
30 | "react-app",
31 | "react-app/jest"
32 | ]
33 | },
34 | "browserslist": {
35 | "production": [
36 | ">0.2%",
37 | "not dead",
38 | "not op_mini all"
39 | ],
40 | "development": [
41 | "last 1 chrome version",
42 | "last 1 firefox version",
43 | "last 1 safari version"
44 | ]
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/public/assets/main.png.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crypto27dev/react_eCommerce/ab95f6a240528a2f0c94a2ba77e6bed37c3a7fa6/public/assets/main.png.jpg
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crypto27dev/react_eCommerce/ab95f6a240528a2f0c94a2ba77e6bed37c3a7fa6/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Ecommerce Website
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
32 |
33 |
34 |
35 |
37 |
40 |
41 |
42 |
43 | You need to enable JavaScript to run this app.
44 |
45 |
46 |
47 |
50 |
53 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/src/components/Footer.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Footer = () => {
4 | return (
5 | <>
6 |
18 | >
19 | );
20 | };
21 |
22 | export default Footer;
23 |
--------------------------------------------------------------------------------
/src/components/Navbar.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { NavLink } from 'react-router-dom'
3 | import { useSelector } from 'react-redux'
4 |
5 | const Navbar = () => {
6 | const state = useSelector(state => state.handleCart)
7 | return (
8 |
9 |
10 |
React Ecommerce
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | Home
19 |
20 |
21 | Products
22 |
23 |
24 | About
25 |
26 |
27 | Contact
28 |
29 |
30 |
31 | Login
32 | Register
33 | Cart ({state.length})
34 |
35 |
36 |
37 |
38 |
39 |
40 | )
41 | }
42 |
43 | export default Navbar
--------------------------------------------------------------------------------
/src/components/Products.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import { useDispatch } from "react-redux";
3 | import { addCart } from "../redux/action";
4 |
5 | import Skeleton from "react-loading-skeleton";
6 | import "react-loading-skeleton/dist/skeleton.css";
7 |
8 | import { Link } from "react-router-dom";
9 |
10 | const Products = () => {
11 | const [data, setData] = useState([]);
12 | const [filter, setFilter] = useState(data);
13 | const [loading, setLoading] = useState(false);
14 | let componentMounted = true;
15 |
16 | const dispatch = useDispatch();
17 |
18 | const addProduct = (product) => {
19 | dispatch(addCart(product))
20 | }
21 |
22 | useEffect(() => {
23 | const getProducts = async () => {
24 | setLoading(true);
25 | const response = await fetch("https://fakestoreapi.com/products/");
26 | if (componentMounted) {
27 | setData(await response.clone().json());
28 | setFilter(await response.json());
29 | setLoading(false);
30 | }
31 |
32 | return () => {
33 | componentMounted = false;
34 | };
35 | };
36 |
37 | getProducts();
38 | }, []);
39 |
40 | const Loading = () => {
41 | return (
42 | <>
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | >
65 | );
66 | };
67 |
68 | const filterProduct = (cat) => {
69 | const updatedList = data.filter((item) => item.category === cat);
70 | setFilter(updatedList);
71 | }
72 | const ShowProducts = () => {
73 | return (
74 | <>
75 |
76 | setFilter(data)}>All
77 | filterProduct("men's clothing")}>Men's Clothing
78 | filterProduct("women's clothing")}>
79 | Women's Clothing
80 |
81 | filterProduct("jewelery")}>Jewelery
82 | filterProduct("electronics")}>Electronics
83 |
84 |
85 | {filter.map((product) => {
86 | return (
87 |
88 |
89 |
95 |
96 |
97 | {product.title.substring(0, 12)}...
98 |
99 |
100 | {product.description.substring(0, 90)}...
101 |
102 |
103 |
104 | $ {product.price}
105 | {/* Dapibus ac facilisis in
106 | Vestibulum at eros */}
107 |
108 |
109 |
110 | Buy Now
111 |
112 | addProduct(product)}>
113 | Add to Cart
114 |
115 |
116 |
117 |
118 |
119 | );
120 | })}
121 | >
122 | );
123 | };
124 | return (
125 | <>
126 |
127 |
128 |
129 |
Latest Products
130 |
131 |
132 |
133 |
134 | {loading ? : }
135 |
136 |
137 | >
138 | );
139 | };
140 |
141 | export default Products;
142 |
--------------------------------------------------------------------------------
/src/components/index.js:
--------------------------------------------------------------------------------
1 | export { default as Navbar } from './Navbar';
2 | export { default as Main } from './main';
3 | export { default as Product } from './Products';
4 | export { default as Footer } from './Footer';
--------------------------------------------------------------------------------
/src/components/main.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Home = () => {
4 | return (
5 | <>
6 |
7 |
8 |
14 |
15 |
16 |
New Season Arrivals
17 |
18 | This is a wider card with supporting text below as a natural
19 | lead-in to additional content. This content is a little bit
20 | longer.
21 |
22 |
23 |
24 |
25 |
26 | >
27 | );
28 | };
29 |
30 | export default Home;
31 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import '../node_modules/font-awesome/css/font-awesome.min.css';
4 | import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
5 | import { BrowserRouter, Routes, Route } from 'react-router-dom';
6 | import { Provider } from 'react-redux';
7 | import store from './redux/store';
8 |
9 |
10 | import { Home, Product, Products, AboutPage, ContactPage, Cart, Login, Register, Checkout, PageNotFound } from "./pages"
11 |
12 | const root = ReactDOM.createRoot(document.getElementById('root'));
13 | root.render(
14 |
15 |
16 |
17 | } />
18 | } />
19 | } />
20 | } />
21 | } />
22 | } />
23 | } />
24 | } />
25 | } />
26 | } />
27 | } />
28 |
29 |
30 |
31 | );
--------------------------------------------------------------------------------
/src/pages/AboutPage.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Footer, Navbar } from "../components";
3 | const AboutPage = () => {
4 | return (
5 | <>
6 |
7 |
8 |
About Us
9 |
10 |
11 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Nostrum
12 | facere doloremque veritatis odit similique sequi. Odit amet fuga nam
13 | quam quasi facilis sed doloremque saepe sint perspiciatis explicabo
14 | totam vero quas provident ipsam, veritatis nostrum velit quos
15 | recusandae est mollitia esse fugit dolore laudantium. Ex vel explicabo
16 | earum unde eligendi autem praesentium, doloremque distinctio nesciunt
17 | porro tempore quis eaque labore voluptatibus ea necessitatibus
18 | exercitationem tempora molestias. Ad consequuntur veniam sequi ullam
19 | tempore vel tenetur soluta dolore sunt maxime aliquam corporis est,
20 | quo saepe dolorem optio minus sint nemo totam dolorum! Reprehenderit
21 | delectus expedita a alias nam recusandae illo debitis repellat libero,
22 | quasi explicabo molestiae saepe, dolorem tempore itaque eveniet quam
23 | dignissimos blanditiis excepturi harum numquam vel nihil? Ipsum
24 |
25 |
26 |
Our Products
27 |
28 |
29 |
30 |
31 |
32 |
Mens's Clothing
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
Women's Clothing
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
Jewelery
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
Electronics
57 |
58 |
59 |
60 |
61 |
62 |
63 | >
64 | )
65 | }
66 |
67 | export default AboutPage
--------------------------------------------------------------------------------
/src/pages/Cart.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Footer, Navbar } from "../components";
3 | import { useSelector, useDispatch } from "react-redux";
4 | import { addCart, delCart } from "../redux/action";
5 | import { Link } from "react-router-dom";
6 |
7 | const Cart = () => {
8 | const state = useSelector((state) => state.handleCart);
9 | const dispatch = useDispatch();
10 |
11 | const EmptyCart = () => {
12 | return (
13 |
14 |
15 |
16 |
Your Cart is Empty
17 |
18 | Continue Shopping
19 |
20 |
21 |
22 |
23 | );
24 | };
25 |
26 | const addItem = (product) => {
27 | dispatch(addCart(product));
28 | };
29 | const removeItem = (product) => {
30 | dispatch(delCart(product));
31 | };
32 |
33 | const ShowCart = () => {
34 | let subtotal = 0;
35 | let shipping = 30.0;
36 | let totalItems = 0;
37 | state.map((item) => {
38 | return (subtotal += item.price * item.qty);
39 | });
40 |
41 | state.map((item) => {
42 | return (totalItems += item.qty);
43 | });
44 | return (
45 | <>
46 |
47 |
48 |
49 |
50 |
51 |
52 |
Item List
53 |
54 |
55 | {state.map((item) => {
56 | return (
57 |
58 |
59 |
60 |
64 |
71 |
72 |
73 |
74 |
75 |
76 | {item.title}
77 |
78 | {/*
Color: blue
79 |
Size: M
*/}
80 |
81 |
82 |
83 |
87 |
{
90 | removeItem(item);
91 | }}
92 | >
93 |
94 |
95 |
96 |
{item.qty}
97 |
98 |
{
101 | addItem(item);
102 | }}
103 | >
104 |
105 |
106 |
107 |
108 |
109 |
110 | {item.qty} {" "}
111 | x ${item.price}
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | );
120 | })}
121 |
122 |
123 |
124 |
125 |
126 |
127 |
Order Summary
128 |
129 |
130 |
131 |
132 | Products ({totalItems})${Math.round(subtotal)}
133 |
134 |
135 | Shipping
136 | ${shipping}
137 |
138 |
139 |
140 | Total amount
141 |
142 |
143 | ${Math.round(subtotal + shipping)}
144 |
145 |
146 |
147 |
148 |
152 | Go to checkout
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 | >
161 | );
162 | };
163 |
164 | return (
165 | <>
166 |
167 |
168 |
Cart
169 |
170 | {state.length > 0 ? : }
171 |
172 |
173 | >
174 | );
175 | };
176 |
177 | export default Cart;
178 |
--------------------------------------------------------------------------------
/src/pages/Checkout.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Footer, Navbar } from "../components";
3 | import { useSelector } from "react-redux";
4 | import { Link } from "react-router-dom";
5 | const Checkout = () => {
6 | const state = useSelector((state) => state.handleCart);
7 |
8 | const EmptyCart = () => {
9 | return (
10 |
11 |
12 |
13 |
No item in Cart
14 |
15 | Continue Shopping
16 |
17 |
18 |
19 |
20 | );
21 | };
22 |
23 | const ShowCheckout = () => {
24 | let subtotal = 0;
25 | let shipping = 30.0;
26 | let totalItems = 0;
27 | state.map((item) => {
28 | return (subtotal += item.price * item.qty);
29 | });
30 |
31 | state.map((item) => {
32 | return (totalItems += item.qty);
33 | });
34 | return (
35 | <>
36 |
37 |
38 |
39 |
40 |
41 |
Order Summary
42 |
43 |
44 |
45 |
46 | Products ({totalItems})${Math.round(subtotal)}
47 |
48 |
49 | Shipping
50 | ${shipping}
51 |
52 |
53 |
54 | Total amount
55 |
56 |
57 | ${Math.round(subtotal + shipping)}
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
Billing address
68 |
69 |
280 |
281 |
282 |
283 |
284 | >
285 | );
286 | };
287 | return (
288 | <>
289 |
290 |
291 |
Checkout
292 |
293 | {state.length ? : }
294 |
295 |
296 | >
297 | );
298 | };
299 |
300 | export default Checkout;
301 |
--------------------------------------------------------------------------------
/src/pages/ContactPage.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Footer, Navbar } from "../components";
3 | const ContactPage = () => {
4 | return (
5 | <>
6 |
7 |
8 |
Contact Us
9 |
10 |
52 |
53 |
54 | >
55 | );
56 | };
57 |
58 | export default ContactPage;
59 |
--------------------------------------------------------------------------------
/src/pages/Home.jsx:
--------------------------------------------------------------------------------
1 | import { Navbar, Main, Product, Footer } from "../components";
2 |
3 | function Home() {
4 | return (
5 | <>
6 |
7 |
8 |
9 |
10 | >
11 | )
12 | }
13 |
14 | export default Home
--------------------------------------------------------------------------------
/src/pages/Login.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 | import { Footer, Navbar } from "../components";
4 |
5 | const Login = () => {
6 | return (
7 | <>
8 |
9 |
10 |
Login
11 |
12 |
13 |
14 |
15 |
16 | Email address
17 |
23 |
24 |
25 | Password
26 |
32 |
33 |
34 |
New Here? Register
35 |
36 |
37 |
38 | Login
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | >
47 | );
48 | };
49 |
50 | export default Login;
51 |
--------------------------------------------------------------------------------
/src/pages/PageNotFound.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 | import { Navbar } from "../components";
4 |
5 | const PageNotFound = () => {
6 | return (
7 | <>
8 |
9 |
10 |
11 |
12 |
13 |
404: Page Not Found
14 |
15 | Go Back to Home
16 |
17 |
18 |
19 |
20 |
21 | >
22 | );
23 | };
24 |
25 | export default PageNotFound;
26 |
--------------------------------------------------------------------------------
/src/pages/Product.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import Skeleton from "react-loading-skeleton";
3 | import { Link, useParams } from "react-router-dom";
4 | import Marquee from "react-fast-marquee";
5 | import { useDispatch } from "react-redux";
6 | import { addCart } from "../redux/action";
7 |
8 | import { Footer, Navbar } from "../components";
9 |
10 | const Product = () => {
11 | const { id } = useParams();
12 | const [product, setProduct] = useState([]);
13 | const [similarProducts, setSimilarProducts] = useState([]);
14 | const [loading, setLoading] = useState(false);
15 | const [loading2, setLoading2] = useState(false);
16 |
17 | const dispatch = useDispatch();
18 |
19 | const addProduct = (product) => {
20 | dispatch(addCart(product));
21 | };
22 |
23 | useEffect(() => {
24 | const getProduct = async () => {
25 | setLoading(true);
26 | setLoading2(true);
27 | const response = await fetch(`https://fakestoreapi.com/products/${id}`);
28 | const data = await response.json();
29 | setProduct(data);
30 | setLoading(false);
31 | const response2 = await fetch(
32 | `https://fakestoreapi.com/products/category/${data.category}`
33 | );
34 | const data2 = await response2.json();
35 | setSimilarProducts(data2);
36 | setLoading2(false);
37 | };
38 | getProduct();
39 | }, [id]);
40 |
41 | const Loading = () => {
42 | return (
43 | <>
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | >
61 | );
62 | };
63 |
64 | const ShowProduct = () => {
65 | return (
66 | <>
67 |
68 |
69 |
70 |
77 |
78 |
79 |
{product.category}
80 |
{product.title}
81 |
82 | {product.rating && product.rating.rate}{" "}
83 |
84 |
85 |
${product.price}
86 |
{product.description}
87 |
addProduct(product)}
90 | >
91 | Add to Cart
92 |
93 |
94 | Go to Cart
95 |
96 |
97 |
98 |
99 | >
100 | );
101 | };
102 |
103 | const Loading2 = () => {
104 | return (
105 | <>
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | >
123 | );
124 | };
125 |
126 | const ShowSimilarProduct = () => {
127 | return (
128 | <>
129 |
130 |
131 | {similarProducts.map((item) => {
132 | return (
133 |
134 |
141 |
142 |
143 | {item.title.substring(0, 15)}...
144 |
145 |
146 | {/*
147 | ${product.price}
148 | */}
149 |
150 |
154 | Buy Now
155 |
156 | addProduct(item)}
159 | >
160 | Add to Cart
161 |
162 |
163 |
164 | );
165 | })}
166 |
167 |
168 | >
169 | );
170 | };
171 | return (
172 | <>
173 |
174 |
175 |
{loading ? : }
176 |
177 |
178 |
You may also Like
179 |
184 | {loading2 ? : }
185 |
186 |
187 |
188 |
189 |
190 | >
191 | );
192 | };
193 |
194 | export default Product;
195 |
--------------------------------------------------------------------------------
/src/pages/Products.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Footer, Navbar, Product } from "../components"
3 |
4 | const Products = () => {
5 | return (
6 | <>
7 |
8 |
9 |
10 | >
11 | )
12 | }
13 |
14 | export default Products
--------------------------------------------------------------------------------
/src/pages/Register.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Footer, Navbar } from "../components";
3 | import { Link } from 'react-router-dom';
4 | const Register = () => {
5 | return (
6 | <>
7 |
8 |
9 |
Register
10 |
11 |
12 |
13 |
14 |
15 | Full Name
16 |
22 |
23 |
24 | Email address
25 |
31 |
32 |
33 | Password
34 |
40 |
41 |
42 |
Already has an account? Login
43 |
44 |
45 |
46 | Register
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | >
55 | )
56 | }
57 |
58 | export default Register
--------------------------------------------------------------------------------
/src/pages/index.js:
--------------------------------------------------------------------------------
1 | export { default as Home } from './Home';
2 | export { default as Products } from './Products';
3 | export { default as Product } from './Product';
4 | export { default as AboutPage } from './AboutPage';
5 | export { default as ContactPage } from './ContactPage';
6 | export { default as Cart } from './Cart';
7 | export { default as Login } from './Login';
8 | export { default as Register } from './Register';
9 | export { default as Checkout } from './Checkout';
10 | export { default as PageNotFound } from './PageNotFound';
--------------------------------------------------------------------------------
/src/redux/action/index.js:
--------------------------------------------------------------------------------
1 | // For Add Item to Cart
2 | export const addCart = (product) =>{
3 | return {
4 | type:"ADDITEM",
5 | payload:product
6 | }
7 | }
8 |
9 | // For Delete Item to Cart
10 | export const delCart = (product) =>{
11 | return {
12 | type:"DELITEM",
13 | payload:product
14 | }
15 | }
--------------------------------------------------------------------------------
/src/redux/reducer/handleCart.js:
--------------------------------------------------------------------------------
1 | const cart = []
2 |
3 | const handleCart = (state=cart, action) =>{
4 | const product = action.payload
5 | switch(action.type){
6 | case "ADDITEM":
7 | // Check if product already in cart
8 | const exist = state.find((x) => x.id === product.id)
9 | if(exist){
10 | // Increase the quantity
11 | return state.map((x)=>x.id ===product.id?{...x, qty: x.qty+1}:x)
12 | }
13 | else{
14 | return [...state, {...product, qty:1}]
15 | }
16 | break;
17 | case "DELITEM":
18 | const exist2 = state.find((x) => x.id === product.id)
19 | if(exist2.qty === 1){
20 | return state.filter((x)=>x.id!==exist2.id)
21 | }
22 | else{
23 | return state.map((x)=> x.id===product.id?{...x, qty:x.qty-1}:x)
24 | }
25 | break;
26 |
27 | default:
28 | return state
29 | break;
30 | }
31 | }
32 |
33 | export default handleCart
--------------------------------------------------------------------------------
/src/redux/reducer/index.js:
--------------------------------------------------------------------------------
1 | import handleCart from './handleCart'
2 | import { combineReducers } from "redux";
3 | const rootReducers = combineReducers({
4 | handleCart,
5 | })
6 | export default rootReducers
--------------------------------------------------------------------------------
/src/redux/store.js:
--------------------------------------------------------------------------------
1 | import {configureStore} from '@reduxjs/toolkit';
2 | import rootReducers from './reducer';
3 | const store = configureStore({
4 | reducer: rootReducers,
5 |
6 | })
7 |
8 | export default store;
9 |
--------------------------------------------------------------------------------