From 04a63f25f4f707842c9b919980b76a46df965cad Mon Sep 17 00:00:00 2001 From: AnPeso Date: Thu, 6 Feb 2025 13:08:54 -0500 Subject: [PATCH 1/8] initial commit --- src/ProductList.jsx | 67 +++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/src/ProductList.jsx b/src/ProductList.jsx index 964b15d49..67c9d19d7 100644 --- a/src/ProductList.jsx +++ b/src/ProductList.jsx @@ -1,10 +1,11 @@ import React, { useState,useEffect } from 'react'; import './ProductList.css' import CartItem from './CartItem'; +import addItem from './CartSlice' function ProductList() { 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 = [ { category: "Air Purifying Plants", @@ -242,40 +243,60 @@ const handlePlantsClick = (e) => { setShowCart(false); // Hide the cart when navigating to About Us }; +const handleAddToCart = (product) => { + dispatch(addItem(product)); + setAddedToCart((prevState) => ({ + ...prevState, + [product.name]: true, // Set the product name as key and value as true to indicate it's added to cart + })); + }; const handleContinueShopping = (e) => { e.preventDefault(); setShowCart(false); }; - return ( -
-
+ return ( +
+
- - {!showCart? ( -
- - + + {!showCart ? ( +
+ {plantsArray.map((category, index) => ( +
+

{category.category}

+
+ {category.plants.map((plant, plantIndex) => ( +
+ {plant.name} +
{plant.name}
+ {/*Similarly like the above plant.name show other details like description and cost*/} + +
+ ))}
- ) : ( - -)}
- ); + ))} +
+ ) : ( + + )} +
+); } -export default ProductList; +export default ProductList; \ No newline at end of file From 58d3e59b8d2d58328aa3ac90dc8e87f4a3836ecd Mon Sep 17 00:00:00 2001 From: AnPeso Date: Thu, 6 Feb 2025 13:13:14 -0500 Subject: [PATCH 2/8] reducers --- src/CartSlice.jsx | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/CartSlice.jsx b/src/CartSlice.jsx index 32b8761ed..077349268 100644 --- a/src/CartSlice.jsx +++ b/src/CartSlice.jsx @@ -7,12 +7,23 @@ 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.quantity++; + } 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; + const itemToUpdate = state.items.find(item => item.name === name); + if (itemToUpdate) { + itemToUpdate.quantity = quantity; + } }, }, From a07de31ba3f4b7c9b2497cef0e23f5fc3f33a1b0 Mon Sep 17 00:00:00 2001 From: AnPeso Date: Thu, 6 Feb 2025 14:20:33 -0500 Subject: [PATCH 3/8] totals --- src/CartItem.jsx | 36 +++++++++++------ src/ProductList.jsx | 97 ++++++++++++++++++++++++++++----------------- 2 files changed, 83 insertions(+), 50 deletions(-) diff --git a/src/CartItem.jsx b/src/CartItem.jsx index e06317433..939741f0b 100644 --- a/src/CartItem.jsx +++ b/src/CartItem.jsx @@ -9,28 +9,40 @@ const CartItem = ({ onContinueShopping }) => { // Calculate total amount for all products in the cart const calculateTotalAmount = () => { - - }; + return cart.reduce((total, item) => { + const cost = parseFloat(item.cost.replace('$', '').trim()); // Make sure cost is a valid number + if (isNaN(cost)) return total; // If it's not a valid number, skip this item + return total + item.quantity * cost; + }, 0).toFixed(2); +}; +const calculateTotalCost = (item) => { + const cost = parseFloat(item.cost.replace('$', '').trim()); // Make sure cost is a valid number + if (isNaN(cost)) return '0.00'; // If it's not a valid number, return 0.00 + return (item.quantity * cost).toFixed(2); +}; const handleContinueShopping = (e) => { - + e.preventDefault(); + if (onContinueShopping) { + onContinueShopping(); + } }; - - const handleIncrement = (item) => { + dispatch(updateQuantity({ name: item.name, quantity: item.quantity + 1 })); }; const handleDecrement = (item) => { - + if (item.quantity > 1) { + dispatch(updateQuantity({ name: item.name, quantity: item.quantity - 1 })); + } }; const handleRemove = (item) => { + dispatch(removeItem(item.name)); }; - // Calculate total cost based on quantity for an item - const calculateTotalCost = (item) => { - }; + return (
@@ -41,7 +53,7 @@ const CartItem = ({ onContinueShopping }) => { {item.name}
{item.name}
-
{item.cost}
+
${item.cost}
{item.quantity} @@ -57,12 +69,10 @@ const CartItem = ({ onContinueShopping }) => {

- +
); }; export default CartItem; - - diff --git a/src/ProductList.jsx b/src/ProductList.jsx index 67c9d19d7..473d77248 100644 --- a/src/ProductList.jsx +++ b/src/ProductList.jsx @@ -1,11 +1,16 @@ -import React, { useState,useEffect } from 'react'; -import './ProductList.css' +import React, { useState } from 'react'; +import { useDispatch } from 'react-redux'; +import './ProductList.css'; import CartItem from './CartItem'; -import addItem from './CartSlice' +import { addItem } from './CartSlice'; + + function ProductList() { const [showCart, setShowCart] = useState(false); - const [showPlants, setShowPlants] = useState(false); // State to control the visibility of the About Us page + const [showPlants, setShowPlants] = useState(true); // Start by showing plants const [addedToCart, setAddedToCart] = useState({}); + const dispatch = useDispatch(); + const plantsArray = [ { category: "Air Purifying Plants", @@ -235,31 +240,37 @@ function ProductList() { } const handleCartClick = (e) => { e.preventDefault(); - setShowCart(true); // Set showCart to true when cart icon is clicked + setShowCart(true); + setShowPlants(false); // Hide plants when cart is shown }; + const handlePlantsClick = (e) => { e.preventDefault(); - setShowPlants(true); // Set showAboutUs to true when "About Us" link is clicked - setShowCart(false); // Hide the cart when navigating to About Us + setShowPlants(true); // Show plants + setShowCart(false); // Hide cart }; + const handleAddToCart = (product) => { dispatch(addItem(product)); setAddedToCart((prevState) => ({ - ...prevState, - [product.name]: true, // Set the product name as key and value as true to indicate it's added to cart - })); - }; - const handleContinueShopping = (e) => { + ...prevState, + [product.name]: true + })); +}; + +const handleContinueShopping = (e) => { e.preventDefault(); - setShowCart(false); - }; - return ( + setShowCart(false); // Hide cart + setShowPlants(true); // Show plants again +}; + +return (
- {!showCart ? ( + {/* Conditionally render the plant list or cart */} + {showPlants && (
- {plantsArray.map((category, index) => ( -
-

{category.category}

-
- {category.plants.map((plant, plantIndex) => ( -
- {plant.name} -
{plant.name}
- {/*Similarly like the above plant.name show other details like description and cost*/} - -
- ))} -
-
- ))} + {plantsArray.map((category, index) => ( +
+

{category.category}

+
+ {category.plants.map((plant, plantIndex) => ( +
+ {plant.name} +
{plant.name}
+
{plant.description}
+
{plant.cost}
+ + +
+ ))} +
+
+ ))}
- ) : ( - )} + + {/* Cart view when showCart is true */} + {showCart && }
); -} +}; export default ProductList; \ No newline at end of file From 2b560fb7fad75f448dbf1feec9230f4e7d98d8ac Mon Sep 17 00:00:00 2001 From: AnPeso Date: Thu, 6 Feb 2025 15:09:07 -0500 Subject: [PATCH 4/8] . --- src/CartItem.jsx | 23 ++++++++++++++++------- src/ProductList.jsx | 25 ++++++++++++++++--------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/CartItem.jsx b/src/CartItem.jsx index 939741f0b..95ff7852f 100644 --- a/src/CartItem.jsx +++ b/src/CartItem.jsx @@ -3,24 +3,30 @@ import { useSelector, useDispatch } from 'react-redux'; import { removeItem, updateQuantity } from './CartSlice'; import './CartItem.css'; -const CartItem = ({ onContinueShopping }) => { +const CartItem = ({ onContinueShopping, onUpdateTotalQuantity }) => { const cart = useSelector(state => state.cart.items); const dispatch = useDispatch(); + // Calculate total quantity of items in the cart + const calculateTotalQuantity = () => { + return cart.reduce((total, item) => total + item.quantity, 0); + }; + // Calculate total amount for all products in the cart const calculateTotalAmount = () => { return cart.reduce((total, item) => { - const cost = parseFloat(item.cost.replace('$', '').trim()); // Make sure cost is a valid number + const cost = parseFloat(item.cost.replace('$', '').trim()); if (isNaN(cost)) return total; // If it's not a valid number, skip this item return total + item.quantity * cost; }, 0).toFixed(2); -}; + }; -const calculateTotalCost = (item) => { - const cost = parseFloat(item.cost.replace('$', '').trim()); // Make sure cost is a valid number + const calculateTotalCost = (item) => { + const cost = parseFloat(item.cost.replace('$', '').trim()); if (isNaN(cost)) return '0.00'; // If it's not a valid number, return 0.00 return (item.quantity * cost).toFixed(2); -}; + }; + const handleContinueShopping = (e) => { e.preventDefault(); if (onContinueShopping) { @@ -42,7 +48,10 @@ const calculateTotalCost = (item) => { dispatch(removeItem(item.name)); }; - + // Update total quantity whenever the cart changes + React.useEffect(() => { + onUpdateTotalQuantity(calculateTotalQuantity()); + }, [cart, onUpdateTotalQuantity]); return (
diff --git a/src/ProductList.jsx b/src/ProductList.jsx index 473d77248..7934dfcfb 100644 --- a/src/ProductList.jsx +++ b/src/ProductList.jsx @@ -1,8 +1,8 @@ import React, { useState } from 'react'; -import { useDispatch } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import './ProductList.css'; import CartItem from './CartItem'; -import { addItem } from './CartSlice'; +import { addItem, removeItem, updateQuantity } from './CartSlice'; function ProductList() { @@ -10,6 +10,7 @@ function ProductList() { const [showPlants, setShowPlants] = useState(true); // Start by showing plants const [addedToCart, setAddedToCart] = useState({}); const dispatch = useDispatch(); + const totalQuantity = useSelector(state => state.cart.updateQuantity); const plantsArray = [ { @@ -267,7 +268,7 @@ const handleContinueShopping = (e) => { return (
-
+
logo @@ -279,11 +280,17 @@ return (
-
-
-
- - + @@ -292,7 +299,7 @@ return (
{plantsArray.map((category, index) => (
-

{category.category}

+

{category.category}

{category.plants.map((plant, plantIndex) => (
From f56bb105c996c2bf5cf252988e0835d3a567fbde Mon Sep 17 00:00:00 2001 From: AnPeso Date: Tue, 11 Feb 2025 15:16:08 -0500 Subject: [PATCH 5/8] initial commit --- src/CartItem.jsx | 25 +++++++------------- src/ProductList.jsx | 56 ++++++++++++++++----------------------------- 2 files changed, 28 insertions(+), 53 deletions(-) diff --git a/src/CartItem.jsx b/src/CartItem.jsx index 95ff7852f..cf3223446 100644 --- a/src/CartItem.jsx +++ b/src/CartItem.jsx @@ -3,30 +3,24 @@ import { useSelector, useDispatch } from 'react-redux'; import { removeItem, updateQuantity } from './CartSlice'; import './CartItem.css'; -const CartItem = ({ onContinueShopping, onUpdateTotalQuantity }) => { +const CartItem = ({ onContinueShopping }) => { const cart = useSelector(state => state.cart.items); const dispatch = useDispatch(); - // Calculate total quantity of items in the cart - const calculateTotalQuantity = () => { - return cart.reduce((total, item) => total + item.quantity, 0); - }; - // Calculate total amount for all products in the cart const calculateTotalAmount = () => { return cart.reduce((total, item) => { - const cost = parseFloat(item.cost.replace('$', '').trim()); + const cost = parseFloat(item.cost.replace('$', '').trim()); // Make sure cost is a valid number if (isNaN(cost)) return total; // If it's not a valid number, skip this item return total + item.quantity * cost; }, 0).toFixed(2); - }; +}; - const calculateTotalCost = (item) => { - const cost = parseFloat(item.cost.replace('$', '').trim()); +const calculateTotalCost = (item) => { + const cost = parseFloat(item.cost.replace('$', '').trim()); // Make sure cost is a valid number if (isNaN(cost)) return '0.00'; // If it's not a valid number, return 0.00 return (item.quantity * cost).toFixed(2); - }; - +}; const handleContinueShopping = (e) => { e.preventDefault(); if (onContinueShopping) { @@ -48,10 +42,7 @@ const CartItem = ({ onContinueShopping, onUpdateTotalQuantity }) => { dispatch(removeItem(item.name)); }; - // Update total quantity whenever the cart changes - React.useEffect(() => { - onUpdateTotalQuantity(calculateTotalQuantity()); - }, [cart, onUpdateTotalQuantity]); + return (
@@ -84,4 +75,4 @@ const CartItem = ({ onContinueShopping, onUpdateTotalQuantity }) => { ); }; -export default CartItem; +export default CartItem; \ No newline at end of file diff --git a/src/ProductList.jsx b/src/ProductList.jsx index 7934dfcfb..76f4346f1 100644 --- a/src/ProductList.jsx +++ b/src/ProductList.jsx @@ -1,17 +1,13 @@ import React, { useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import './ProductList.css'; import CartItem from './CartItem'; -import { addItem, removeItem, updateQuantity } from './CartSlice'; - - +import { addItem } from './CartSlice'; function ProductList() { const [showCart, setShowCart] = useState(false); const [showPlants, setShowPlants] = useState(true); // Start by showing plants const [addedToCart, setAddedToCart] = useState({}); const dispatch = useDispatch(); - const totalQuantity = useSelector(state => state.cart.updateQuantity); - const plantsArray = [ { category: "Air Purifying Plants", @@ -244,14 +240,12 @@ function ProductList() { setShowCart(true); setShowPlants(false); // Hide plants when cart is shown }; - const handlePlantsClick = (e) => { e.preventDefault(); setShowPlants(true); // Show plants setShowCart(false); // Hide cart }; - const handleAddToCart = (product) => { dispatch(addItem(product)); setAddedToCart((prevState) => ({ @@ -259,16 +253,14 @@ const handleAddToCart = (product) => { [product.name]: true })); }; - -const handleContinueShopping = (e) => { - e.preventDefault(); - setShowCart(false); // Hide cart - setShowPlants(true); // Show plants again +const handleContinueShopping = () => { + setShowPlants(true); // Näytetään kasvit uudelleen + setShowCart(false); // Piilotetaan ostoskori }; return (
-
+
logo @@ -280,26 +272,18 @@ return (
-
- - - - {/* Conditionally render the plant list or cart */} + + {/* Näytä kasvit, jos showPlants on true */} {showPlants && (
{plantsArray.map((category, index) => (
-

{category.category}

+

{category.category}

{category.plants.map((plant, plantIndex) => (
@@ -308,13 +292,12 @@ return (
{plant.description}
{plant.cost}
- + className={`product-button ${addedToCart[plant.name] ? 'added' : ''}`} + onClick={() => handleAddToCart(plant)} + disabled={addedToCart[plant.name]} + > + {addedToCart[plant.name] ? "Added" : "Add to Cart"} +
))}
@@ -323,10 +306,11 @@ return (
)} - {/* Cart view when showCart is true */} + {/* Näytä ostoskori, jos showCart on true */} {showCart && }
); + }; export default ProductList; \ No newline at end of file From dd70628f9352ff785c75ccf0924d3fe4bb70e1d1 Mon Sep 17 00:00:00 2001 From: AnPeso Date: Tue, 11 Feb 2025 15:36:10 -0500 Subject: [PATCH 6/8] updates --- src/CartItem.jsx | 2 +- src/CartSlice.jsx | 16 +++++++++++----- src/ProductList.jsx | 8 ++++---- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/CartItem.jsx b/src/CartItem.jsx index cf3223446..1074649de 100644 --- a/src/CartItem.jsx +++ b/src/CartItem.jsx @@ -53,7 +53,7 @@ const calculateTotalCost = (item) => { {item.name}
{item.name}
-
${item.cost}
+
{item.cost}
{item.quantity} diff --git a/src/CartSlice.jsx b/src/CartSlice.jsx index 077349268..110cabc8a 100644 --- a/src/CartSlice.jsx +++ b/src/CartSlice.jsx @@ -3,7 +3,8 @@ import { createSlice } from '@reduxjs/toolkit'; export const CartSlice = createSlice({ name: 'cart', initialState: { - items: [], // Initialize items as an empty array + items: [], // Ostoskorin tuotteet + totalQuantity: 0, // Uusi tila, joka seuraa tuotteiden kokonaismäärää }, reducers: { addItem: (state, action) => { @@ -14,17 +15,22 @@ export const CartSlice = createSlice({ } else { state.items.push({ name, image, cost, quantity: 1 }); } - }, + state.totalQuantity++; // Päivitä kokonaismäärä + }, removeItem: (state, action) => { - state.items = state.items.filter(item => item.name !== action.payload); + const itemToRemove = state.items.find(item => item.name === action.payload); + if (itemToRemove) { + state.totalQuantity -= itemToRemove.quantity; // Vähennä tuotteen määrä kokonaismäärästä + state.items = state.items.filter(item => item.name !== action.payload); + } }, updateQuantity: (state, action) => { const { name, quantity } = action.payload; const itemToUpdate = state.items.find(item => item.name === name); if (itemToUpdate) { - itemToUpdate.quantity = quantity; + state.totalQuantity += (quantity - itemToUpdate.quantity); // Päivitä kokonaismäärä + itemToUpdate.quantity = quantity; } - }, }, }); diff --git a/src/ProductList.jsx b/src/ProductList.jsx index 76f4346f1..a53526526 100644 --- a/src/ProductList.jsx +++ b/src/ProductList.jsx @@ -260,7 +260,7 @@ const handleContinueShopping = () => { return (
-
+
- From 8c4ea38942db94f13d94a3a7ea6f1c5189425dce Mon Sep 17 00:00:00 2001 From: AnPeso Date: Wed, 12 Feb 2025 12:17:13 -0500 Subject: [PATCH 7/8] Quantity counter --- src/CartItem.jsx | 26 ++++++++++++++------------ src/ProductList.jsx | 9 +++++++-- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/CartItem.jsx b/src/CartItem.jsx index 1074649de..4d352f509 100644 --- a/src/CartItem.jsx +++ b/src/CartItem.jsx @@ -7,20 +7,24 @@ const CartItem = ({ onContinueShopping }) => { const cart = useSelector(state => state.cart.items); const dispatch = useDispatch(); - // Calculate total amount for all products in the cart + // Laske tuotteiden kokonaismäärä ostoskorissa + const totalQuantity = cart.reduce((total, item) => total + item.quantity, 0); + + // Laske kokonaishinta const calculateTotalAmount = () => { return cart.reduce((total, item) => { - const cost = parseFloat(item.cost.replace('$', '').trim()); // Make sure cost is a valid number - if (isNaN(cost)) return total; // If it's not a valid number, skip this item + const cost = parseFloat(item.cost.replace('$', '').trim()); + if (isNaN(cost)) return total; return total + item.quantity * cost; }, 0).toFixed(2); -}; + }; -const calculateTotalCost = (item) => { - const cost = parseFloat(item.cost.replace('$', '').trim()); // Make sure cost is a valid number - if (isNaN(cost)) return '0.00'; // If it's not a valid number, return 0.00 + const calculateTotalCost = (item) => { + const cost = parseFloat(item.cost.replace('$', '').trim()); + if (isNaN(cost)) return '0.00'; return (item.quantity * cost).toFixed(2); -}; + }; + const handleContinueShopping = (e) => { e.preventDefault(); if (onContinueShopping) { @@ -42,11 +46,10 @@ const calculateTotalCost = (item) => { dispatch(removeItem(item.name)); }; - - return (

Total Cart Amount: ${calculateTotalAmount()}

+

Total Items in Cart: {totalQuantity}

{cart.map(item => (
@@ -65,7 +68,6 @@ const calculateTotalCost = (item) => {
))}
-

@@ -75,4 +77,4 @@ const calculateTotalCost = (item) => { ); }; -export default CartItem; \ No newline at end of file +export default CartItem; diff --git a/src/ProductList.jsx b/src/ProductList.jsx index a53526526..b247bd42a 100644 --- a/src/ProductList.jsx +++ b/src/ProductList.jsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { useDispatch } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import './ProductList.css'; import CartItem from './CartItem'; import { addItem } from './CartSlice'; @@ -8,6 +8,7 @@ function ProductList() { const [showPlants, setShowPlants] = useState(true); // Start by showing plants const [addedToCart, setAddedToCart] = useState({}); const dispatch = useDispatch(); + const totalQuantity = useSelector(state => state.cart.totalQuantity); const plantsArray = [ { category: "Air Purifying Plants", @@ -274,7 +275,11 @@ return (
From ac545f0e9055bdc7eaedf9bf71059eda37564f68 Mon Sep 17 00:00:00 2001 From: AnPeso Date: Wed, 12 Feb 2025 12:29:58 -0500 Subject: [PATCH 8/8] publish --- package-lock.json | 235 +++++++++++++++++++++++++++++++++----------- package.json | 4 +- src/ProductList.css | 2 +- vite.config.js | 2 +- 4 files changed, 180 insertions(+), 63 deletions(-) diff --git a/package-lock.json b/package-lock.json index af7843d84..3e89598b7 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 b7d4c1d1d..bebf32a8c 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" } } diff --git a/src/ProductList.css b/src/ProductList.css index 52f9c7a84..3cdbe9807 100644 --- a/src/ProductList.css +++ b/src/ProductList.css @@ -1,7 +1,7 @@ /* Reset some default styles */ body, h1, ul { margin: 0; - padding: 0; + padding: 3; } /* Set a background color */ diff --git a/vite.config.js b/vite.config.js index 4d190ae43..beeaed5cd 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()], })