From fe4f082d8c02ede2f87a391520c0ab4ee73a4cca Mon Sep 17 00:00:00 2001 From: Charith345 <44852950+Charith345@users.noreply.github.com> Date: Sun, 3 Dec 2023 20:40:44 -0800 Subject: [PATCH 1/5] Order-Customization-Admin Completed Finished all necessary components of Order-Customization-Admin side --- .../admin-menu/AddEditMenuItemForm.jsx | 43 +++++ .../admin-menu/MenuCustomization.jsx | 181 ++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 client/src/components/admin-menu/MenuCustomization.jsx diff --git a/client/src/components/admin-menu/AddEditMenuItemForm.jsx b/client/src/components/admin-menu/AddEditMenuItemForm.jsx index 810f3d7..a7bcae6 100644 --- a/client/src/components/admin-menu/AddEditMenuItemForm.jsx +++ b/client/src/components/admin-menu/AddEditMenuItemForm.jsx @@ -2,9 +2,11 @@ import React, { useState, useEffect } from 'react'; import Camera from '../admin-menu/camera-circle.png'; import Trash from '../admin-menu/trash-icon.png'; import Check from '../admin-menu/check-circle.png'; +import MenuCustomization from './MenuCustomization'; const AddEditMenuItemForm = ({ selectedItem, addMenuItem, editMenuItem, deleteMenuItem, setIsOpen }) => { const [itemData, setItemData] = useState(selectedItem || {}); + const [categories, setCategories] = useState([]); const [editMode, setEditMode] = useState({ id: false, image: false, @@ -24,6 +26,7 @@ const AddEditMenuItemForm = ({ selectedItem, addMenuItem, editMenuItem, deleteMe itemPrice: '', itemContent: '', image: '', + categories: [], }); } }, [selectedItem]); @@ -61,10 +64,16 @@ const AddEditMenuItemForm = ({ selectedItem, addMenuItem, editMenuItem, deleteMe itemPrice: '', itemContent: '', image: '', + categories: [], }); } }; + const handleCategoriesUpdate = (updatedCategories) => { + setCategories(updatedCategories); + setItemData({...itemData, categories: updatedCategories}); + } + // const handleImageUpload = (files) => { // const file = files[0]; // if (file) { @@ -189,6 +198,40 @@ const AddEditMenuItemForm = ({ selectedItem, addMenuItem, editMenuItem, deleteMe )} + + {itemData?.categories?.map((category) => ( +
+
{category.name}
+ {category.optionType === 'Single Option Selectable' && ( +
+ {category.options.map((option) => ( +
+ + +
+ ))} +
+ )} + {category.optionType === 'Multiple Options Selectable' && ( +
+ {category.options.map((option) => ( +
+ + +
+ ))} +
+ )} +
+ ))}
diff --git a/client/src/components/admin-menu/MenuCustomization.jsx b/client/src/components/admin-menu/MenuCustomization.jsx new file mode 100644 index 0000000..8f3688e --- /dev/null +++ b/client/src/components/admin-menu/MenuCustomization.jsx @@ -0,0 +1,181 @@ +import React, {useState} from 'react'; + +const MenuCustomization = ({categories, setCategories}) => { + const [customizable, setCustomizable] = useState(false); + const [newCategory, setNewCategory] = useState(''); + const [optionType, setOptionType] = useState(''); + const [newOption, setNewOption] = useState(''); + const [enableOptions, setEnableOptions] = useState(false); + const [trackIndex, setTrackIndex] = useState(null); + + const handleCustomizationChange = () => { + setCustomizable(!customizable); + if (!customizable) { + setOptionType(''); + setNewCategory(''); + setNewOption(''); + } + }; + + const addCategory = () => { + if (newCategory.trim() !== '') { + if (trackIndex != null) { + const updatedCategories = [...categories]; + categories[trackIndex].name = newCategory; + setCategories(updatedCategories); + setTrackIndex(null); + setNewCategory(''); + } + else { + setCategories([...categories, {name: newCategory, options:[], optionType: '' }]); + setNewCategory(''); + setEnableOptions(true); + } + } + }; + + const editCategory = (index) => { + setNewCategory(categories[index].name); + setTrackIndex(index); + } + + const addOption = () => { + if (newOption.trim() !== '') { + const updatedCategories = [...categories]; + const currentCategory = updatedCategories[updatedCategories.length - 1]; + currentCategory.options.push(newOption); + setCategories(updatedCategories); + setNewOption(''); + } + }; + + const handleChangeCategory = (e) => { + setNewCategory(e.target.value); + } + + const changeOptionType = (e) => { + const updatedCategories = [...categories]; + const currentCategory = updatedCategories[updatedCategories.length - 1]; + currentCategory.optionType = e.target.value; + setCategories(updatedCategories) + } + + const handleChangeOption = (e) => { + setNewOption(e.target.value); + } + + return ( +
+
+ Allow Customer Customization? + +
+ {customizable && ( +
+
+ + +
+ {enableOptions && ( +
+ Select selection type: +
+ + +
+
+ + +
+
+ + +
+
+ )} + {/*
+
Categories:
+ {categories.map((category) => ( +
+
{category.name}
+ {category.options.map((option) => ( +
{category.name}:{option}
+ ))} +
+ ))} +
+ {optionType && ( +
+
Selected Option Type:
+
{optionType}
+
+ )}*/} + +
+ )} + {/*
+ {categories.map((category, index) => ( +
+
{category.name}
+ + {category.optionType === 'Single Option Selectable' && ( +
+ {category.options.map((option) => ( +
+ + +
+ ))} +
+ )} + {category.optionType === 'Multiple Options Selectable' && ( +
+ {category.options.map((option) => ( +
+ + +
+ ))} +
+ )} +
+ ))} +
*/} +
+ ); +}; +export default MenuCustomization; \ No newline at end of file From 69cdafdbc846f6efc3a237cb7a868e86ed2243e3 Mon Sep 17 00:00:00 2001 From: Charith345 <44852950+Charith345@users.noreply.github.com> Date: Sun, 3 Dec 2023 21:24:41 -0800 Subject: [PATCH 2/5] Customer-Side Customization implement customization on Customer-side --- client/src/components/itemModal.jsx | 35 +++++++++++++++++++++++++++++ client/src/pages/menu.js | 5 ++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/client/src/components/itemModal.jsx b/client/src/components/itemModal.jsx index 93f15fe..8c9c52c 100644 --- a/client/src/components/itemModal.jsx +++ b/client/src/components/itemModal.jsx @@ -16,6 +16,41 @@ const ItemModal = ({ isOpen, onClose, item }) => {
{item.itemName}
+
+ {item?.categories?.map((category) => ( +
+
{category.name}
+ {category.optionType === 'Single Option Selectable' && ( +
+ {category.options.map((option) => ( +
+ + +
+ ))} +
+ )} + {category.optionType === 'Multiple Options Selectable' && ( +
+ {category.options.map((option) => ( +
+ + +
+ ))} +
+ )} +
+ ))} +
{item.itemFilter.map((filter, index) => (
{filter}
diff --git a/client/src/pages/menu.js b/client/src/pages/menu.js index b362974..4aaf0f9 100644 --- a/client/src/pages/menu.js +++ b/client/src/pages/menu.js @@ -34,6 +34,7 @@ const Menu = (props) => { itemContent: item.description, itemPrice: item.price, itemDiet: item.diet, + itemCustomization: item.customize, }))); } } @@ -102,6 +103,7 @@ const Menu = (props) => { itemPrice={item.itemPrice} itemContent={item.itemContent} itemDiet={item.itemDiet} + itemCustomization = {item.itemCustomization} />
))} @@ -132,13 +134,14 @@ const Menu = (props) => { itemPrice={item.itemPrice} itemContent={item.itemContent} itemDiet={item.itemDiet} + itemCustomization = {item.itemCustomization} />
))}
- + )} From 470ad7021ed52c7ac0243277db230e58520e1771 Mon Sep 17 00:00:00 2001 From: Charith345 <44852950+Charith345@users.noreply.github.com> Date: Mon, 4 Dec 2023 17:29:29 -0800 Subject: [PATCH 3/5] small change visuals --- client/src/components/admin-menu/MenuCustomization.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/src/components/admin-menu/MenuCustomization.jsx b/client/src/components/admin-menu/MenuCustomization.jsx index 8f3688e..8724b09 100644 --- a/client/src/components/admin-menu/MenuCustomization.jsx +++ b/client/src/components/admin-menu/MenuCustomization.jsx @@ -66,6 +66,7 @@ const MenuCustomization = ({categories, setCategories}) => { return (
+ {categories && categories.length === 0 && (
Allow Customer Customization? { onChange={handleCustomizationChange} />
+ )} {customizable && (
From 4ebd9b7047ca8e6fad71252ec0a0a53245ef06d8 Mon Sep 17 00:00:00 2001 From: Jeffuz Date: Tue, 5 Dec 2023 13:01:56 -0800 Subject: [PATCH 4/5] Revert "Merge branch 'main' into Menu_Customization" This reverts commit 5eeaeedfeb59595b7aa5dcffd9a7c1134fc73584, reversing changes made to 470ad7021ed52c7ac0243277db230e58520e1771. --- client/src/WebSocketService.js | 70 +------ .../src/components/admin-menu/MenuManager.jsx | 15 +- client/src/components/itemCard.jsx | 36 +--- client/src/components/itemModal.jsx | 9 +- .../src/components/landing-page/lpNavBar.jsx | 14 +- .../landing-page/lpShoppingCart.jsx | 183 +++++++++++++---- client/src/components/orderManager.jsx | 3 +- client/src/components/shoppingCart.jsx | 13 +- client/src/components/shoppingCartCard.jsx | 34 +-- client/src/pages/admin-orders.js | 80 +------- client/src/pages/customer-menu.js | 30 --- client/src/pages/landing-page.js | 51 ++++- client/src/pages/menu.js | 94 ++++----- server/controllers/menu.js | 15 +- server/server.js | 194 +++--------------- 15 files changed, 323 insertions(+), 518 deletions(-) delete mode 100644 client/src/pages/customer-menu.js diff --git a/client/src/WebSocketService.js b/client/src/WebSocketService.js index b4c2e35..4cb0647 100644 --- a/client/src/WebSocketService.js +++ b/client/src/WebSocketService.js @@ -1,5 +1,4 @@ import { AiOutlineConsoleSql } from "react-icons/ai"; -import { useState } from 'react'; /** * WebSocketService is what the client systems will use to communicate with the server @@ -10,11 +9,6 @@ const WebSocketService = { isMaster: null, // type Bool menu: null, // type json object - waitingOrders: [], - workingOrders: [], - finishedOrders: [], - allOrders: [], - /** * Establishes a WebSocket connection with the server * @param {String} hostname Hostname to use to connect to server. Defaults to '127.0.0.1'. @@ -36,24 +30,12 @@ const WebSocketService = { }); window.dispatchEvent(menuUpdateEvent); } - - function dispatchOrderUpdate(orders) { - const orderUpdateEvent = new CustomEvent('orderUpdate', { - detail: { - waitingOrders: orders.waitingOrders, - workingOrders: orders.workingOrders, - finishedOrders: orders.finishedOrders, - } - }); - window.dispatchEvent(orderUpdateEvent); - } function connectToServer(hostname, port) { return new Promise((resolve, reject) => { const socket = new WebSocket(`ws://${hostname}:${port}`); var id = 'NO_ID'; var menu = {}; - var allOrders = null; socket.addEventListener('open', (e) => { console.log('WebSocket connection is open (connected).'); @@ -73,11 +55,10 @@ const WebSocketService = { console.log('Received INIT from server'); id = payload.ID; menu = payload.menu; - allOrders = payload.allOrders; console.log("Received menu", menu); - resolve([socket, id, menu, allOrders]); + resolve([socket, id, menu.menuList]); return; case 'BROADCAST': @@ -94,7 +75,6 @@ const WebSocketService = { case 'MENU': WebSocketService.menu = payload.menuList; - console.log("RECEIVED MENU:", payload); dispatchMenuUpdate('menuUpdate'); break; @@ -104,22 +84,8 @@ const WebSocketService = { case 'ORDERPLACED': const message = payload.order; - console.log('order:', payload); - console.log(payload.waitingOrders); - allOrders = payload.allOrders; - WebSocketService.waitingOrders = payload.waitingOrders; - WebSocketService.workingOrders = payload.workingOrders; - WebSocketService.finishedOrders = payload.finishedOrders; - console.log("all queues:"); - console.log('Waiting orders:', WebSocketService.waitingOrders); - console.log('Working orders:', WebSocketService.workingOrders); - console.log('FInished orders:', WebSocketService.finishedOrders); - dispatchOrderUpdate(allOrders); - break; - - case 'ALLORDERS': - console.log('ALLORDERS payload:', payload.allOrders); - dispatchOrderUpdate(allOrders); + console.log(message); + alert("received message:", message); break; default: @@ -133,16 +99,13 @@ const WebSocketService = { //this.socket = connectToServer(this.socket, hostname, port); connectToServer(hostname, port) - .then(([socket, id, menu, allOrders]) => { + .then(([socket, id, menu]) => { console.log("PROMISE RESOLVED", socket, id); this.socket = socket; this.id = id; this.menu = menu; - this.allOrders = allOrders; - console.log(menu) if (isMaster){ this.requestMaster(); - dispatchOrderUpdate(this.allOrders); } dispatchMenuUpdate('menuUpdate'); }); @@ -171,6 +134,7 @@ const WebSocketService = { 'order': order, }; + console.log(this.socket); this.socket.send(JSON.stringify(actionObject)); return; }, @@ -184,14 +148,6 @@ const WebSocketService = { return; }, - requestOrders() { - const actionObject = { - 'action': 'REQUESTORDERS' - }; - this.socket.send(JSON.stringify(actionObject)); - return; - }, - /** * Sends a actionObject request to the server * @param {ActionObject} actionObject @@ -203,22 +159,6 @@ const WebSocketService = { this.socket.send(JSON.stringify(actionObject)); }, - workOnItem(item) { - const actionObject = { - action: 'WORKONITEM', - item: item - }; - this.socket.send(JSON.stringify(actionObject)); - }, - - finishItem(item) { - const actionObject = { - action: 'FINISHITEM', - item: item - }; - this.socket.send(JSON.stringify(actionObject)); - }, - addListener(callback) { this.listeners.push(callback); }, diff --git a/client/src/components/admin-menu/MenuManager.jsx b/client/src/components/admin-menu/MenuManager.jsx index 7efac3f..1ce92a1 100644 --- a/client/src/components/admin-menu/MenuManager.jsx +++ b/client/src/components/admin-menu/MenuManager.jsx @@ -37,8 +37,6 @@ const MenuManager = () => { useEffect(() => { // Loads the menu items from the menu stored in WebSocketService.menu - const menuList = WebSocketService.menu; - console.log('menumanager menu:', menuList); setMenuItems(WebSocketService.menu.map(item => ({ id: item.menuId, image: item.image, @@ -51,7 +49,7 @@ const MenuManager = () => { // This code should thoeretically update the menu whenever a event is dispatched // Couldn't figure out how to test it though so it will remain like this for now - const menuUpdateHandler = () => { + const menuUpdateHandler = (event) => { console.log("Menu Update Received!"); const menuList = WebSocketService.menu; console.log("MenuList: ", menuList); @@ -262,7 +260,16 @@ const MenuManager = () => { {menuItems.map((item) => (
openModalEdit(item)}> - +
))}
diff --git a/client/src/components/itemCard.jsx b/client/src/components/itemCard.jsx index c9ab6e5..143e0eb 100644 --- a/client/src/components/itemCard.jsx +++ b/client/src/components/itemCard.jsx @@ -1,6 +1,6 @@ -import React, { useState, useEffect} from 'react'; +import React from 'react'; -/*const ItemCard = ({ image, itemName, itemPrice }) => { +const ItemCard = ({ image, itemName, itemPrice }) => { return (
{itemName} @@ -10,36 +10,6 @@ import React, { useState, useEffect} from 'react';
); -};*/ - -const ItemCard = ({ item, onItemClick }) => { - const [selfItem, setSelfItem] = useState(null); - const id = item.id; - const image = item.image; - const itemName = item.itemName; - const itemPrice = item.itemPrice; - - useEffect(() => { - setSelfItem(item); - }, [item]); - - const handleItemClick = () => { - console.log("itemcard handleItemClick clicked!"); - console.log(selfItem); - if (onItemClick) { - onItemClick(selfItem); - } - }; - - return ( -
- {itemName} -
-
{itemName}
-
${itemPrice}
-
-
- ); -} +}; export default ItemCard; diff --git a/client/src/components/itemModal.jsx b/client/src/components/itemModal.jsx index 7e0d6da..8c9c52c 100644 --- a/client/src/components/itemModal.jsx +++ b/client/src/components/itemModal.jsx @@ -2,14 +2,9 @@ import React from 'react'; import { AiOutlineClose } from 'react-icons/ai' import { FaShoppingCart } from 'react-icons/fa' -const ItemModal = ({ isOpen, onClose, parentCallback, item }) => { +const ItemModal = ({ isOpen, onClose, item }) => { if (!isOpen) return null; - const addToCart = () => { - onClose(); - parentCallback(item); - } - return (
@@ -69,7 +64,7 @@ const ItemModal = ({ isOpen, onClose, parentCallback, item }) => {
{diet}
))}
-
+
  Add to cart
diff --git a/client/src/components/landing-page/lpNavBar.jsx b/client/src/components/landing-page/lpNavBar.jsx index a5fe12e..6ea6bc5 100644 --- a/client/src/components/landing-page/lpNavBar.jsx +++ b/client/src/components/landing-page/lpNavBar.jsx @@ -6,14 +6,15 @@ import { Link } from 'react-router-dom'; import { MdOutlineDashboard } from "react-icons/md"; import LpShoppingCart from './lpShoppingCart'; -const LpNavBar = ({cartItems, cartSize, renderCartSize, removeFromCart, WebSocketService}) => { +const LpNavBar = () => { + /* Testing */ let email = true; // let email = false; let admin = true; // let admin = false; - /*const cartItems = [ + const cartItems = [ { itemImage: 'test/nacho-chips.png', itemName: 'Nacho chips', @@ -92,7 +93,8 @@ const LpNavBar = ({cartItems, cartSize, renderCartSize, removeFromCart, WebSocke itemPrice: 9.99, itemCount: 2 }, - ];*/ + + ]; // Sign In/Up const [selectedLoginItem, setSelectedLoginItem] = useState(null); @@ -115,7 +117,7 @@ const LpNavBar = ({cartItems, cartSize, renderCartSize, removeFromCart, WebSocke }; // Shopping Cart - const itemCount = cartSize; // Item Count Here + const itemCount = 3; // Item Count Here const [selectedCartItem, setSelectedCartItem] = useState(null); const openCartModal = () => { setSelectedCartItem(); @@ -143,7 +145,7 @@ const LpNavBar = ({cartItems, cartSize, renderCartSize, removeFromCart, WebSocke Profile @@ -172,7 +174,7 @@ const LpNavBar = ({cartItems, cartSize, renderCartSize, removeFromCart, WebSocke
- + ) } diff --git a/client/src/components/landing-page/lpShoppingCart.jsx b/client/src/components/landing-page/lpShoppingCart.jsx index 15a6ca5..609f7a2 100644 --- a/client/src/components/landing-page/lpShoppingCart.jsx +++ b/client/src/components/landing-page/lpShoppingCart.jsx @@ -1,39 +1,30 @@ import React, { useState, useEffect } from 'react' import { AiOutlineClose } from 'react-icons/ai' import ShoppingCartCard from '../shoppingCartCard'; +import { FaShoppingCart } from "react-icons/fa"; +import ReactCardFlip from 'react-card-flip' import { BsFillSendFill } from "react-icons/bs"; -const LpShoppingCart = ({ isOpen, onClose, cartItems, cartSize, renderCartSize, removeFromCart, WebSocketService }) => { +const LpShoppingCart = ({ isOpen, onClose, cartItems }) => { const [subTotal, setSubTotal] = useState(0); const [total, setTotal] = useState(0); const [tax, setTax] = useState(0); - - const calculateCosts = () => { - let sum = 0; - cartItems.forEach((cartItem) => { - sum += cartItem[0].itemPrice; - }); + useEffect(() => { + const sum = cartItems.reduce((accu, cartItem) => { + return accu + cartItem.itemPrice * cartItem.itemCount; + }, 0); setSubTotal(sum.toFixed(2)); const calcTax = 0.07 * sum; setTax(calcTax.toFixed(2)); const calcTotal = sum + calcTax; setTotal(calcTotal.toFixed(2)); - } - useEffect(() => { - /*const sum = cartItems.reduce((accu, cartItem) => { - return accu + cartItem[0].itemPrice * cartItem[0].itemCount; - }, 0);*/ - calculateCosts(); + }, [cartItems, total]); - }); - - // Send order to server and wipe cart - const sendOrder = () => { - WebSocketService.submitOrder(cartItems); - removeFromCart(0); - onClose(); + const [isFlipped, setIsFlipped] = useState(false); + function flipCard() { + setIsFlipped(!isFlipped); } if (!isOpen) return null; @@ -41,50 +32,156 @@ const LpShoppingCart = ({ isOpen, onClose, cartItems, cartSize, renderCartSize, return ( <>
- {/* Checkout Side */} -
+ + {/* Shopping Cart Side */} +
- {/*
Check Out
*/}
Shopping Cart
- -
{cartItems.map((cartItem) => ( - + ))}
-
- {/* Payment Amount */} -
-
-
Subtotal:
-
${subTotal}
+ +
+
+ + + {/* Checkout Side */} +
+
+ +
Check Out
+ + +
+
+ {cartItems.map((cartItem) => ( + + ))} +
+ +
+
+ {/* Payment Amount */} +
+
+
Subtotal:
+
${subTotal}
+
+
+
Tax:
+
${tax}
+
+
+
Total:
+
${total}
+
-
-
Total:
-
${total}
+ +
+
+
+ +
+ {/* */} + {/* Shopping Cart Side */} + {/*
+
+ +
Shopping Cart
+
+
+ {cartItems.map((cartItem) => ( + + ))} +
+
+
+ +
+
+
*/} + {/* Checkout Side */} + {/*
+
+ +
Check Out
+
+
+ {cartItems.map((cartItem) => ( + + ))}
+
+
-
-
+
*/} + {/*
*/} + ) } diff --git a/client/src/components/orderManager.jsx b/client/src/components/orderManager.jsx index 38ca30e..7becfd5 100644 --- a/client/src/components/orderManager.jsx +++ b/client/src/components/orderManager.jsx @@ -80,7 +80,7 @@ const initializeColumns = () => { }; }; -const OrderManager = ({pq}) => { +const OrderManager = () => { const [state, setState] = useState({ tasks: initializeTasks(), columns: initializeColumns(), @@ -134,7 +134,6 @@ const OrderManager = ({pq}) => { const onDragEnd = (result) => { console.log('Drag Result:', result); - pq(); const { destination, source } = result; // Check if user tries to drop in an unknown destination diff --git a/client/src/components/shoppingCart.jsx b/client/src/components/shoppingCart.jsx index fd2cf7b..70d6174 100644 --- a/client/src/components/shoppingCart.jsx +++ b/client/src/components/shoppingCart.jsx @@ -44,7 +44,6 @@ const ShoppingCart = ({ orderNum, tableNum, date, cartItems, setCartItems, WebSo setTax(calcTax.toFixed(2)); const calcTotal = sum + calcTax; setTotal(calcTotal.toFixed(2)); - alert('CART ITEMS:', cartItems); }, [cartItems, total]); const changeCounter = (index, newCount) => { @@ -55,6 +54,8 @@ const ShoppingCart = ({ orderNum, tableNum, date, cartItems, setCartItems, WebSo return (
+ + {/* Table and Shopping Cart Div */}
{/* Table Information */} @@ -82,18 +83,18 @@ const ShoppingCart = ({ orderNum, tableNum, date, cartItems, setCartItems, WebSo {/* Payment and Customer Buttons Div */}
{/* Payment Amount */} -
+
Subtotal:
${subTotal}
-
Tax:
-
${tax}
+
Tax:
+
${tax}
-
Total:
-
${total}
+
Total:
+
${total}
diff --git a/client/src/components/shoppingCartCard.jsx b/client/src/components/shoppingCartCard.jsx index 622aab5..7046378 100644 --- a/client/src/components/shoppingCartCard.jsx +++ b/client/src/components/shoppingCartCard.jsx @@ -1,17 +1,21 @@ import React from 'react'; -import { AiOutlineMessage } from 'react-icons/ai' +import { useState } from 'react'; +import { AiOutlinePlusCircle, AiOutlineMinusCircle, AiOutlineMessage } from 'react-icons/ai' +const ShoppingCartCard = ({ itemImage, itemName, itemPrice, itemCounter, ifChangeCounter}) => { + const[counter, setCounter] = useState(itemCounter); -const ShoppingCartCard = ({item, removeFromCart}) => { - const selfItem = item[0]; - const itemImage = selfItem.image; - const itemPrice = selfItem.itemPrice; - const itemName = selfItem.itemName; - const itemHash = item[1]; + const counterIncrement = () => { + setCounter(counter + 1); + ifChangeCounter(counter + 1); + }; - const removeItemFromCart = () => { - removeFromCart(itemHash); - } + const counterDecrement = () => { + if (counter > 1) { + setCounter(counter - 1); + ifChangeCounter(counter - 1); + } + }; return (
@@ -32,14 +36,20 @@ const ShoppingCartCard = ({item, removeFromCart}) => {
+ {/* Item Amount */} +
+ +
{counter}
+ +
{/* Item Remove */}
- +
); -} +}; export default ShoppingCartCard; \ No newline at end of file diff --git a/client/src/pages/admin-orders.js b/client/src/pages/admin-orders.js index b449b6d..ad8e386 100644 --- a/client/src/pages/admin-orders.js +++ b/client/src/pages/admin-orders.js @@ -6,50 +6,6 @@ const Admin_orders = (props) => { const { WebSocketService, setPage } = props; - // waitingOrders formatted as [hash: int, clientId: string, item: object, time: string] - const [waitingOrders, setWaitingOrders] = useState(WebSocketService.waitingOrders); - const [workingOrders, setWorkingOrders] = useState(WebSocketService.workingOrders); - const [finishedOrders, setFinishedOrders] = useState(WebSocketService.finishedOrders); - - const enqueueItem = (item) => { - // Remove item from waiting orders - // Rerender that - - // push item to working orders - // rerender working orders - setWaitingOrders([]); - setWorkingOrders([...workingOrders, item]); - } - - useEffect(() => { - // Function invoked when WebSocketService receives a order update - - const orderUpdateHandler = (orders) => { - console.log('adminOrders.js received order update!'); - console.log('orders:', orders.detail); - setWaitingOrders(orders.detail.waitingOrders); - setWorkingOrders(orders.detail.workingOrders); - setFinishedOrders(orders.detail.finishedOrders); - } - WebSocketService.requestOrders(); - window.addEventListener('orderUpdate', orderUpdateHandler); - }, [WebSocketService, WebSocketService.finishedOrders, WebSocketService.waitingOrders, WebSocketService.workingOrders, waitingOrders]); - - const printQueue = () => { - console.log('printing queue'); - console.log(waitingOrders); - console.log(workingOrders); - console.log(finishedOrders); - } - - const workOnItem = (item) => { - WebSocketService.workOnItem(item); - } - - const finishItem = (item) => { - WebSocketService.finishItem(item); - } - return ( <>
@@ -57,41 +13,7 @@ const Admin_orders = (props) => {
Orders
-
-
- Waiting Order - {waitingOrders.map((waitingOrder) => ( - - ))} -
-
- Working Order - {workingOrders.map((workingOrder) => ( - - ))} -
-
- Finished orders: - {finishedOrders.map((finishedOrder) => ( -
- client: {finishedOrder.orderer}
- Order id: {finishedOrder.hash}
- Order: {finishedOrder.item.id} -
- ))} -
-
- - +
diff --git a/client/src/pages/customer-menu.js b/client/src/pages/customer-menu.js deleted file mode 100644 index 3b16e0c..0000000 --- a/client/src/pages/customer-menu.js +++ /dev/null @@ -1,30 +0,0 @@ -import React, { useEffect } from 'react' -import MenuManager from '../components/admin-menu/MenuManager' -import AdminNavbar from '../components/adminNavbar'; - -import WebSocketService from '../WebSocketService'; - -const Customer_Menu = (props) => { - /*useEffect(() => { - if (!WebSocketService.socket){ - WebSocketService.connect('127.0.0.1', '8080', true) - .then(alert("Connected!")); - } - }, []);*/ - - const { WebSocketService, setPage } = props; - - return( -
-
-
-
{/* Adjust the width as needed */} - -
-
-
- ) - -} - -export default Customer_Menu; \ No newline at end of file diff --git a/client/src/pages/landing-page.js b/client/src/pages/landing-page.js index 1fe2bb9..8830ab7 100644 --- a/client/src/pages/landing-page.js +++ b/client/src/pages/landing-page.js @@ -7,6 +7,55 @@ import LpTestimonial from '../components/landing-page/lpTestimonial'; import { Link } from 'react-router-dom'; const items = [ + { + id: "nacho-chips", + image: "test/nacho-chips.png", + itemName: "Nacho Chips", + itemPrice: 9.99, + }, + { + id: "steak1", + image: "test/steak.png", + itemName: "Steak", + itemPrice: 19.99, + }, + { + id: "nacho-chips", + image: "test/nacho-chips.png", + itemName: "Nacho Chips", + itemPrice: 9.99, + }, + { + id: "steak1", + image: "test/steak.png", + itemName: "Steak", + itemPrice: 19.99, + }, + { + id: "nacho-chips", + image: "test/nacho-chips.png", + itemName: "Nacho Chips", + itemPrice: 9.99, + }, + { + id: "steak1", + image: "test/steak.png", + itemName: "Steak", + itemPrice: 19.99, + }, + { + id: "nacho-chips", + image: "test/nacho-chips.png", + itemName: "Nacho Chips", + itemPrice: 9.99, + }, + { + id: "steak1", + image: "test/steak.png", + itemName: "Steak", + itemPrice: 19.99, + }, + ]; function getItemsToShow() { @@ -44,7 +93,7 @@ const Landing_page = () => { <>
- +
Welcome to 115A's Diner diff --git a/client/src/pages/menu.js b/client/src/pages/menu.js index 5c1f358..4aaf0f9 100644 --- a/client/src/pages/menu.js +++ b/client/src/pages/menu.js @@ -6,18 +6,25 @@ import ShoppingCart from '../components/shoppingCart'; import LpNavBar from '../components/landing-page/lpNavBar'; import WebSocketService from '../WebSocketService'; -const Menu = () => { +const Menu = (props) => { + + + // Testing + // let admin = true; let admin = false; const [items, setItems] = useState([]); // used to save data states const [isLoading, setIsLoading] = useState(true); // used to save whether data is loading + const [menuItems, setMenuItems] = useState([]); + + const menuSet = false; + useEffect(() => { - // Function invoked when WebSocketService receives a menu update + const menuUpdateHandler = () => { console.log("Menu.js update received!"); const menuList = WebSocketService.menu; - console.log('menuList:', menuList); if (menuList) { setItems(menuList.map(item => ({ id: item.menuId, @@ -29,49 +36,39 @@ const Menu = () => { itemDiet: item.diet, itemCustomization: item.customize, }))); - setIsLoading(false); } } - // Connect to server if not already connected if (!WebSocketService.socket) { WebSocketService.connect('127.0.0.1', '8080', false) .then( alert("Connected!"), + setIsLoading(false), ); } window.addEventListener('menuUpdate', menuUpdateHandler); }, []); - const [cartItems, renderCartItems] = useState([]); - const [cartSize, renderCartSize] = useState(0); + const [cartItems, setCartItems] = useState([ + { + index: 0, + itemImage: 'test/nacho-chips.png', + itemName: 'Nacho chips', + itemPrice: 9.99, + itemCount: 1 + }, + { + index: 1, + itemImage: 'test/nacho-chips.png', + itemName: 'Nacho chips', + itemPrice: 9.99, + itemCount: 2 + } + ]); const [selectedItem, setSelectedItem] = useState(null); - const getRandomNumber = () => Math.floor(Math.random() * (9999999999 - 1000000000 + 1) + 1000000000); - - const addItemToCart = (item) => { - const hash = getRandomNumber(); - const updatedCart = [...cartItems, [item, hash]]; - renderCartItems(updatedCart); - renderCartSize(cartSize + 1); - } - - - - const removeItemFromCart = (hash) => { - if (hash === 0){ - closeModal(); - renderCartSize(0); - renderCartItems([]); - }else{ - renderCartSize(cartSize - 1); - const newCartItems = cartItems.filter((cartItem) => cartItem[1] !== hash); - renderCartItems(newCartItems); - } - } - const openModal = (item) => { setSelectedItem(item); }; @@ -80,16 +77,10 @@ const Menu = () => { setSelectedItem(null); }; - // callback listener for itemcard - const handleItemClick = (clickedItem) => { - addItemToCart(clickedItem); - } - // render the pages if the data is loaded if (isLoading) { return
Loading...
; // if data is loading, rending a loading pages } - else { return ( @@ -113,7 +104,6 @@ const Menu = () => { itemContent={item.itemContent} itemDiet={item.itemDiet} itemCustomization = {item.itemCustomization} - onItemClick={openModal} />
))} @@ -121,22 +111,21 @@ const Menu = () => {
- +
) : ( - -
- -
-
Menu
-
-
-
- - {items.map((item) => ( + <> +
+ +
+
Menu
+
+
+
+ {items.map((item) => (
openModal(item)} role="button"> { />
))} - - +
+
+
+
- -
+ )}
); diff --git a/server/controllers/menu.js b/server/controllers/menu.js index 88da795..d1ab591 100644 --- a/server/controllers/menu.js +++ b/server/controllers/menu.js @@ -13,7 +13,7 @@ function getMenus(message) { "Menus not found for restaurantId: " + restaurantId, }); } else { - resolve(restaurant.restaurantMenu.menuList); + resolve({ action: "GETMENUS", menuList: restaurant.restaurantMenu.menuList}); } }) .catch((err) => { @@ -39,7 +39,7 @@ function getMenu(message) { const menuItem = restaurant.restaurantMenu.menuList.find( (menuItem) => menuItem.menuId == menuId ); - resolve(menuItem); + resolve({ action: "GETMENU", menuItem: menuItem }); } }) .catch((err) => { @@ -94,8 +94,8 @@ function createMenu(message) { .save() .then(() => { resolve({ - //menuList: newMenuItem, - menuList: getMenus(), + action: "CREATEMENU", + menuItem: newMenuItem, }); }) .catch((err) => { @@ -152,10 +152,7 @@ function updateMenu(message) { restaurant .save() .then(() => { - getMenus() - .then((menu) => { - resolve({menuList: menu}); - }) + resolve({ action: "UPDATEMENU", menuItem: menuItem }); }) .catch((err) => { reject({ @@ -202,7 +199,7 @@ function deleteMenu(message) { restaurant .save() .then(() => { - resolve({menuList: getMenus()}); + resolve({ action: "DELETEMENU", menuItem: menuItem }); }) .catch((err) => { reject({ diff --git a/server/server.js b/server/server.js index dd3afa0..62d614f 100644 --- a/server/server.js +++ b/server/server.js @@ -42,12 +42,6 @@ class Server { this.clients = []; // array of connected ClientWebSockets this.disconnected = []; // array of disconnected ClientWebSockets this.master = []; // array of ClientWebSocket - - this.orderLog = []; // array of all processed orders with items [client, orderItem, startTime, finishTime] - this.waitingOrders = []; // queue with items [hash, client, orderItem, startTime] - this.workingOrders = []; // array with items [hash, client, orderItem, startTime] - this.finishedOrders = []; // array with items[hash, client, orderItem, startTime, finishTime]; - } /********************************* @@ -133,53 +127,10 @@ class Server { }); break; - case 'REQUESTORDERS': - console.log('Received order queue request'); - this.fulfillRequestOrder(client); - break; - case "ORDER": console.log(`Server received ORDER request`); - let orders = payload.order; - const batch = { - client: client.id, - orders: [] - } - orders.forEach((order) => { - console.log('order:', order); - batch.orders.push({hash: order[1], item: order[0]}); - }); - this.queueOrder(client, batch); - break; - - case 'WORKONITEM': - console.log(`Server received WORKONITEM request`); - // Remove item from waitingOrders - this.waitingOrders = this.waitingOrders.filter(order => order.hash !== payload.item.hash); - // Add item to workingOrders - this.workingOrders.push(payload.item); - console.log('waitingOrders:', this.waitingOrders); - console.log('workingOrders:', this.workingOrders); - // Broadcast changes - this.clients.forEach((client) => { - this.fulfillRequestOrder(client); - }) - /* this.master.forEach((master) => { - this.fulfillRequestOrder(master); - })*/ - this.updateKitchens(); - break; - - case 'FINISHITEM': - console.log(`Server received FINISHITEM`); - // Remove item from workingOrders - this.workingOrders = this.workingOrders.filter(order => order.hash !== payload.item.hash); - // Add item to finishedItems - this.finishedOrders.push(payload.item); - this.clients.forEach((client) => { - this.fulfillRequestOrder(client); - }) - this.updateKitchens(); + let orders = payload.cart; + this.sendOrderToKitchen(client, orders); break; // Restaurant @@ -200,53 +151,39 @@ class Server { case "DELETERESTAURANT": console.log("Received request DELETERESTAURANT"); - // flying a little too close to the sun here no? - //deleteRestaurant(payload); + deleteRestaurant(payload); break; // Menu case "GETMENUS": console.log("Received request GETMENUS"); - this.sendMenu(client); - //this.sendMenu(client); + getMenus(payload); break; case "GETMENU": console.log("Received request GETMENU"); - getMenu(payload) - .then((menu) => { - const actionObject = { - action: 'GETMENU', - menuList: menu, - } - this.sendMenu(client, menu); - }); + getMenu(payload); break; case "CREATEMENU": console.log("Received request CREATEMENU"); - createMenu(payload) - .then((updatedMenu) => { - //console.log('updated menu:', updateMenu); - console.log('updated menu:', updatedMenu); - this.pushMenuUpdate(updatedMenu); - }); + createMenu(payload); break; case "DELETEMENU": console.log("Received request DELETEMENU"); - deleteMenu(payload) - .then((updatedMenu) => { - this.pushMenuUpdate(updatedMenu); - }) + + // // testing fixing by Rixin Li + // console.log("testing delete working?"); + // // checking payload + // console.log(payload); + + deleteMenu(payload); break; case "EDITMENU": console.log("Received request EDITMENU"); - updateMenu(payload) - .then((updatedMenu) => { - this.pushMenuUpdate(updatedMenu); - }); + updateMenu(payload); break; // Table @@ -383,16 +320,12 @@ class Server { * @param {Bool} isMaster Signals if system is master or slave */ sendInit(client, id, isMaster) { + var actionObject; getMenus().then((menu) => { var actionObject = { action: "INIT", ID: id, menu: menu, - allOrders: { - waitingOrders: this.waitingOrders, - workingOrders: this.workingOrders, - finishedOrders: this.finishedOrders, - } }; client.send(JSON.stringify(actionObject)); }); @@ -423,10 +356,13 @@ class Server { * Wrapper function for sendMenu * Pushes a menu update to all clients */ - pushMenuUpdate(menu) { - this.clients.forEach((client) => { - this.sendMenu(client, menu); - }) + pushMenuUpdate() { + getMenus().then((menu) => { + this.clients.forEach((client) => { + client.send(JSON.stringify(menu)); + }); + }); + return; } @@ -435,92 +371,12 @@ class Server { * @param {ClientWebSocket} client * @returns */ - sendMenu(client, menu) { - /*if(!menu){ - getMenus().then((menu) => { - const actionObject = { - action: 'MENU', - menuList: menu, - } - client.send(JSON.stringify(actionObject)); - }); - }else{ - const actionObject = { - action: "MENU", - menuList: menu, - } - client.send(JSON.stringify(actionObject)); - }*/ + sendMenu(client) { getMenus().then((menu) => { - const actionObject = { - action: 'MENU', - menuList: menu, - } - client.send(JSON.stringify(actionObject)); - }) - - return; - } - - /** - * Queues the order and sends to the kitchen - */ - queueOrder(client, batch){ - console.log('Queue order received order', batch, 'for client', client.id); - const now = new Date(); - const hours = now.getHours().toString().padStart(2, '0'); - const minutes = now.getMinutes().toString().padStart(2, '0'); - const seconds = now.getSeconds().toString().padStart(2, '0'); - const day = now.getDate().toString().padStart(2, '0'); - const month = (now.getMonth() + 1).toString().padStart(2, '0'); // Months are zero-based - const year = now.getFullYear(); - const formattedDateTime = `${hours}:${minutes}:${seconds} ${day}/${month}/${year}`; - /*order.forEach((orderItem) => { - console.log('orderItem:', orderItem); - //this.waitingOrders.push([orderItem[0][1], client.id, order[0][0], formattedDateTime]); - })*/ - - // Push items to waitingOrders - batch.orders.forEach((order) => { - order.orderer = batch.client; - order.orderTime = formattedDateTime; - console.log('order:', order); - this.waitingOrders.push(order); - }); - - console.log('waitingOrders:', this.waitingOrders); - - this.updateKitchens(); - } - - /** - * Sends current WaitingOrders to kitchen - */ - updateKitchens(){ - const actionObject = { - action: 'ORDERPLACED', - allOrders: { - waitingOrders: this.waitingOrders, - workingOrders: this.workingOrders, - finishedOrders: this.finishedOrders, - } - } - - this.master.forEach((master) => { - master.send(JSON.stringify(actionObject)); + client.send(JSON.stringify(menu)); }); - } - fulfillRequestOrder(client) { - const actionObject = { - action: 'ALLORDERS', - allOrders: { - waitingOrders: this.waitingOrders, - workingOrders: this.workingOrders, - finishedOrders: this.finishedOrders, - } - } - client.send(JSON.stringify(actionObject)); + return; } } From 9e26bfcf0e6bc7b6ecefef1f126c37fbc9748d36 Mon Sep 17 00:00:00 2001 From: ipsitabisht Date: Mon, 11 Dec 2023 15:25:18 -0800 Subject: [PATCH 5/5] added image upload --- .../admin-menu/AddEditMenuItemForm.jsx | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/client/src/components/admin-menu/AddEditMenuItemForm.jsx b/client/src/components/admin-menu/AddEditMenuItemForm.jsx index a7bcae6..121cd24 100644 --- a/client/src/components/admin-menu/AddEditMenuItemForm.jsx +++ b/client/src/components/admin-menu/AddEditMenuItemForm.jsx @@ -74,40 +74,40 @@ const AddEditMenuItemForm = ({ selectedItem, addMenuItem, editMenuItem, deleteMe setItemData({...itemData, categories: updatedCategories}); } - // const handleImageUpload = (files) => { - // const file = files[0]; - // if (file) { - // const reader = new FileReader(); - // reader.onload = (e) => { - // setItemData({ - // ...itemData, - // image: e.target.result, - // }); - // }; - // reader.readAsDataURL(file); - // } - // }; const handleImageUpload = (files) => { const file = files[0]; if (file) { - const relativePath = `test/${file.name}`; - setItemData({ - ...itemData, - image: relativePath, - - }); - + const reader = new FileReader(); + reader.onload = (e) => { + setItemData({ + ...itemData, + image: e.target.result, + }); + }; + reader.readAsDataURL(file); } }; - const handleImageChange = (e) => { - setItemData({ ...itemData, image: e.target.value }); // update image as a string - }; + // const handleImageUpload = (files) => { + // const file = files[0]; + // if (file) { + // const relativePath = `test/${file.name}`; + // setItemData({ + // ...itemData, + // image: relativePath, + + // }); + + // } + // }; + // const handleImageChange = (e) => { + // setItemData({ ...itemData, image: e.target.value }); // update image as a string + // }; return (
- {/* {itemData.image ? ( + {itemData.image ? (
Selected Image