Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
60db076
Added objects inside the array varible "initialState"
rodrigcasio Sep 9, 2025
f08b555
Added "Add-ons" images for "avSlice.js" objects
rodrigcasio Sep 9, 2025
7b9d85f
Added correct path for images used for the value property of img
rodrigcasio Sep 9, 2025
6b9ab98
Created logic for reducer functions "incrementAvQuantity and decremen…
rodrigcasio Sep 9, 2025
6310b3a
Added the "avSlice" to the redux "store.js"
rodrigcasio Sep 9, 2025
a77f6f7
Imported add-on items and by creating a variable called "avItems" tha…
rodrigcasio Sep 9, 2025
eefa8f3
Starting to display "avItems" data with map() method
rodrigcasio Sep 9, 2025
b97086b
Added functionality to display "avItems" data using a map() method and
rodrigcasio Sep 9, 2025
48e7f64
Inside the preinitialized functions for "av" actions, need to dispatc…
rodrigcasio Sep 9, 2025
56c0f92
Imported reducer functions so it can be used when calling the functio…
rodrigcasio Sep 9, 2025
721c55e
Added av items to the function that sums up the cost of the items fro…
rodrigcasio Sep 9, 2025
cf49d0b
Created a const "avTotalCost" which stores the total cost of the "av"…
rodrigcasio Sep 9, 2025
bed150c
Added meal items data in an array inside the initial state of meals
rodrigcasio Sep 9, 2025
64e5270
Added logic for function reducer "toggleMealSelection"
rodrigcasio Sep 9, 2025
19d1b69
Imported "mealsSlice.js" into the redux store to import details
rodrigcasio Sep 9, 2025
8c2e3e3
Created a const variable named "mealsItems" to import access to the d…
rodrigcasio Sep 9, 2025
6b9c37b
Making use of the "numberOfPeople" varible with useState to modify th…
rodrigcasio Sep 9, 2025
8227078
Added a map method for the "mealsItems" varible to display data from …
rodrigcasio Sep 9, 2025
def3353
Imported the function reducer "toggleMealSeletion" into "ConferenceEv…
rodrigcasio Sep 9, 2025
dea1d3d
Added the logic ot obtain the total cost based on the numberOfPeople …
rodrigcasio Sep 9, 2025
814a476
Included the result of the const "mealsTotalCost" inside the <div nod…
rodrigcasio Sep 9, 2025
67ac794
Created object named "totalCosts" to include the subtotals of the "ve…
rodrigcasio Sep 9, 2025
185cd27
Added logic for gitItemsFromTotalCost function which store all the it…
rodrigcasio Sep 9, 2025
3a733e5
Added content to the component "ItemDisplay"
rodrigcasio Sep 9, 2025
b40fd77
Added const "total_amount" to sum up the subtotals for "venue, av and…
rodrigcasio Sep 9, 2025
e0338bb
Fixed typo for the name of the file projector
rodrigcasio Sep 9, 2025
5a86eef
Erased unused space inside the return function
rodrigcasio Sep 9, 2025
e253073
Added suggestions to fix the issue with .length'
rodrigcasio Sep 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/imgsFinalPractice/auditorium.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/imgsFinalPractice/conferenceRoom.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/imgsFinalPractice/meetingRoom.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/imgsFinalPractice/microphone.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/imgsFinalPractice/presentationRoom.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/imgsFinalPractice/projector.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/imgsFinalPractice/signpost.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/imgsFinalPractice/smallMeetingRoom.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/imgsFinalPractice/speakers.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/imgsFinalPractice/whiteboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
183 changes: 158 additions & 25 deletions src/ConferenceEvent.jsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
import React, { useState } from "react";
import { useState } from "react";
import "./ConferenceEvent.css";
import TotalCost from "./TotalCost";
import { useSelector, useDispatch } from "react-redux";
import { incrementQuantity, decrementQuantity } from "./venueSlice";
import { incrementAvQuantity, decrementAvQuantity } from "./avSlice.js";
import { toggleMealSelection } from './mealsSlice.js';

const ConferenceEvent = () => {
const [showItems, setShowItems] = useState(false);
const [numberOfPeople, setNumberOfPeople] = useState(1);

// venue:
const venueItems = useSelector((state) => state.venue);
const dispatch = useDispatch();
const dispatch = useDispatch(); // used by all slices
const remainingAuditoriumQuantity = 3 - venueItems.find(item => item.name === "Auditorium Hall (Capacity:200)").quantity;


// av:
const avItems = useSelector((state) => state.av);

// meals:
const mealsItems = useSelector((state) => state.meals);


const handleToggleItems = () => {
console.log("handleToggleItems called");
setShowItems(!showItems);
Expand All @@ -23,41 +34,124 @@ const ConferenceEvent = () => {
dispatch(incrementQuantity(index));
};

const handleRemoveFromCart = (index) => {
if (venueItems[index].quantity > 0) {
dispatch(decrementQuantity(index));
}
};
const handleRemoveFromCart = (index) => {
if (venueItems[index].quantity > 0) {
dispatch(decrementQuantity(index));
}
};

// av:
const handleIncrementAvQuantity = (index) => {
dispatch(incrementAvQuantity(index));
};

// av:
const handleDecrementAvQuantity = (index) => {
dispatch(decrementAvQuantity(index));
};

// meals:
const handleMealSelection = (index) => {

const item = mealsItems[index];
if(item.selected && item.type === 'mealForPeople'){
const newNumberOfPeople = item.selected ? numberOfPeople : 0;
dispatch(toggleMealSelection(index, newNumberOfPeople));
}else{
dispatch(toggleMealSelection(index));
}
};

const getItemsFromTotalCost = () => {
const items = [];
venueItems.forEach((item) => {
if(item.quantity > 0){
items.push({...item, type: "venue"});
}
});
avItems.forEach((item) => {
if(
item.quantity && !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 <>
<div className="display_box1">
{items.length === 0 && <p>No items selected</p>}
<table className="table_item_data">
<thead>
<tr>
<th>Name</th>
<th>Unit Cost</th>
<th>Quantity</th>
<th>Subtotal</th>
</tr>
</thead>
<tbody>
{items.map((item, index) => (
<tr key={index}>
<td>{item.name}</td>
<td>{item.cost}</td>
<td>
{item.type === "meals" || item.numberOfPeople ?
` For ${numberOfPeople} people` : item.quantity}
</td>
<td>{item.type === "meals" || item.numberOfPeople ?
`${item.cost * numberOfPeople}` : `${item.cost * item.quantity}`}
</td>
</tr>
))}
</tbody>
</table>
</div>
</>
};
const calculateTotalCost = (section) => {
let totalCost = 0;
if (section === "venue") {
venueItems.forEach((item) => {
totalCost += item.cost * item.quantity;
});
}else if(section === "av"){ // adding the costs of the data from the av items
avItems.forEach((item) => {
totalCost += item.cost * item.quantity;
});
}else if(section == "meals"){
mealsItems.forEach((item) => {
if(item.selected){
totalCost += item.cost * numberOfPeople; // if item is selected, its cost is multiplied by the numberOfPeople
}
});
}

return totalCost;
};

// venue:
const venueTotalCost = calculateTotalCost("venue");

// av:
const avTotalCost = calculateTotalCost("av");

// meals:
const mealsTotalCost = calculateTotalCost("meals");

const navigateToProducts = (idType) => {
if (idType == '#venue' || idType == '#addons' || idType == '#meals') {
if (showItems) { // Check if showItems is false
Expand All @@ -66,6 +160,13 @@ const ConferenceEvent = () => {
}
}

// object that include the all three subtotals in the totalcost
const totalCosts = {
venue: venueTotalCost,
av: avTotalCost,
meals: mealsTotalCost,
};

return (
<>
<navbar className="navbar_event_conference">
Expand Down Expand Up @@ -146,40 +247,63 @@ const ConferenceEvent = () => {
</div>
<div className="total_cost">Total Cost: ${venueTotalCost}</div>
</div>

{/*Necessary Add-ons*/}
<div id="addons" className="venue_container container_main">


<div className="text">

<h1> Add-ons Selection</h1>

</div>
<div className="addons_selection">

{avItems.map((item, index) => (
<div className="av_data venue_main" key={index}>
<div className="img">
<img src={item.img} alt={item.name} />
</div>
<div className="text"> {item.name}</div>
<div> ${item.cost}</div>
<div className="addons_btn">
<button className="btn-warning" onClick={() => handleDecrementAvQuantity(index)}> &ndash; </button>
<span className="quantity-value">{item.quantity}</span>
<button className=" btn-success" onClick={() => handleIncrementAvQuantity(index)}> &#43; </button>
</div>
</div>
))}
</div>
<div className="total_cost">Total Cost:</div>

<div className="total_cost">Total Cost: {avTotalCost}</div>
</div>

{/* Meal Section */}

<div id="meals" className="venue_container container_main">

<div className="text">

<h1>Meals Selection</h1>
</div>
<div className="meal_section">
{mealsItems.map((item, index) => (
<div className="meal_item" key={item} style={{ padding: 15 }}>
<div className="inner">
<input type="checkbox" id={`meal${index}`}
checked={item.selected}
onChange={() => handleMealSelection(index)}
/>
<label htmlFor={`meal${item}`}> {item.name} </label>
</div>
<div className="meal_cost">${item.cost}</div>
</div>
))}
</div>

<div className="input-container venue_selection">

<label htmlFor="numberOfPeople"><h3>Number of People:</h3></label>
<input type="number" className="input_box5" id="numberOfPeople" value={numberOfPeople}
onChange={(e) => setNumberOfPeople(parseInt(e.target.value))}
min="1" />
</div>
<div className="meal_selection">

</div>
<div className="total_cost">Total Cost: </div>

<div className="total_cost">Total Cost: {mealsTotalCost}</div>

</div>
</div>
Expand All @@ -190,13 +314,22 @@ const ConferenceEvent = () => {
)
}




</div>
</>

);
};

export default ConferenceEvent;

/*
tip added from copilot suggestions
TIP: For optimal code quality and easier debugging,
consider adding PropTypes to validate component props.
Example:
import PropTypes from 'prop-types';
MyComponent.propTypes = {
items: PropTypes.array.isRequired,
};
This helps catch bugs early and documents expected prop types.
*/
10 changes: 5 additions & 5 deletions src/TotalCost.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import React, { useState, useEffect } from 'react';
import "./TotalCost.css";

const TotalCost = ({ totalCosts, ItemsDisplay }) => {


const total_amount = totalCosts.venue + totalCosts.av + totalCosts.meals;

return (
<div className="pricing-app">
Expand All @@ -12,11 +13,10 @@ const TotalCost = ({ totalCosts, ItemsDisplay }) => {
</div>
<div>
<h2 id="pre_fee_cost_display" className="price">

${total_amount}
</h2>

<div>

<div className="render_items">
<ItemsDisplay />
</div>
</div>
</div>
Expand Down
50 changes: 45 additions & 5 deletions src/avSlice.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,59 @@
import { createSlice } from "@reduxjs/toolkit";

// 1. adding objects to provide data structure
// 2. create logic for incrementAvQuantity() and decrementAvQuantity() functions
// 3. export all reducer functions and actions (ln-61 and ln-63)
export const avSlice = createSlice({
name: "av",
initialState: [

{
img: "./imgsFinalPractice/projector.jpg",
name: "Projectors",
cost: 200,
quantity: 0,
},
{
img: "./imgsFinalPractice/speakers.jpg",
name: "Speaker",
cost: 35,
quantity: 0,
},
{
img: "./imgsFinalPractice/microphone.jpg",
name: "Microphones",
cost: 45,
quantity: 0,
},
{
img: "./imgsFinalPractice/whiteboard.png",
name: "Whiteboards",
cost: 80,
quantity: 0,
},
{
img: "./imgsFinalPractice/signpost.jpg",
name: "Signage",
cost: 80,
quantity: 0,
},

],


reducers: {
reducers: { // reducer functions:

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--;
}
},

},
});

Expand Down
10 changes: 8 additions & 2 deletions src/mealsSlice.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
// mealsSlice.js
import { createSlice } from '@reduxjs/toolkit';

// 1. including the meal items inside the initialState array
// 2. adding the logic needed for function reducer toggleMealSelection
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 },
],
// reducer functions:
reducers: {
toggleMealSelection: (state, action) => {
state[action.payload].selected = ! state[action.payload].selected; // uses [action.payload] to identify the item to update
},
},
});
Expand Down
Loading