From 223b63b453a02779c82320880794889cd0093c8a Mon Sep 17 00:00:00 2001 From: raj shringi Date: Wed, 23 Nov 2022 23:47:42 +0530 Subject: [PATCH 1/5] create store and actions file --- src/store/actions.js | 6 ++++++ src/store/index.js | 23 +++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/store/actions.js create mode 100644 src/store/index.js diff --git a/src/store/actions.js b/src/store/actions.js new file mode 100644 index 0000000..3ce3309 --- /dev/null +++ b/src/store/actions.js @@ -0,0 +1,6 @@ +export default function selectSize(size) { + return { + type: "select_size", + payload: size, + }; +} diff --git a/src/store/index.js b/src/store/index.js new file mode 100644 index 0000000..4cddfdf --- /dev/null +++ b/src/store/index.js @@ -0,0 +1,23 @@ +import { createStore } from "redux"; + +const initialState = { + sizes: [], + cart: [], +}; + +function reducer(state = initialState, action) { + switch (action.type) { + case "select_size": + return state.sizes.includes(action.payload) + ? { + ...state, + sizes: state.sizes.filter((size) => size !== action.payload), + } + : { ...state, sizes: [...state.sizes, action.payload] }; + default: + return state; + } +} + +let store = createStore(reducer); +export default store; From 765549295f0676aaad3138a22a8ae92c64592c24 Mon Sep 17 00:00:00 2001 From: raj shringi Date: Wed, 23 Nov 2022 23:48:35 +0530 Subject: [PATCH 2/5] add redux and react-redux package --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 91dcbdd..fd868b4 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,9 @@ "@testing-library/user-event": "^7.1.2", "react": "^17.0.1", "react-dom": "^17.0.1", - "react-scripts": "^4.0.2" + "react-redux": "^8.0.5", + "react-scripts": "^4.0.2", + "redux": "^4.2.0" }, "scripts": { "start": "react-scripts start", From d2cd1ac804517ca4c71709dfc261b3500fa03869 Mon Sep 17 00:00:00 2001 From: raj shringi Date: Wed, 23 Nov 2022 23:49:19 +0530 Subject: [PATCH 3/5] handle select size by user and filter products according to sizes --- src/components/Products.js | 23 ++++++++++--- src/components/Sidebar.js | 20 ++++++++++-- src/index.js | 9 +++++- yarn.lock | 66 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 111 insertions(+), 7 deletions(-) diff --git a/src/components/Products.js b/src/components/Products.js index 70f47d8..c9a860c 100644 --- a/src/components/Products.js +++ b/src/components/Products.js @@ -1,5 +1,6 @@ import React from "react"; import OrderBy from "./OrderBy"; +import { connect } from "react-redux"; class Products extends React.Component { constructor(props) { @@ -25,7 +26,15 @@ class Products extends React.Component { render() { let { selectedOrder } = this.state; - let products = this.handleOrderProducts(selectedOrder, this.props.data); + + const data = + this.props.sizes.length !== 0 + ? this.props.data.filter((item) => + item.availableSizes.some((size) => this.props.sizes.includes(size)) + ) + : this.props.data; + + let products = this.handleOrderProducts(selectedOrder, data); return (
@@ -41,8 +50,8 @@ class Products extends React.Component { />
- {products.map((product) => ( - + {products.map((product, index) => ( + ))}
@@ -70,4 +79,10 @@ function Product(props) { ); } -export default Products; +export default connect(mapStateToProps)(Products); + +function mapStateToProps(state) { + return { + sizes: state.sizes, + }; +} diff --git a/src/components/Sidebar.js b/src/components/Sidebar.js index a05b530..73e9c73 100644 --- a/src/components/Sidebar.js +++ b/src/components/Sidebar.js @@ -1,14 +1,30 @@ +import { useDispatch, useSelector } from "react-redux"; +import selectSize from "../store/actions"; function Sidebar({ products }) { let sizes = products.reduce((acc, cv) => { acc = acc.concat(cv.availableSizes); return acc; }, []); let uniqueSizes = [...new Set(sizes)]; + + const dispatch = useDispatch(); + const sizesState = useSelector((state) => state.sizes); + + const handleClick = (size) => { + dispatch(selectSize(size)); + }; + return ( diff --git a/src/index.js b/src/index.js index 47e9199..0fa581e 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,13 @@ import React from "react"; import { render } from "react-dom"; +import { Provider } from "react-redux"; import App from "./components/App"; import "./style/index.css"; +import store from "../src/store"; -render(, document.getElementById("root")); +render( + + + , + document.getElementById("root") +); diff --git a/yarn.lock b/yarn.lock index 91f0999..be14c4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1179,6 +1179,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.12.1", "@babel/runtime@^7.9.2": + version "7.20.1" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.1.tgz#1148bb33ab252b165a06698fde7576092a78b4a9" + integrity sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg== + dependencies: + regenerator-runtime "^0.13.10" + "@babel/runtime@^7.5.1", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2": version "7.7.6" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.6.tgz#d18c511121aff1b4f2cd1d452f1bac9601dd830f" @@ -1843,6 +1850,14 @@ dependencies: "@types/node" "*" +"@types/hoist-non-react-statics@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" + integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + "@types/html-minifier-terser@^5.0.0": version "5.1.1" resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#3c9ee980f1a10d6021ae6632ca3e79ca2ec4fb50" @@ -1989,6 +2004,11 @@ dependencies: source-map "^0.6.1" +"@types/use-sync-external-store@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43" + integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA== + "@types/webpack-sources@*": version "2.1.0" resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-2.1.0.tgz#8882b0bd62d1e0ce62f183d0d01b72e6e82e8c10" @@ -5735,6 +5755,13 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" +hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + hoopy@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" @@ -9551,6 +9578,11 @@ react-error-overlay@^6.0.9: resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew== +react-is@^16.7.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + react-is@^16.8.1, react-is@^16.8.4: version "16.12.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c" @@ -9561,6 +9593,23 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +react-redux@^8.0.5: + version "8.0.5" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.0.5.tgz#e5fb8331993a019b8aaf2e167a93d10af469c7bd" + integrity sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw== + dependencies: + "@babel/runtime" "^7.12.1" + "@types/hoist-non-react-statics" "^3.3.1" + "@types/use-sync-external-store" "^0.0.3" + hoist-non-react-statics "^3.3.2" + react-is "^18.0.0" + use-sync-external-store "^1.0.0" + react-refresh@^0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" @@ -9729,6 +9778,13 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" +redux@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.0.tgz#46f10d6e29b6666df758780437651eeb2b969f13" + integrity sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA== + dependencies: + "@babel/runtime" "^7.9.2" + regenerate-unicode-properties@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" @@ -9746,6 +9802,11 @@ regenerator-runtime@^0.11.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== +regenerator-runtime@^0.13.10: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + regenerator-runtime@^0.13.2: version "0.13.3" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" @@ -11452,6 +11513,11 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" +use-sync-external-store@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" From b751b89a9b6eebeb2d4da9e86918555913746756 Mon Sep 17 00:00:00 2001 From: raj shringi Date: Thu, 24 Nov 2022 16:04:39 +0530 Subject: [PATCH 4/5] show correct count of product --- src/components/Products.js | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/components/Products.js b/src/components/Products.js index c9a860c..3b630d3 100644 --- a/src/components/Products.js +++ b/src/components/Products.js @@ -1,6 +1,8 @@ import React from "react"; import OrderBy from "./OrderBy"; import { connect } from "react-redux"; +import { useDispatch } from "react-redux"; +import { addProductToCart } from "../store/actions"; class Products extends React.Component { constructor(props) { @@ -39,19 +41,15 @@ class Products extends React.Component { return (
-

- {`${this.props.data.length} Product${ - this.props.data.length > 1 ? "s" : "" - } found.`}{" "} -

+

{`${data.length} Product${data.length > 1 ? "s" : ""} found.`}

- {products.map((product, index) => ( - + {products.map((product) => ( + ))}
@@ -60,6 +58,12 @@ class Products extends React.Component { } function Product(props) { + const dispatch = useDispatch(); + + const handleClick = (product) => { + dispatch(addProductToCart(product)); + }; + return (
Free Shipping
@@ -74,7 +78,17 @@ function Product(props) {

{props.currencyFormat + props.price}

- +
); From 0048cc6f14963a33638711945e1d7f5da9f855ad Mon Sep 17 00:00:00 2001 From: raj shringi Date: Thu, 24 Nov 2022 16:05:52 +0530 Subject: [PATCH 5/5] handle add item to cart, remove item, increase and decrease quantity and get subtotal of cart --- src/components/Cart.js | 96 ++++++++++++++++++++++++-------------- src/components/CartItem.js | 93 ++++++++++++++++++++++-------------- src/store/actions.js | 28 +++++++++++ src/store/index.js | 36 ++++++++++++++ 4 files changed, 183 insertions(+), 70 deletions(-) diff --git a/src/components/Cart.js b/src/components/Cart.js index c51b442..ea6334d 100644 --- a/src/components/Cart.js +++ b/src/components/Cart.js @@ -1,5 +1,6 @@ -import React from 'react'; -import CartItem from './CartItem'; +import React from "react"; +import CartItem from "./CartItem"; +import { connect } from "react-redux"; class Cart extends React.Component { constructor(props) { @@ -14,46 +15,65 @@ class Cart extends React.Component { open = () => { this.setState({ isOpen: true }); }; + totalItemsInCart = () => { + return this.props.cart.reduce((acc, cur) => { + acc += cur.quantity; + return acc; + }, 0); + }; + subTotal = () => { + return this.props.cart.reduce((acc, cur) => { + acc += cur.price * cur.quantity; + return acc; + }, 0); + }; + alertSubTotal = () => { + alert(`Checkout - Subtotal: $ ${this.subTotal().toFixed(2)}`); + }; render() { const { isOpen } = this.state; if (!isOpen) { - return ; + return ( + + ); } return ( -