From 3bb2ce54a808c8182ca533244f4f9f9e71204089 Mon Sep 17 00:00:00 2001 From: mcdavis705 Date: Wed, 12 Nov 2025 05:42:55 -0500 Subject: [PATCH 1/5] inital commit --- src/ProductList.jsx | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/ProductList.jsx b/src/ProductList.jsx index 7682c04fc4..4040d79a59 100644 --- a/src/ProductList.jsx +++ b/src/ProductList.jsx @@ -1,9 +1,12 @@ import React, { useState, useEffect } from 'react'; import './ProductList.css' import CartItem from './CartItem'; +import { addItem } from './CartSlice'; + function ProductList({ onHomeClick }) { const [showCart, setShowCart] = useState(false); const [showPlants, setShowPlants] = useState(false); // State to control the visibility of the About Us page + const [addedToCart, setAddedToCart] = useState({}); const plantsArray = [ { @@ -212,6 +215,7 @@ function ProductList({ onHomeClick }) { ] } ]; + const styleObj = { backgroundColor: '#4CAF50', color: '#fff!important', @@ -252,6 +256,17 @@ function ProductList({ onHomeClick }) { e.preventDefault(); setShowCart(false); }; + + const handleAddToCart = (product) => { + dispatchEvent(addItem(product)) + + setAddedToCart((prevState)=> ({ + ...prevState, + [product.name]: true, + })); + } + + return (
@@ -274,7 +289,35 @@ function ProductList({ onHomeClick }) {
{!showCart ? (
+ {plantsArray.map((category, index) => ( +
+

+
{category.category}
+

+
+ {category.plants.map((plant, plantIndex) => ( +
+ {plant.name} +
{plant.name}
+
{plant.description}
+
{plant.cost}
+ + +
+ ))} +
+
+ ))}
) : ( From 74b30cf53148e8542238d90b46e3491d0c958cb6 Mon Sep 17 00:00:00 2001 From: mcdavis705 Date: Wed, 12 Nov 2025 06:03:02 -0500 Subject: [PATCH 2/5] Declare slice functions --- src/CartSlice.jsx | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/CartSlice.jsx b/src/CartSlice.jsx index 32b8761ed0..2ff5a0ee4a 100644 --- a/src/CartSlice.jsx +++ b/src/CartSlice.jsx @@ -7,13 +7,24 @@ export const CartSlice = createSlice({ }, reducers: { addItem: (state, action) => { - + const {name, image, cost} = action.payload; + const existingitem = state.items.find(item => item.name === name); + if (existingitem) { + existingitem.updateQuantity++; + } else { + state.items.push({name, image, cost, quantity: 1}) + } }, removeItem: (state, action) => { + state.items = state.items.filter(item => item.name !== action.payload); + }, updateQuantity: (state, action) => { - - + const {name, quantity} = action.payload; + itemToUpdate = state.items.find(item => item.name === name); + if(itemToUpdate){ + itemToUpdate.quantity = quantity; + } }, }, }); From 4b098eee641e3e2456125dbc47b2d789818d6d0f Mon Sep 17 00:00:00 2001 From: mcdavis705 Date: Wed, 12 Nov 2025 09:14:59 -0500 Subject: [PATCH 3/5] logic --- src/CartItem.jsx | 117 ++++++++++++++++++++++++++------------------ src/CartSlice.jsx | 2 + src/ProductList.jsx | 17 +++++-- 3 files changed, 84 insertions(+), 52 deletions(-) diff --git a/src/CartItem.jsx b/src/CartItem.jsx index e06317433f..ac60e737cc 100644 --- a/src/CartItem.jsx +++ b/src/CartItem.jsx @@ -4,63 +4,86 @@ import { removeItem, updateQuantity } from './CartSlice'; import './CartItem.css'; const CartItem = ({ onContinueShopping }) => { - const cart = useSelector(state => state.cart.items); - const dispatch = useDispatch(); + const cart = useSelector(state => state.cart.items); + const dispatch = useDispatch(); - // Calculate total amount for all products in the cart - const calculateTotalAmount = () => { - - }; + // Calculate total amount for all products in the cart + const calculateTotalAmount = (cart) => { + let total = 0; + cart.forEach(item => { + const quantity = item.quantity; + const cost = parseFloat(item.cost.substring(1)); + total += quantity * cost; + }) + return total.toFixed(2); + }; - const handleContinueShopping = (e) => { - - }; + const handleContinueShopping = (e) => { + onContinueShopping(e) + }; + const handleCheckoutShopping = (e) => { + alert('Functionality to be added for future reference'); + } - const handleIncrement = (item) => { - }; - const handleDecrement = (item) => { - - }; + const handleIncrement = (item) => { + dispatch(updateQuantity({ name: item.name, quantity: item.quantity + 1 })); + }; - const handleRemove = (item) => { - }; + const handleDecrement = (item) => { + if (item.quantity > 1) { + dispatch(updateQuantity({ name: item.name, quantity: item.quantity - 1 })); + } else { + dispatch(removeItem(item.name)) + } + }; - // Calculate total cost based on quantity for an item - const calculateTotalCost = (item) => { - }; + const handleRemove = (item) => { + dispatch(removeItem(item.name)) + }; - return ( -
-

Total Cart Amount: ${calculateTotalAmount()}

-
- {cart.map(item => ( -
- {item.name} -
-
{item.name}
-
{item.cost}
-
- - {item.quantity} - -
-
Total: ${calculateTotalCost(item)}
- + // Calculate total cost based on quantity for an item + const calculateTotalCost = (item) => { + const quantity = item.quantity; + const cost = parseFloat(item.cost.substring(1)); + return (quantity * cost).toFixed(2); + }; + + const updateQuantity = () => { + dispatch + } + + return ( +
+

Total Cart Amount: ${calculateTotalAmount()}

+
+ {cart.map(item => ( +
+ {item.name} +
+
{item.name}
+
{item.cost}
+
+ + {item.quantity} + +
+
Total: ${calculateTotalCost(item)}
+ +
+
+ ))} +
+
+
+ +
+
-
- ))} -
-
-
- -
- -
-
- ); +
+ ); }; export default CartItem; diff --git a/src/CartSlice.jsx b/src/CartSlice.jsx index 2ff5a0ee4a..17acb63b44 100644 --- a/src/CartSlice.jsx +++ b/src/CartSlice.jsx @@ -24,6 +24,8 @@ export const CartSlice = createSlice({ itemToUpdate = state.items.find(item => item.name === name); if(itemToUpdate){ itemToUpdate.quantity = quantity; + } else { + addItem(); } }, }, diff --git a/src/ProductList.jsx b/src/ProductList.jsx index 4040d79a59..55d98ede18 100644 --- a/src/ProductList.jsx +++ b/src/ProductList.jsx @@ -2,11 +2,14 @@ import React, { useState, useEffect } from 'react'; import './ProductList.css' import CartItem from './CartItem'; import { addItem } from './CartSlice'; +import { useDispatch, useSelector } from 'react-redux'; function ProductList({ onHomeClick }) { const [showCart, setShowCart] = useState(false); const [showPlants, setShowPlants] = useState(false); // State to control the visibility of the About Us page const [addedToCart, setAddedToCart] = useState({}); + const dispatch = useDispatch(); + const cartItems = useSelector((state) => state.cart.items); const plantsArray = [ { @@ -215,7 +218,7 @@ function ProductList({ onHomeClick }) { ] } ]; - + const styleObj = { backgroundColor: '#4CAF50', color: '#fff!important', @@ -257,15 +260,19 @@ function ProductList({ onHomeClick }) { setShowCart(false); }; - const handleAddToCart = (product) => { - dispatchEvent(addItem(product)) + const handleAddToCart = (plant) => { + dispatch(addItem(plant)) setAddedToCart((prevState)=> ({ ...prevState, - [product.name]: true, + [plant.name]: true, })); } + const calculateTotalQuantity = () => { + return cartItems ? cartItems.reduce((total, item) => total + item.quantity, 0) : 0; + }; + return (
@@ -309,7 +316,7 @@ function ProductList({ onHomeClick }) { From 91eae8699177ef5292e9ea36e621a50c73a89e60 Mon Sep 17 00:00:00 2001 From: mcdavis705 Date: Wed, 12 Nov 2025 13:50:40 -0500 Subject: [PATCH 4/5] added cart items sum badge --- package-lock.json | 235 +++++++++++++++++++++++++++++++++----------- package.json | 2 +- src/App.css | 1 + src/App.jsx | 72 +++++++------- src/CartItem.css | 21 ++++ src/CartItem.jsx | 180 ++++++++++++++++++++------------- src/CartSlice.jsx | 26 ++--- src/ProductList.jsx | 57 ++++++++--- 8 files changed, 399 insertions(+), 195 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..eee7884013 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,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" } } diff --git a/src/App.css b/src/App.css index 88bb5690eb..08b67f04d8 100644 --- a/src/App.css +++ b/src/App.css @@ -50,6 +50,7 @@ flex-direction: column; justify-content: center; gap: 10px; + padding: 10px; } .content p, diff --git a/src/App.jsx b/src/App.jsx index 799372d75d..800e9b4ac1 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -5,42 +5,42 @@ import './App.css'; import AboutUs from './AboutUs'; function App() { - - const [showProductList, setShowProductList] = useState(false); - - const handleGetStartedClick = () => { - setShowProductList(true); - }; - - const handleHomeClick = () => { - setShowProductList(false); - }; - - return ( -
-
-
-
-
-

Welcome To Paradise Nursery

-
-

Where Green Meets Serenity

- - -
-
- -
-
- -
-
- -
-
- ); + + const [showProductList, setShowProductList] = useState(false); + + const handleGetStartedClick = () => { + setShowProductList(true); + }; + + const handleHomeClick = () => { + setShowProductList(false); + }; + + return ( +
+
+
+
+
+

Welcome To Paradise Nursery

+
+

Where Green Meets Serenity

+ + +
+
+ +
+
+ +
+
+ +
+
+ ); } export default App; diff --git a/src/CartItem.css b/src/CartItem.css index 66a6a4061f..60d3611587 100644 --- a/src/CartItem.css +++ b/src/CartItem.css @@ -1,5 +1,26 @@ /* CartItem.css */ /* CartItem.css */ +.cart { + position: relative; + display: inline-block; +} + +.cart-number { + position: absolute; + top: -5px; + right: 8px; + background-color: #e63946; + color: white; + font-size: 14px; + font-weight: bold; + padding: 2px 6px; + border-radius: 50%; + min-width: 20px; + text-align: center; + line-height: 1; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.2); +} + .cart-item { display: flex; diff --git a/src/CartItem.jsx b/src/CartItem.jsx index ac60e737cc..238883cd44 100644 --- a/src/CartItem.jsx +++ b/src/CartItem.jsx @@ -4,88 +4,126 @@ import { removeItem, updateQuantity } from './CartSlice'; import './CartItem.css'; const CartItem = ({ onContinueShopping }) => { - const cart = useSelector(state => state.cart.items); - const dispatch = useDispatch(); - - // Calculate total amount for all products in the cart - const calculateTotalAmount = (cart) => { - let total = 0; - cart.forEach(item => { - const quantity = item.quantity; - const cost = parseFloat(item.cost.substring(1)); - total += quantity * cost; - }) - return total.toFixed(2); - }; - - const handleContinueShopping = (e) => { - onContinueShopping(e) - }; - - const handleCheckoutShopping = (e) => { - alert('Functionality to be added for future reference'); - } + const cart = useSelector((state) => state.cart.items); + const dispatch = useDispatch(); + + const calculateTotalAmount = () => { + let total = 0; + cart.forEach((item) => { + const quantity = item.quantity; + const cost = parseFloat(item.cost.replace('$', '')); + total += quantity * cost; + }); + return total.toFixed(2); + }; - const handleIncrement = (item) => { - dispatch(updateQuantity({ name: item.name, quantity: item.quantity + 1 })); - }; + const calculateSubtotal = (item) => { + const quantity = item.quantity; + const cost = parseFloat(item.cost.replace('$', '')); + return (quantity * cost).toFixed(2); + }; - const handleDecrement = (item) => { - if (item.quantity > 1) { - dispatch(updateQuantity({ name: item.name, quantity: item.quantity - 1 })); - } else { - dispatch(removeItem(item.name)) - } - }; - const handleRemove = (item) => { - dispatch(removeItem(item.name)) - }; + const handleIncrement = (item) => { + dispatch(updateQuantity({ name: item.name, quantity: item.quantity + 1 })); + }; - // Calculate total cost based on quantity for an item - const calculateTotalCost = (item) => { - const quantity = item.quantity; - const cost = parseFloat(item.cost.substring(1)); - return (quantity * cost).toFixed(2); - }; - const updateQuantity = () => { - dispatch + const handleDecrement = (item) => { + if (item.quantity > 1) { + dispatch(updateQuantity({ name: item.name, quantity: item.quantity - 1 })); + } else { + dispatch(removeItem(item.name)); } + }; + + + const handleRemove = (item) => { + dispatch(removeItem(item.name)); + }; + + const handleContinueShopping = (e) => { + onContinueShopping(e); + }; + + + const handleCheckout = () => { + alert('Checkout functionality coming soon!'); + }; + + if (cart.length === 0) { return ( -
-

Total Cart Amount: ${calculateTotalAmount()}

-
- {cart.map(item => ( -
- {item.name} -
-
{item.name}
-
{item.cost}
-
- - {item.quantity} - -
-
Total: ${calculateTotalCost(item)}
- -
-
- ))} -
-
-
- -
- -
-
+
+

Your cart is empty 🛒

+ +
); -}; + } -export default CartItem; + return ( +
+

+ Total Cart Amount: ${calculateTotalAmount()} +

+ +
+ {cart.map((item) => ( +
+ {item.name} + +
+
{item.name}
+
Price: {item.cost}
+ +
+ + {item.quantity} + +
+
+ Subtotal: ${calculateSubtotal(item)} +
+ +
+
+ ))} +
+ +
+ + +
+
+ ); +}; + +export default CartItem; diff --git a/src/CartSlice.jsx b/src/CartSlice.jsx index 17acb63b44..b05963687f 100644 --- a/src/CartSlice.jsx +++ b/src/CartSlice.jsx @@ -7,26 +7,26 @@ export const CartSlice = createSlice({ }, reducers: { addItem: (state, action) => { - const {name, image, cost} = action.payload; - const existingitem = state.items.find(item => item.name === name); - if (existingitem) { - existingitem.updateQuantity++; - } else { - state.items.push({name, image, cost, quantity: 1}) - } - }, + const { name, image, cost } = action.payload; + const existingItem = state.items.find(item => item.name === name); + if (existingItem) { + existingItem.quantity++; + } else { + state.items.push({ name, image, cost, quantity: 1 }); + } + alert('Item added to cart'); + }, + removeItem: (state, action) => { state.items = state.items.filter(item => item.name !== action.payload); - }, + updateQuantity: (state, action) => { const {name, quantity} = action.payload; - itemToUpdate = state.items.find(item => item.name === name); + const itemToUpdate = state.items.find(item => item.name === name); if(itemToUpdate){ itemToUpdate.quantity = quantity; - } else { - addItem(); - } + }; }, }, }); diff --git a/src/ProductList.jsx b/src/ProductList.jsx index 55d98ede18..ea995af3bb 100644 --- a/src/ProductList.jsx +++ b/src/ProductList.jsx @@ -240,6 +240,7 @@ function ProductList({ onHomeClick }) { textDecoration: 'none', } + const handleHomeClick = (e) => { e.preventDefault(); onHomeClick(); @@ -260,18 +261,22 @@ function ProductList({ onHomeClick }) { setShowCart(false); }; - const handleAddToCart = (plant) => { - dispatch(addItem(plant)) + const handleAddToCart = (product) => { + dispatch(addItem(product)); - setAddedToCart((prevState)=> ({ + setAddedToCart((prevState) => ({ ...prevState, - [plant.name]: true, + [product.name]: true, })); - } + }; const calculateTotalQuantity = () => { return cartItems ? cartItems.reduce((total, item) => total + item.quantity, 0) : 0; - }; + }; + + const calculateTotalItems = () => { + return cartItems.reduce((total, item) => total + item.quantity, 0); + }; return ( @@ -291,7 +296,31 @@ function ProductList({ onHomeClick }) {
- +
handleCartClick(e)}> + + + + + + + + {calculateTotalItems() > 0 && ( + {calculateTotalItems()} + )} +
+
{!showCart ? ( @@ -305,18 +334,18 @@ function ProductList({ onHomeClick }) { {category.plants.map((plant, plantIndex) => (
{plant.name}
{plant.name}
-
{plant.description}
-
{plant.cost}
+
{plant.description}
+
{plant.cost}
- From f921a706b7a0c955fd75fbd73dc145f7d88fad84 Mon Sep 17 00:00:00 2001 From: mcdavis705 Date: Wed, 12 Nov 2025 14:27:49 -0500 Subject: [PATCH 5/5] minor css --- index.html | 1 - package.json | 58 +++++++++++++++++++++++++------------------------ src/AboutUs.css | 5 ++--- src/App.css | 1 + vite.config.js | 2 +- 5 files changed, 34 insertions(+), 33 deletions(-) diff --git a/index.html b/index.html index 77b24fdfea..024575bcfe 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,6 @@ - E-Plant diff --git a/package.json b/package.json index eee7884013..0f36178438 100644 --- a/package.json +++ b/package.json @@ -1,29 +1,31 @@ { - "name": "shoppingcart", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "vite build", - "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite build; vite preview --host" - }, - "dependencies": { - "@reduxjs/toolkit": "^2.2.3", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-redux": "^9.1.1" - }, - "devDependencies": { - "@types/react": "^18.2.66", - "@types/react-dom": "^18.2.22", - "@vitejs/plugin-react": "^4.2.1", - "eslint": "^8.57.0", - "eslint-plugin-react": "^7.34.1", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.6", - "gh-pages": "^6.3.0", - "vite": "^5.2.0" - } -} + "name": "shoppingcart", + "private": true, + "version": "0.0.0", + "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" + }, + "dependencies": { + "@reduxjs/toolkit": "^2.2.3", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-redux": "^9.1.1" + }, + "devDependencies": { + "@types/react": "^18.2.66", + "@types/react-dom": "^18.2.22", + "@vitejs/plugin-react": "^4.2.1", + "eslint": "^8.57.0", + "eslint-plugin-react": "^7.34.1", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.6", + "gh-pages": "^6.3.0", + "vite": "^5.2.0" + } +} \ No newline at end of file diff --git a/src/AboutUs.css b/src/AboutUs.css index ab682db243..eb658adb6c 100644 --- a/src/AboutUs.css +++ b/src/AboutUs.css @@ -1,8 +1,7 @@ .about-us-container { width: 1000px; /* margin: 0 auto; */ - /* padding: 20px; */ - /* background-color: red; */ + background-color: red, text-align: justify; } @@ -21,7 +20,7 @@ } .about-us-content { - font-size: 18px; + font-size: 10px; margin-bottom: 20px; } .plant_logo_right{ diff --git a/src/App.css b/src/App.css index 08b67f04d8..ca3c5a793a 100644 --- a/src/App.css +++ b/src/App.css @@ -11,6 +11,7 @@ width: 100vw; height: 100vh; background-color: #f8f8f8; + } .background-image { 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()], })