From 8510e9a70277759eec451d575adca5f0d800a387 Mon Sep 17 00:00:00 2001 From: rodrigcasio Date: Wed, 10 Sep 2025 15:37:06 -0600 Subject: [PATCH 01/15] Added gh-pages into the file "package.json" --- package-lock.json | 235 ++++++++++++++++++++++++++++++++++------------ package.json | 4 +- 2 files changed, 178 insertions(+), 61 deletions(-) diff --git a/package-lock.json b/package-lock.json index af7843d848..3e89598b75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "eslint-plugin-react": "^7.34.1", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.6", - "gh-pages": "^6.1.1", + "gh-pages": "^6.3.0", "vite": "^5.2.0" } }, @@ -1364,24 +1364,13 @@ } }, "node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/array.prototype.findlast": { @@ -1524,6 +1513,19 @@ "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/browserslist": { "version": "4.23.0", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", @@ -1634,12 +1636,13 @@ "dev": true }, "node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/commondir": { @@ -1788,6 +1791,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -2336,6 +2352,36 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -2395,6 +2441,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", @@ -2573,18 +2632,19 @@ } }, "node_modules/gh-pages": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.1.1.tgz", - "integrity": "sha512-upnohfjBwN5hBP9w2dPE7HO5JJTHzSGMV1JrLrHvNuqmjoYHg6TBrCcnEoorjG/e0ejbuvnwyKMdTyM40PEByw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.3.0.tgz", + "integrity": "sha512-Ot5lU6jK0Eb+sszG8pciXdjMXdBJ5wODvgjR+imihTqsUWF2K6dJ9HST55lgqcs8wWcw6o6wAsUzfcYRhJPXbA==", "dev": true, + "license": "MIT", "dependencies": { "async": "^3.2.4", - "commander": "^11.0.0", + "commander": "^13.0.0", "email-addresses": "^5.0.0", "filenamify": "^4.3.0", "find-cache-dir": "^3.3.1", "fs-extra": "^11.1.1", - "globby": "^6.1.0" + "globby": "^11.1.0" }, "bin": { "gh-pages": "bin/gh-pages.js", @@ -2651,19 +2711,24 @@ } }, "node_modules/globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/gopd": { @@ -3029,6 +3094,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/is-number-object": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", @@ -3370,6 +3445,30 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3639,40 +3738,33 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" + "node": ">=8.6" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/pkg-dir": { @@ -4178,6 +4270,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/source-map-js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", @@ -4337,6 +4439,19 @@ "node": ">=4" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/trim-repeated": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", diff --git a/package.json b/package.json index b7d4c1d1d4..dcd790fd40 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,8 @@ "type": "module", "scripts": { "dev": "vite", + "predeploy": "npm run build", + "deploy": "gh-pages -d dist", "build": "vite build", "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", "preview": "vite build; vite preview --host" @@ -23,7 +25,7 @@ "eslint-plugin-react": "^7.34.1", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.6", - "gh-pages": "^6.1.1", + "gh-pages": "^6.3.0", "vite": "^5.2.0" } } From 96b3b59f7df1fd7841e6b8c414537c30c781c46e Mon Sep 17 00:00:00 2001 From: rodrigcasio Date: Wed, 10 Sep 2025 15:42:10 -0600 Subject: [PATCH 02/15] Added the name of my fork repo into the file "vite.config.js" to deploy --- vite.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vite.config.js b/vite.config.js index 4d190ae430..beeaed5cdc 100644 --- a/vite.config.js +++ b/vite.config.js @@ -3,6 +3,6 @@ import react from '@vitejs/plugin-react' // https://vitejs.dev/config/ export default defineConfig({ - base: "/shoppingreact", + base: "/e-plantShopping", plugins: [react()], }) From 5ae0f9761e7ba1e4bedd1f18332de488b05e4d36 Mon Sep 17 00:00:00 2001 From: rodrigcasio Date: Wed, 10 Sep 2025 16:02:48 -0600 Subject: [PATCH 03/15] setting up the ProductList component layout from task #1 --- src/ProductList.jsx | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/ProductList.jsx b/src/ProductList.jsx index 7682c04fc4..47ec1c2a6d 100644 --- a/src/ProductList.jsx +++ b/src/ProductList.jsx @@ -274,7 +274,25 @@ function ProductList({ onHomeClick }) { {!showCart ? (
- + {plantsArray.map((category, index) => ( // a loop through each cateory in plantsArray +
{/* unique key for each category div */} +

+
{category.category}
{/* display the category name */} +

+
+ {category.plants.map((plant, plantIndex) => ( {/* loop through each plant in the current category.. */} +
+ {plant.name} +
{plant.name}
{/* displayin the plant name */} +
+ ))} +
+
+ ))}
) : ( From 2c0406bbd3e4d4ae0635bc044165f8c8649da2fb Mon Sep 17 00:00:00 2001 From: rodrigcasio Date: Wed, 10 Sep 2025 16:14:04 -0600 Subject: [PATCH 04/15] Added fuctionality to display the product grid content --- src/ProductList.jsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ProductList.jsx b/src/ProductList.jsx index 47ec1c2a6d..acac53ef65 100644 --- a/src/ProductList.jsx +++ b/src/ProductList.jsx @@ -288,12 +288,19 @@ function ProductList({ onHomeClick }) { alt={plant.name} />
{plant.name}
{/* displayin the plant name */} + +
{plant.description}
{/* displaying plant description */} + ))} ))} - ) : ( From 23bc888036d34c93629cfd8824a27aae600db77b Mon Sep 17 00:00:00 2001 From: rodrigcasio Date: Wed, 10 Sep 2025 16:27:04 -0600 Subject: [PATCH 05/15] Created "handleAddToCart()" function to handle the functionality of adding a plant to the cart with the user selects the "Add to Cart" button --- src/ProductList.jsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/ProductList.jsx b/src/ProductList.jsx index acac53ef65..83c47913cb 100644 --- a/src/ProductList.jsx +++ b/src/ProductList.jsx @@ -5,6 +5,8 @@ function ProductList({ onHomeClick }) { const [showCart, setShowCart] = useState(false); const [showPlants, setShowPlants] = useState(false); // State to control the visibility of the About Us page + // new variable + const [addToCart, setAddToCart] = useState({}); const plantsArray = [ { category: "Air Purifying Plants", @@ -252,6 +254,18 @@ function ProductList({ onHomeClick }) { e.preventDefault(); setShowCart(false); }; + + // new functions: + const handleAddToCart = (product) => { + dispatch(addItem(product)); // dispatch the action to add the product to the cart (redux action) + + setAddedToCart((prevState) => ( // update the local state to reflect that the product has been added + {...prevState, // spread the previous state to retain exiting entries + [product.name]: true, } // Set the current product's name as a key with value 'true' to mark it as added + )); + }; + + return (
From c25599aed3815dbbf39d7f59bb4f64f5ccd1b19e Mon Sep 17 00:00:00 2001 From: rodrigcasio Date: Wed, 10 Sep 2025 16:36:36 -0600 Subject: [PATCH 06/15] Added functionality for function reducer "addItems()" --- src/CartSlice.jsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/CartSlice.jsx b/src/CartSlice.jsx index 32b8761ed0..1e98c8d492 100644 --- a/src/CartSlice.jsx +++ b/src/CartSlice.jsx @@ -7,7 +7,15 @@ export const CartSlice = createSlice({ }, reducers: { addItem: (state, action) => { - + const { name, image, cost } = action.payload; // destructive product details from the action payload + + const existingItem = state.items.find(item => item.name === name); // chcking if the item already exists in the cart by comparing names + if(existingItem){ + existingItem.quantity++; // if item already exists in the cart, increase its quantity + }else{ + state.items.push({ name, image, cost, quantity: 1 }); // if item does not exist, add it to the cart with quantity 1 + } + }, removeItem: (state, action) => { }, From 6b43f8b63984e6451679b5357d446620d1119c71 Mon Sep 17 00:00:00 2001 From: rodrigcasio Date: Wed, 10 Sep 2025 16:45:46 -0600 Subject: [PATCH 07/15] Added logic to the "addItem()" reducer function --- src/CartSlice.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/CartSlice.jsx b/src/CartSlice.jsx index 1e98c8d492..ba3330ec59 100644 --- a/src/CartSlice.jsx +++ b/src/CartSlice.jsx @@ -15,7 +15,6 @@ export const CartSlice = createSlice({ }else{ state.items.push({ name, image, cost, quantity: 1 }); // if item does not exist, add it to the cart with quantity 1 } - }, removeItem: (state, action) => { }, From 0946181653c2a6b68ee67f0e89fcbbb78bd208b0 Mon Sep 17 00:00:00 2001 From: rodrigcasio Date: Wed, 10 Sep 2025 16:53:23 -0600 Subject: [PATCH 08/15] Created the logic for the reducer functions: "removeItem and updateQuantity" --- src/CartSlice.jsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/CartSlice.jsx b/src/CartSlice.jsx index ba3330ec59..d1d29258cf 100644 --- a/src/CartSlice.jsx +++ b/src/CartSlice.jsx @@ -6,6 +6,8 @@ export const CartSlice = createSlice({ items: [], // Initialize items as an empty array }, reducers: { + + // reducer adds a new plant item to the "items" array addItem: (state, action) => { const { name, image, cost } = action.payload; // destructive product details from the action payload @@ -16,10 +18,20 @@ export const CartSlice = createSlice({ state.items.push({ name, image, cost, quantity: 1 }); // if item does not exist, add it to the cart with quantity 1 } }, + + // reducer removes an item from the cart based on its name and gets called when the user wants to remove products from the cart removeItem: (state, action) => { + state.items = state.items.filter(item => item.name !== action.payload); }, + updateQuantity: (state, action) => { + const { name, quantity } = action.payload; // Destructive the product name and new quantity from the action payload + // *find the item in the cart that matches the given name + const itemToUpdate = state.items.find(item => item.name === name); + if(itemToUpdate){ + itemToUpdate.quantity = quantity; // if item is found, update its quantity to the new value + } }, }, From 210fa3f4e582ebede11f93d4135aec27571de40e Mon Sep 17 00:00:00 2001 From: rodrigcasio Date: Wed, 10 Sep 2025 16:55:51 -0600 Subject: [PATCH 09/15] Added number of task done from the instructions --- src/CartSlice.jsx | 1 + src/ProductList.jsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CartSlice.jsx b/src/CartSlice.jsx index d1d29258cf..74a4f8ad5b 100644 --- a/src/CartSlice.jsx +++ b/src/CartSlice.jsx @@ -1,5 +1,6 @@ import { createSlice } from '@reduxjs/toolkit'; +// task #2 export const CartSlice = createSlice({ name: 'cart', initialState: { diff --git a/src/ProductList.jsx b/src/ProductList.jsx index 83c47913cb..6350066fa3 100644 --- a/src/ProductList.jsx +++ b/src/ProductList.jsx @@ -4,7 +4,7 @@ import CartItem from './CartItem'; function ProductList({ onHomeClick }) { const [showCart, setShowCart] = useState(false); const [showPlants, setShowPlants] = useState(false); // State to control the visibility of the About Us page - + // new variable const [addToCart, setAddToCart] = useState({}); const plantsArray = [ From 640ab8ce58aa4276c78249fd1dcd66a36b299381 Mon Sep 17 00:00:00 2001 From: rodrigcasio Date: Wed, 10 Sep 2025 17:14:32 -0600 Subject: [PATCH 10/15] Added functionality for the function "calculateTotalAmount()" --- src/CartItem.jsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/CartItem.jsx b/src/CartItem.jsx index e06317433f..dbb01ca505 100644 --- a/src/CartItem.jsx +++ b/src/CartItem.jsx @@ -3,13 +3,20 @@ import { useSelector, useDispatch } from 'react-redux'; import { removeItem, updateQuantity } from './CartSlice'; import './CartItem.css'; +// task 3 const CartItem = ({ onContinueShopping }) => { const cart = useSelector(state => state.cart.items); const dispatch = useDispatch(); // Calculate total amount for all products in the cart const calculateTotalAmount = () => { - + let total = 0; + cart.forEach((item) => { + item.cost = parseFloat(item.cost.substring(1)); + total = item.cost * item.quantity; + }) + + return total; }; const handleContinueShopping = (e) => { From 19544d22d3ddde4f2eea1a01064281f7c8c79ff2 Mon Sep 17 00:00:00 2001 From: rodrigcasio Date: Wed, 10 Sep 2025 17:44:22 -0600 Subject: [PATCH 11/15] Added functionality for functions "handleDecrement, handleIncrement, and calculateTotalAmount()" --- src/CartItem.jsx | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/CartItem.jsx b/src/CartItem.jsx index dbb01ca505..5fba6f089a 100644 --- a/src/CartItem.jsx +++ b/src/CartItem.jsx @@ -12,31 +12,38 @@ const CartItem = ({ onContinueShopping }) => { const calculateTotalAmount = () => { let total = 0; cart.forEach((item) => { - item.cost = parseFloat(item.cost.substring(1)); - total = item.cost * item.quantity; - }) - + const unitCost = parseFloat(item.cost.substring(1)); + total += unitCost * item.quantity; + }); return total; }; const handleContinueShopping = (e) => { - + onContinueShopping(e) }; - - const handleIncrement = (item) => { + // Increment the quantity of the item by 1 + dispatch(updateQuantity({ name: item.name, quantity: item.quantity + 1 })); }; const handleDecrement = (item) => { - + // If quantity > 1, decrement; else remove item + if (item.quantity > 1) { + dispatch(updateQuantity({ name: item.name, quantity: item.quantity - 1 })); + } else { + dispatch(removeItem(item)); + } }; const handleRemove = (item) => { - }; + removeItem(item); + } + } // Calculate total cost based on quantity for an item const calculateTotalCost = (item) => { + item.forEach((item)) }; return ( From 0dcffb87cf3c1219c1210beb0be70da8d5926347 Mon Sep 17 00:00:00 2001 From: rodrigcasio Date: Wed, 10 Sep 2025 17:47:05 -0600 Subject: [PATCH 12/15] Added functionality for the "handleRemove() and calculateTotalCost()" --- src/CartItem.jsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/CartItem.jsx b/src/CartItem.jsx index 5fba6f089a..b9951e673b 100644 --- a/src/CartItem.jsx +++ b/src/CartItem.jsx @@ -37,13 +37,14 @@ const CartItem = ({ onContinueShopping }) => { }; const handleRemove = (item) => { - removeItem(item); - } - } + // Remove the item from the cart + dispatch(removeItem(item)); + }; // Calculate total cost based on quantity for an item const calculateTotalCost = (item) => { - item.forEach((item)) + // Calculate total cost for a single item + return parseFloat(item.cost.substring(1)) * item.quantity; }; return ( From 64728565bb43d22ac2c88573abcbb7f86d1c6606 Mon Sep 17 00:00:00 2001 From: rodrigcasio Date: Wed, 10 Sep 2025 17:58:09 -0600 Subject: [PATCH 13/15] Add cart actions and UI updates for adding, removing and updating item quantities --- src/CartItem.jsx | 6 ++--- src/ProductList.jsx | 61 +++++++++++++++++++++++++++++---------------- 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/src/CartItem.jsx b/src/CartItem.jsx index b9951e673b..b3c3fb8ae8 100644 --- a/src/CartItem.jsx +++ b/src/CartItem.jsx @@ -32,13 +32,13 @@ const CartItem = ({ onContinueShopping }) => { if (item.quantity > 1) { dispatch(updateQuantity({ name: item.name, quantity: item.quantity - 1 })); } else { - dispatch(removeItem(item)); + dispatch(removeItem(item.name)); } }; const handleRemove = (item) => { - // Remove the item from the cart - dispatch(removeItem(item)); + // Remove the item from the cart + dispatch(removeItem(item.name)); }; // Calculate total cost based on quantity for an item diff --git a/src/ProductList.jsx b/src/ProductList.jsx index 6350066fa3..29cb0dc42c 100644 --- a/src/ProductList.jsx +++ b/src/ProductList.jsx @@ -1,12 +1,18 @@ import React, { useState, useEffect } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { addItem } from './CartSlice'; import './ProductList.css' import CartItem from './CartItem'; function ProductList({ onHomeClick }) { const [showCart, setShowCart] = useState(false); - const [showPlants, setShowPlants] = useState(false); // State to control the visibility of the About Us page - - // new variable - const [addToCart, setAddToCart] = useState({}); + const [showPlants, setShowPlants] = useState(false); + const dispatch = useDispatch(); + const cartItems = useSelector(state => state.cart.items); + const [addedToCart, setAddedToCart] = useState({}); + // Calculate total quantity in cart + const calculateTotalQuantity = () => { + return cartItems ? cartItems.reduce((total, item) => total + item.quantity, 0) : 0; + }; const plantsArray = [ { category: "Air Purifying Plants", @@ -257,12 +263,11 @@ function ProductList({ onHomeClick }) { // new functions: const handleAddToCart = (product) => { - dispatch(addItem(product)); // dispatch the action to add the product to the cart (redux action) - - setAddedToCart((prevState) => ( // update the local state to reflect that the product has been added - {...prevState, // spread the previous state to retain exiting entries - [product.name]: true, } // Set the current product's name as a key with value 'true' to mark it as added - )); + dispatch(addItem(product)); + setAddedToCart((prevState) => ({ + ...prevState, + [product.name]: true, + })); }; @@ -279,36 +284,48 @@ function ProductList({ onHomeClick }) {
- {!showCart ? (
- {plantsArray.map((category, index) => ( // a loop through each cateory in plantsArray -
{/* unique key for each category div */} + {plantsArray.map((category, index) => ( +

-
{category.category}
{/* display the category name */} +
{category.category}

- {category.plants.map((plant, plantIndex) => ( {/* loop through each plant in the current category.. */} + {category.plants.map((plant, plantIndex) => (
- {plant.name} -
{plant.name}
{/* displayin the plant name */} - -
{plant.description}
{/* displaying plant description */} -
+
{plant.description}
+
))} From 0c5acdc3c32c746f85b488450f577ad8d421ebe3 Mon Sep 17 00:00:00 2001 From: rodrigcasio Date: Wed, 10 Sep 2025 18:04:52 -0600 Subject: [PATCH 14/15] Added code space between the imported files, and added a ";" for the export line from the "store.js" file --- src/ProductList.jsx | 1 + src/store.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ProductList.jsx b/src/ProductList.jsx index 29cb0dc42c..e764ee572d 100644 --- a/src/ProductList.jsx +++ b/src/ProductList.jsx @@ -3,6 +3,7 @@ import { useSelector, useDispatch } from 'react-redux'; import { addItem } from './CartSlice'; import './ProductList.css' import CartItem from './CartItem'; + function ProductList({ onHomeClick }) { const [showCart, setShowCart] = useState(false); const [showPlants, setShowPlants] = useState(false); diff --git a/src/store.js b/src/store.js index 54d0d6d66e..072f1e901d 100644 --- a/src/store.js +++ b/src/store.js @@ -5,4 +5,5 @@ import cartReducer from './CartSlice'; cart: cartReducer, }, }); -export default store + +export default store; From cda74e16c0bf56d69d7dad9b34f30982f10d0417 Mon Sep 17 00:00:00 2001 From: rodrigcasio Date: Wed, 10 Sep 2025 18:45:35 -0600 Subject: [PATCH 15/15] Added gh pages --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dcd790fd40..bebf32a8c8 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "dev": "vite", "predeploy": "npm run build", - "deploy": "gh-pages -d dist", + "deploy": "gh-pages -d dist", "build": "vite build", "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", "preview": "vite build; vite preview --host"