From 5277299cfdd32067905bb32e6b165d3fa1d909e7 Mon Sep 17 00:00:00 2001 From: IC-Administrator Date: Sat, 15 Feb 2025 14:52:36 -0500 Subject: [PATCH 1/4] edited ConferenceEvent.jsx, avSlice.js and store.js to include AV addons functionality --- src/ConferenceEvent.jsx | 25 ++++++++++++++++++++++++- src/avSlice.js | 41 ++++++++++++++++++++++++++++++++++++++--- src/store.js | 3 ++- 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/ConferenceEvent.jsx b/src/ConferenceEvent.jsx index 612a4648..7a6e3f5b 100644 --- a/src/ConferenceEvent.jsx +++ b/src/ConferenceEvent.jsx @@ -3,10 +3,12 @@ import "./ConferenceEvent.css"; import TotalCost from "./TotalCost"; import { useSelector, useDispatch } from "react-redux"; import { incrementQuantity, decrementQuantity } from "./venueSlice"; +import { incrementAvQuantity, decrementAvQuantity } from "./avSlice"; const ConferenceEvent = () => { const [showItems, setShowItems] = useState(false); const [numberOfPeople, setNumberOfPeople] = useState(1); const venueItems = useSelector((state) => state.venue); + const avItems = useSelector((state) => state.av); const dispatch = useDispatch(); const remainingAuditoriumQuantity = 3 - venueItems.find(item => item.name === "Auditorium Hall (Capacity:200)").quantity; @@ -29,9 +31,11 @@ const ConferenceEvent = () => { } }; const handleIncrementAvQuantity = (index) => { + dispatch(incrementAvQuantity(index)); }; const handleDecrementAvQuantity = (index) => { + dispatch(decrementAvQuantity(index)); }; const handleMealSelection = (index) => { @@ -53,9 +57,14 @@ const ConferenceEvent = () => { venueItems.forEach((item) => { totalCost += item.cost * item.quantity; }); + } else if (section === "av") { + avItems.forEach((item) => { + totalCost += item.cost * item.quantity; + }); } return totalCost; }; + const avTotalCost = calculateTotalCost("av"); const venueTotalCost = calculateTotalCost("venue"); const navigateToProducts = (idType) => { @@ -157,9 +166,23 @@ const ConferenceEvent = () => {
+ {avItems.map((item, index) => ( +
+
+ {item.name} +
+
{item.name}
+
${item.cost}
+
+ + {item.quantity} + +
+
+ ))}
-
Total Cost:
+
Total Cost: {avTotalCost}
diff --git a/src/avSlice.js b/src/avSlice.js index cdd79aac..0d03683e 100644 --- a/src/avSlice.js +++ b/src/avSlice.js @@ -3,16 +3,51 @@ import { createSlice } from "@reduxjs/toolkit"; export const avSlice = createSlice({ name: "av", initialState: [ - + { + img: "https://pixabay.com/images/download/business-20031_640.jpg", + name: "Projectors", + cost: 200, + quantity: 0, + }, + { + img: "https://pixabay.com/images/download/speakers-4109274_640.jpg", + name: "Speaker", + cost: 35, + quantity: 0, + }, + { + img: "https://pixabay.com/images/download/public-speaking-3926344_640.jpg", + name: "Microphones", + cost: 45, + quantity: 0, + }, + { + img: "https://pixabay.com/images/download/whiteboard-2903269_640.png", + name: "Whiteboards", + cost: 80, + quantity: 0, + }, + { + img: "https://pixabay.com/images/download/signpost-235079_640.jpg", + name: "Signage", + cost: 80, + quantity: 0, + }, ], reducers: { incrementAvQuantity: (state, action) => { - + const item = state[action.payload]; + if (item) { + item.quantity++; + } }, decrementAvQuantity: (state, action) => { - + const item = state[action.payload]; + if (item && item.quantity > 0) { + item.quantity--; + } }, }, }); diff --git a/src/store.js b/src/store.js index f05b9f8f..725114eb 100644 --- a/src/store.js +++ b/src/store.js @@ -1,9 +1,10 @@ // store.js import { configureStore } from '@reduxjs/toolkit'; import venueReducer from './venueSlice'; - +import avReducer from './avSlice'; export default configureStore({ reducer: { venue: venueReducer, + av: avReducer, }, }); From 5823c05f3df88707c5f5f66a0c47e6515449f898 Mon Sep 17 00:00:00 2001 From: IC-Administrator Date: Sat, 15 Feb 2025 15:11:26 -0500 Subject: [PATCH 2/4] edited ConferenceEvent.jsx, mealsSlice.js and store.js to include meals addons functionality --- src/ConferenceEvent.jsx | 44 +++++++++++++++++++++++++++++++++++------ src/mealsSlice.js | 6 +++++- src/store.js | 2 ++ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/ConferenceEvent.jsx b/src/ConferenceEvent.jsx index 7a6e3f5b..da0657b5 100644 --- a/src/ConferenceEvent.jsx +++ b/src/ConferenceEvent.jsx @@ -4,11 +4,13 @@ import TotalCost from "./TotalCost"; import { useSelector, useDispatch } from "react-redux"; import { incrementQuantity, decrementQuantity } from "./venueSlice"; import { incrementAvQuantity, decrementAvQuantity } from "./avSlice"; +import { toggleMealSelection } from "./mealsSlice"; const ConferenceEvent = () => { const [showItems, setShowItems] = useState(false); const [numberOfPeople, setNumberOfPeople] = useState(1); const venueItems = useSelector((state) => state.venue); const avItems = useSelector((state) => state.av); + const mealsItems = useSelector((state) => state.meals); const dispatch = useDispatch(); const remainingAuditoriumQuantity = 3 - venueItems.find(item => item.name === "Auditorium Hall (Capacity:200)").quantity; @@ -39,7 +41,15 @@ const ConferenceEvent = () => { }; const handleMealSelection = (index) => { - + const item = mealsItems[index]; + if (item.selected && item.type === "mealForPeople") { + // Ensure numberOfPeople is set before toggling selection + const newNumberOfPeople = item.selected ? numberOfPeople : 0; + dispatch(toggleMealSelection(index, newNumberOfPeople)); + } + else { + dispatch(toggleMealSelection(index)); + } }; const getItemsFromTotalCost = () => { @@ -58,13 +68,20 @@ const ConferenceEvent = () => { totalCost += item.cost * item.quantity; }); } else if (section === "av") { - avItems.forEach((item) => { - totalCost += item.cost * item.quantity; + avItems.forEach((item) => { + totalCost += item.cost * item.quantity; + }); + } else if (section === "meals") { + mealsItems.forEach((item) => { + if (item.selected) { + totalCost += item.cost * numberOfPeople; + } }); } return totalCost; }; const avTotalCost = calculateTotalCost("av"); + const mealsTotalCost = calculateTotalCost("meals"); const venueTotalCost = calculateTotalCost("venue"); const navigateToProducts = (idType) => { @@ -196,12 +213,27 @@ const ConferenceEvent = () => {
- + + setNumberOfPeople(parseInt(e.target.value))} + min="1" + />
- + {mealsItems.map((item, index) => ( +
+
+ handleMealSelection(index)} + /> + +
+
${item.cost}
+
+ ))}
-
Total Cost:
+
Total Cost: {mealsTotalCost}
diff --git a/src/mealsSlice.js b/src/mealsSlice.js index faf8138a..2d8d1960 100644 --- a/src/mealsSlice.js +++ b/src/mealsSlice.js @@ -4,10 +4,14 @@ import { createSlice } from '@reduxjs/toolkit'; export const mealsSlice = createSlice({ name: 'meals', initialState: [ - + { name: 'Breakfast', cost: 50, selected: false }, + { name: 'High Tea', cost: 25, selected: false }, + { name: 'Lunch', cost: 65, selected: false }, + { name: 'Dinner', cost: 70, selected: false }, ], reducers: { toggleMealSelection: (state, action) => { + state[action.payload].selected = !state[action.payload].selected; }, }, }); diff --git a/src/store.js b/src/store.js index 725114eb..0c2d54ea 100644 --- a/src/store.js +++ b/src/store.js @@ -2,9 +2,11 @@ import { configureStore } from '@reduxjs/toolkit'; import venueReducer from './venueSlice'; import avReducer from './avSlice'; +import mealsReducer from './mealsSlice'; export default configureStore({ reducer: { venue: venueReducer, av: avReducer, + meals: mealsReducer, }, }); From 3f177211306f486d2e702e929a5ba182ff939cdf Mon Sep 17 00:00:00 2001 From: IC-Administrator Date: Sat, 15 Feb 2025 15:22:40 -0500 Subject: [PATCH 3/4] edited ConferenceEvent.jsx to display selected items and cost details in a table --- src/ConferenceEvent.jsx | 64 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/src/ConferenceEvent.jsx b/src/ConferenceEvent.jsx index da0657b5..45f26447 100644 --- a/src/ConferenceEvent.jsx +++ b/src/ConferenceEvent.jsx @@ -54,13 +54,69 @@ const ConferenceEvent = () => { const getItemsFromTotalCost = () => { const items = []; + venueItems.forEach((item) => { + if (item.quantity > 0) { + items.push({ ...item, type: "venue" }); + } + }); + avItems.forEach((item) => { + if ( + item.quantity > 0 && + !items.some((i) => i.name === item.name && i.type === "av") + ) { + items.push({ ...item, type: "av" }); + } + }); + mealsItems.forEach((item) => { + if (item.selected) { + const itemForDisplay = { ...item, type: "meals" }; + if (item.numberOfPeople) { + itemForDisplay.numberOfPeople = numberOfPeople; + } + items.push(itemForDisplay); + } + }); + return items; }; const items = getItemsFromTotalCost(); const ItemsDisplay = ({ items }) => { - + console.log(items); + return <> +
+ {items.length === 0 &&

No items selected

} + + + + + + + + + + + {items.map((item, index) => ( + + + + + + + ))} + +
NameUnit CostQuantitySubtotal
{item.name}${item.cost} + {item.type === "meals" || item.numberOfPeople + ? ` For ${numberOfPeople} people` + : item.quantity} + {item.type === "meals" || item.numberOfPeople + ? `${item.cost * numberOfPeople}` + : `${item.cost * item.quantity}`} +
+
+ }; + const calculateTotalCost = (section) => { let totalCost = 0; if (section === "venue") { @@ -91,7 +147,11 @@ const ConferenceEvent = () => { } } } - + const totalCosts = { + venue: venueTotalCost, + av: avTotalCost, + meals: mealsTotalCost, + }; return ( <> From 43bece566ac5a37456c8ee9d796459af3eccd695 Mon Sep 17 00:00:00 2001 From: IC-Administrator Date: Sat, 15 Feb 2025 15:30:40 -0500 Subject: [PATCH 4/4] Edited TotalCost.jsx with logic to display items in table when Show Details button is selected --- src/TotalCost.jsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/TotalCost.jsx b/src/TotalCost.jsx index 845abca9..7d7862d4 100644 --- a/src/TotalCost.jsx +++ b/src/TotalCost.jsx @@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react'; import "./TotalCost.css"; const TotalCost = ({ totalCosts, ItemsDisplay }) => { + const total_amount = totalCosts.venue + totalCosts.av + totalCosts.meals; return ( @@ -11,12 +12,11 @@ const TotalCost = ({ totalCosts, ItemsDisplay }) => {

Total cost for the event

-

- -

- -
- +

+ ${total_amount} +

+
+