diff --git a/src/CartItem.jsx b/src/CartItem.jsx
index e06317433f..5f38c2210f 100644
--- a/src/CartItem.jsx
+++ b/src/CartItem.jsx
@@ -4,63 +4,99 @@ 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 = () => {
-
- };
-
- const handleContinueShopping = (e) => {
-
- };
-
-
-
- const handleIncrement = (item) => {
- };
-
- const handleDecrement = (item) => {
-
- };
-
- const handleRemove = (item) => {
- };
-
- // Calculate total cost based on quantity for an item
- const calculateTotalCost = (item) => {
- };
-
- return (
-
-
Total Cart Amount: ${calculateTotalAmount()}
-
- {cart.map(item => (
-
-

-
-
{item.name}
-
{item.cost}
-
-
- {item.quantity}
-
-
-
Total: ${calculateTotalCost(item)}
-
+ const cart = useSelector(state => state.cart.items);
+ const dispatch = useDispatch();
+
+
+ const parseItemCostToInteger = (itemCost) => {
+ /*
+ Remove currency symbol before multiplication.
+ Otherwise, NaN returned.
+ Improve in future: Use regex to remove all possible currency symbols?
+ */
+ return parseInt(itemCost.replace('$', ''), 10);
+ };
+
+ // Calculate total amount for all products in the cart
+ const calculateTotalAmount = () => {
+ let totalCost = 0;
+
+ cart.forEach((item) => {
+ const itemCost = parseItemCostToInteger(item.cost);
+ totalCost += itemCost * item.quantity;
+ });
+
+ return totalCost;
+ };
+
+ const handleContinueShopping = (e) => {
+ onContinueShopping(e);
+ };
+
+ const handleCheckoutShopping = (e) => {
+ alert('Functionality to be added for future reference');
+ };
+
+ const handleIncrement = (item) => {
+ const updatedItem = { ...item };
+ updatedItem.quantity++;
+ dispatch(updateQuantity(updatedItem));
+ };
+
+ const handleDecrement = (item) => {
+ const updatedItem = { ...item };
+
+ if (updatedItem.quantity == 1) {
+ // Remove item if number of items gets decremented to 0
+ dispatch(removeItem(updatedItem));
+ } else {
+ updatedItem.quantity--;
+ dispatch(updateQuantity(updatedItem));
+ }
+ };
+
+ const handleRemove = (item) => {
+ dispatch(removeItem(item));
+ };
+
+ // Calculate total cost based on quantity for an item
+ const calculateTotalCost = (item) => {
+ let totalCost = 0;
+ const itemCost = parseItemCostToInteger(item.cost);
+ totalCost = item.quantity * itemCost;
+
+ return totalCost;
+ };
+
+ return (
+
+
Total Cart Amount: ${calculateTotalAmount()}
+
+ {cart.map(item => (
+
+

+
+
{item.name}
+
{item.cost}
+
+
+ {item.quantity}
+
+
+
Total: ${calculateTotalCost(item)}
+
+
+
+ ))}
+
+
+
+
+
+
-
- ))}
-
-
-
-
-
-
-
-
- );
+
+ );
};
export default CartItem;
diff --git a/src/CartSlice.jsx b/src/CartSlice.jsx
index 32b8761ed0..6b142d16fb 100644
--- a/src/CartSlice.jsx
+++ b/src/CartSlice.jsx
@@ -1,21 +1,49 @@
import { createSlice } from '@reduxjs/toolkit';
export const CartSlice = createSlice({
- name: 'cart',
- initialState: {
- items: [], // Initialize items as an empty array
- },
- reducers: {
- addItem: (state, action) => {
-
+ name: 'cart',
+ initialState: {
+ items: [], // Initialize items as an empty array
+ numOfItems: 0 // Number of items multiplied by their quantity
},
- removeItem: (state, action) => {
- },
- updateQuantity: (state, action) => {
-
+ reducers: {
+ addItem: (state, action) => {
+ const { name, image, cost } = action.payload;
+ const existingItem = state.items.find(item => item.name === name);
+
+ if (existingItem) {
+ // In existing items, quantity is already added as property
+ existingItem.quantity++;
+ } else {
+ state.items.push({ name, image, cost, quantity: 1 });
+ }
+
+ state.numOfItems += 1;
+ },
+
+ removeItem: (state, action) => {
+ const { name, quantity } = action.payload;
+ state.items = state.items.filter(item => item.name !== name);
+ state.numOfItems -= quantity;
+
+ // Just to be sure... I hate negative numbers
+ if (state.numOfItems < 0) {
+ state.numOfItems = 0;
+ }
+ },
+
+ updateQuantity: (state, action) => {
+ const { name, quantity } = action.payload;
+ const existingItem = state.items.find(item => item.name === name);
+
+ if (existingItem) {
+ const differenceQuantity = quantity - existingItem.quantity;
+ state.numOfItems += differenceQuantity;
+ existingItem.quantity = quantity;
+ }
+ },
},
- },
});
export const { addItem, removeItem, updateQuantity } = CartSlice.actions;
diff --git a/src/ProductList.jsx b/src/ProductList.jsx
index 7682c04fc4..aff34b8495 100644
--- a/src/ProductList.jsx
+++ b/src/ProductList.jsx
@@ -1,287 +1,252 @@
-import React, { useState, useEffect } from 'react';
-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
+/* Reset some default styles */
+body, h1, ul {
+ margin: 0;
+ padding: 0;
+}
- const plantsArray = [
- {
- category: "Air Purifying Plants",
- plants: [
- {
- name: "Snake Plant",
- image: "https://cdn.pixabay.com/photo/2021/01/22/06/04/snake-plant-5939187_1280.jpg",
- description: "Produces oxygen at night, improving air quality.",
- cost: "$15"
- },
- {
- name: "Spider Plant",
- image: "https://cdn.pixabay.com/photo/2018/07/11/06/47/chlorophytum-3530413_1280.jpg",
- description: "Filters formaldehyde and xylene from the air.",
- cost: "$12"
- },
- {
- name: "Peace Lily",
- image: "https://cdn.pixabay.com/photo/2019/06/12/14/14/peace-lilies-4269365_1280.jpg",
- description: "Removes mold spores and purifies the air.",
- cost: "$18"
- },
- {
- name: "Boston Fern",
- image: "https://cdn.pixabay.com/photo/2020/04/30/19/52/boston-fern-5114414_1280.jpg",
- description: "Adds humidity to the air and removes toxins.",
- cost: "$20"
- },
- {
- name: "Rubber Plant",
- image: "https://cdn.pixabay.com/photo/2020/02/15/11/49/flower-4850729_1280.jpg",
- description: "Easy to care for and effective at removing toxins.",
- cost: "$17"
- },
- {
- name: "Aloe Vera",
- image: "https://cdn.pixabay.com/photo/2018/04/02/07/42/leaf-3283175_1280.jpg",
- description: "Purifies the air and has healing properties for skin.",
- cost: "$14"
- }
- ]
- },
- {
- category: "Aromatic Fragrant Plants",
- plants: [
- {
- name: "Lavender",
- image: "https://images.unsplash.com/photo-1611909023032-2d6b3134ecba?q=80&w=1074&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
- description: "Calming scent, used in aromatherapy.",
- cost: "$20"
- },
- {
- name: "Jasmine",
- image: "https://images.unsplash.com/photo-1592729645009-b96d1e63d14b?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
- description: "Sweet fragrance, promotes relaxation.",
- cost: "$18"
- },
- {
- name: "Rosemary",
- image: "https://cdn.pixabay.com/photo/2019/10/11/07/12/rosemary-4541241_1280.jpg",
- description: "Invigorating scent, often used in cooking.",
- cost: "$15"
- },
- {
- name: "Mint",
- image: "https://cdn.pixabay.com/photo/2016/01/07/18/16/mint-1126282_1280.jpg",
- description: "Refreshing aroma, used in teas and cooking.",
- cost: "$12"
- },
- {
- name: "Lemon Balm",
- image: "https://cdn.pixabay.com/photo/2019/09/16/07/41/balm-4480134_1280.jpg",
- description: "Citrusy scent, relieves stress and promotes sleep.",
- cost: "$14"
- },
- {
- name: "Hyacinth",
- image: "https://cdn.pixabay.com/photo/2019/04/07/20/20/hyacinth-4110726_1280.jpg",
- description: "Hyacinth is a beautiful flowering plant known for its fragrant.",
- cost: "$22"
- }
- ]
- },
- {
- category: "Insect Repellent Plants",
- plants: [
- {
- name: "oregano",
- image: "https://cdn.pixabay.com/photo/2015/05/30/21/20/oregano-790702_1280.jpg",
- description: "The oregano plants contains compounds that can deter certain insects.",
- cost: "$10"
- },
- {
- name: "Marigold",
- image: "https://cdn.pixabay.com/photo/2022/02/22/05/45/marigold-7028063_1280.jpg",
- description: "Natural insect repellent, also adds color to the garden.",
- cost: "$8"
- },
- {
- name: "Geraniums",
- image: "https://cdn.pixabay.com/photo/2012/04/26/21/51/flowerpot-43270_1280.jpg",
- description: "Known for their insect-repelling properties while adding a pleasant scent.",
- cost: "$20"
- },
- {
- name: "Basil",
- image: "https://cdn.pixabay.com/photo/2016/07/24/20/48/tulsi-1539181_1280.jpg",
- description: "Repels flies and mosquitoes, also used in cooking.",
- cost: "$9"
- },
- {
- name: "Lavender",
- image: "https://images.unsplash.com/photo-1611909023032-2d6b3134ecba?q=80&w=1074&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
- description: "Calming scent, used in aromatherapy.",
- cost: "$20"
- },
- {
- name: "Catnip",
- image: "https://cdn.pixabay.com/photo/2015/07/02/21/55/cat-829681_1280.jpg",
- description: "Repels mosquitoes and attracts cats.",
- cost: "$13"
- }
- ]
- },
- {
- category: "Medicinal Plants",
- plants: [
- {
- name: "Aloe Vera",
- image: "https://cdn.pixabay.com/photo/2018/04/02/07/42/leaf-3283175_1280.jpg",
- description: "Soothing gel used for skin ailments.",
- cost: "$14"
- },
- {
- name: "Echinacea",
- image: "https://cdn.pixabay.com/photo/2014/12/05/03/53/echinacea-557477_1280.jpg",
- description: "Boosts immune system, helps fight colds.",
- cost: "$16"
- },
- {
- name: "Peppermint",
- image: "https://cdn.pixabay.com/photo/2017/07/12/12/23/peppermint-2496773_1280.jpg",
- description: "Relieves digestive issues and headaches.",
- cost: "$13"
- },
- {
- name: "Lemon Balm",
- image: "https://cdn.pixabay.com/photo/2019/09/16/07/41/balm-4480134_1280.jpg",
- description: "Calms nerves and promotes relaxation.",
- cost: "$14"
- },
- {
- name: "Chamomile",
- image: "https://cdn.pixabay.com/photo/2016/08/19/19/48/flowers-1606041_1280.jpg",
- description: "Soothes anxiety and promotes sleep.",
- cost: "$15"
- },
- {
- name: "Calendula",
- image: "https://cdn.pixabay.com/photo/2019/07/15/18/28/flowers-4340127_1280.jpg",
- description: "Heals wounds and soothes skin irritations.",
- cost: "$12"
- }
- ]
- },
- {
- category: "Low Maintenance Plants",
- plants: [
- {
- name: "ZZ Plant",
- image: "https://images.unsplash.com/photo-1632207691143-643e2a9a9361?q=80&w=464&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
- description: "Thrives in low light and requires minimal watering.",
- cost: "$25"
- },
- {
- name: "Pothos",
- image: "https://cdn.pixabay.com/photo/2018/11/15/10/32/plants-3816945_1280.jpg",
- description: "Tolerates neglect and can grow in various conditions.",
- cost: "$10"
- },
- {
- name: "Snake Plant",
- image: "https://cdn.pixabay.com/photo/2021/01/22/06/04/snake-plant-5939187_1280.jpg",
- description: "Needs infrequent watering and is resilient to most pests.",
- cost: "$15"
- },
- {
- name: "Cast Iron Plant",
- image: "https://cdn.pixabay.com/photo/2017/02/16/18/04/cast-iron-plant-2072008_1280.jpg",
- description: "Hardy plant that tolerates low light and neglect.",
- cost: "$20"
- },
- {
- name: "Succulents",
- image: "https://cdn.pixabay.com/photo/2016/11/21/16/05/cacti-1846147_1280.jpg",
- description: "Drought-tolerant plants with unique shapes and colors.",
- cost: "$18"
- },
- {
- name: "Aglaonema",
- image: "https://cdn.pixabay.com/photo/2014/10/10/04/27/aglaonema-482915_1280.jpg",
- description: "Requires minimal care and adds color to indoor spaces.",
- cost: "$22"
- }
- ]
- }
- ];
- const styleObj = {
- backgroundColor: '#4CAF50',
- color: '#fff!important',
- padding: '15px',
- display: 'flex',
- justifyContent: 'space-between',
- alignIems: 'center',
- fontSize: '20px',
- }
- const styleObjUl = {
- display: 'flex',
- justifyContent: 'space-between',
- alignItems: 'center',
- width: '1100px',
- }
- const styleA = {
- color: 'white',
- fontSize: '30px',
- textDecoration: 'none',
- }
+/* Set a background color */
+body {
+ font-family: Arial, sans-serif;
+ background-color: #f0f0f0;
+}
+
+/* Navbar */
+.navbar {
+ background-color: #4CAF50;
+ color: #fff!important;
+ padding: 15px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-size: 20px;
+}
+
+.navbar .ul {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ width: 1100px;
+}
+
+.navbar li {
+ margin-right: 30px;
+}
- const handleHomeClick = (e) => {
- e.preventDefault();
- onHomeClick();
- };
+.navbar .ul div a {
+ color: white;
+ font-size: 30px;
+ text-decoration: none;
+
+}
- const handleCartClick = (e) => {
- e.preventDefault();
- setShowCart(true); // Set showCart to true when cart icon is clicked
- };
- 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
- };
+/* Product Grid */
+.product-grid {
+ display:flex;
+ flex-direction: column;
+ width: 100vw;
+ align-items: center;
+ justify-content: center;
+}
+.product-list {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 50px;
+ /* background-color: pink; */
+ /* justify-content: space-between; */
+ padding: 20px;
+ width: 100%;
+ align-items: center;
+ justify-content: center;
+}
- const handleContinueShopping = (e) => {
- e.preventDefault();
- setShowCart(false);
- };
- return (
-
-
-
-
+/* Product Card */
+.product-card {
+ flex: 0 0 calc(33.33% - 20px); /* Adjust width for 3 cards per row with 20px gap */
+ max-width: calc(26.33% - 20px); /* Adjust max-width for 3 cards per row with 20px gap */
+ margin-bottom: 20px;
+ padding: 20px;
+ background-color: #fff;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+ text-align: center;
+ position: relative;
+
+ gap: 20px;
+}
-
-
-
- {!showCart ? (
-
+/* Pseudo-classes - Hover effect on product button */
+.product-card:hover {
+ transform: scale(1.05);
+ transition: transform 0.3s ease-in-out;
+ z-index: 1;
+}
+.product-title {
+ font-weight: bold;
+ margin-bottom: 10px;
+}
-
- ) : (
-
- )}
-
- );
+.product-price {
+ color: #e74c3c;
+ font-size: 1.2rem;
+ margin-bottom: 10px;
}
-export default ProductList;
+.product-image {
+ max-width: 100%;
+ height: 200px; /* Adjust height for better consistency */
+}
+
+.product-button {
+ background-color: #e74c3c;
+ color: #fff;
+ border: none;
+ padding: 10px 20px;
+ cursor: pointer;
+ transition: background-color 0.3s ease-in-out;
+ margin-top: 10px;
+}
+
+.product-button:hover {
+ background-color: #c0392b;
+}
+
+/* Pseudo-elements - Sale badge */
+.product-card::before {
+ content: "SALE";
+ background-color: #e74c3c;
+ color: #fff;
+ position: absolute;
+ top: 0;
+ right: 0;
+ padding: 5px 10px;
+ border-radius: 0 0 0 5px;
+}
+.tag_home_link{
+ display: flex;
+ /* background-color: red; */
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ margin-left: 50px;
+ color: white;
+ text-decoration: none;
+ font-size: 20px;
+}
+.tag_home_link h3{
+ font-size: 30px;
+}
+.tag a{
+ text-decoration: none;
+}
+.tag {
+ width: 400px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.tag img {
+ height: 70px;
+ width: 70px;
+ border-radius: 70%;
+
+}
+
+.luxury {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 650px;
+ font-size: 19px;
+}
+.cart{
+ color: white;
+ display: flex;
+}
+.cart_quantity_count{
+ margin-top: 16px;
+ /* background-color: red; */
+ margin-left: 27px;
+ position: absolute;
+ font-size: 29px;
+
+}
+.plantname_heading{
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ /* background-color: yellow; */
+}
+.plant_heading{
+ width: 400px;
+ text-align: center;
+ margin: 20px;
+ border: 1px solid rgb(5, 4, 4);
+ border-left: none;
+ border-right: none;
+
+
+}
+/* Add Media Query for responsiveness */
+@media (max-width: 768px) {
+ .product-card {
+ flex: 1 1 calc(50% - 20px); /* Adjust width for 2 cards per row with 20px gap on smaller screens */
+ max-width: calc(50% - 20px); /* Adjust max-width for 2 cards per row with 20px gap on smaller screens */
+ }
+}
+/* ProductList.css */
+
+.product-button {
+ background-color: #4CAF50; /* Green */
+ border: none;
+ color: white;
+ padding: 10px 20px;
+ text-align: center;
+ text-decoration: none;
+ display: inline-block;
+ font-size: 16px;
+ margin: 4px 2px;
+ transition-duration: 0.4s;
+ cursor: pointer;
+ }
+
+ .product-button:hover {
+ background-color: #45a049;
+ }
+
+ .product-button.added-to-cart {
+ background-color: grey; /* Grey when product is added */
+ }
+ @media (max-width: 1200px) {
+ .product-card {
+ flex: 1 1 calc(33.33% - 20px); /* Adjust width for 3 cards per row with 20px gap on medium screens */
+ max-width: calc(33.33% - 20px); /* Adjust max-width for 3 cards per row with 20px gap on medium screens */
+ }
+ }
+
+ @media (max-width: 768px) {
+ .product-card {
+ flex: 1 1 calc(50% - 20px); /* Adjust width for 2 cards per row with 20px gap on small screens */
+ max-width: calc(50% - 20px); /* Adjust max-width for 2 cards per row with 20px gap on small screens */
+ }
+ .navbar {
+ flex-direction: column; /* Change flex direction to stack items vertically */
+ align-items: center; /* Align items to the center of the container */
+ }
+
+ .tag {
+ margin-bottom: 20px; /* Add margin bottom for spacing */
+ text-align: center; /* Align text to the center */
+ }
+
+ .ul {
+ display: flex; /* Set display to flex */
+ flex-direction: column; /* Change flex direction to stack items vertically */
+ gap: 10px; /* Add gap between items */
+ }
+
+ .ul div {
+ text-align: center; /* Align text to the center */
+ }
+ }
diff --git a/src/store.js b/src/store.js
index 54d0d6d66e..57a00db8c5 100644
--- a/src/store.js
+++ b/src/store.js
@@ -1,8 +1,9 @@
import { configureStore } from '@reduxjs/toolkit';
import cartReducer from './CartSlice';
+
const store = configureStore({
reducer: {
cart: cartReducer,
},
});
-export default store
+export default store
\ No newline at end of file
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()],
})