This commit is contained in:
nospeedlimitindonesia
2024-07-27 20:10:18 +00:00
parent d31196d378
commit ae79c9fc5a
3 changed files with 62 additions and 41 deletions

View File

@@ -211,6 +211,7 @@ const Child = styled.div`
const Header = ({ const Header = ({
HeaderText, HeaderText,
shopId, shopId,
showProfile,
user, user,
isEdit, isEdit,
isLogout, isLogout,

View File

@@ -82,6 +82,7 @@ function CafePage({
<body className="App-header"> <body className="App-header">
<Header <Header
HeaderText={"Menu"} HeaderText={"Menu"}
showProfile={true}
isEdit={() => setIsModalOpen(true)} isEdit={() => setIsModalOpen(true)}
isLogout={handleLogout} isLogout={handleLogout}
shopId={shopId} shopId={shopId}

View File

@@ -1,13 +1,13 @@
import React, { useRef, useEffect, useState } from 'react'; import React, { useRef, useEffect, useState } from "react";
import styles from './Cart.module.css'; import styles from "./Cart.module.css";
import ItemLister from '../components/ItemLister'; import ItemLister from "../components/ItemLister";
import { ThreeDots, ColorRing } from 'react-loader-spinner'; import { ThreeDots, ColorRing } from "react-loader-spinner";
import { useParams } from 'react-router-dom'; import { useParams } from "react-router-dom";
import { useNavigationHelpers } from '../helpers/navigationHelpers'; import { useNavigationHelpers } from "../helpers/navigationHelpers";
import { getTable } from '../helpers/tableHelper.js'; import { getTable } from "../helpers/tableHelper.js";
import { getCartDetails } from '../helpers/itemHelper.js'; import { getCartDetails } from "../helpers/itemHelper.js";
import { getItemsByCafeId } from '../helpers/cartHelpers'; // Import getItemsByCafeId import { getItemsByCafeId } from "../helpers/cartHelpers"; // Import getItemsByCafeId
import Modal from '../components/Modal'; // Import the reusable Modal component import Modal from "../components/Modal"; // Import the reusable Modal component
export default function Cart({ sendParam, totalItemsCount }) { export default function Cart({ sendParam, totalItemsCount }) {
const { shopId } = useParams(); const { shopId } = useParams();
@@ -16,13 +16,13 @@ export default function Cart({ sendParam, totalItemsCount }) {
const { goToShop, goToInvoice } = useNavigationHelpers(shopId); const { goToShop, goToInvoice } = useNavigationHelpers(shopId);
const [cartItems, setCartItems] = useState([]); const [cartItems, setCartItems] = useState([]);
const [totalPrice, setTotalPrice] = useState(0); const [totalPrice, setTotalPrice] = useState(0);
const [orderType, setOrderType] = useState('pickup'); const [orderType, setOrderType] = useState("pickup");
const [tableNumber, setTableNumber] = useState(''); const [tableNumber, setTableNumber] = useState("");
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
const [modalContent, setModalContent] = useState(null); const [modalContent, setModalContent] = useState(null);
const [isCheckoutLoading, setIsCheckoutLoading] = useState(false); // State for checkout button loading animation const [isCheckoutLoading, setIsCheckoutLoading] = useState(false); // State for checkout button loading animation
const [email, setEmail] = useState(''); const [email, setEmail] = useState("");
const textareaRef = useRef(null); const textareaRef = useRef(null);
@@ -36,13 +36,16 @@ export default function Cart({ sendParam, totalItemsCount }) {
if (items) setCartItems(items); if (items) setCartItems(items);
const initialTotalPrice = items.reduce((total, itemType) => { const initialTotalPrice = items.reduce((total, itemType) => {
return total + itemType.itemList.reduce((subtotal, item) => { return (
return subtotal + (item.qty * item.price); total +
}, 0); itemType.itemList.reduce((subtotal, item) => {
return subtotal + item.qty * item.price;
}, 0)
);
}, 0); }, 0);
setTotalPrice(initialTotalPrice); setTotalPrice(initialTotalPrice);
} catch (error) { } catch (error) {
console.error('Error fetching cart items:', error); console.error("Error fetching cart items:", error);
} }
}; };
@@ -51,12 +54,12 @@ export default function Cart({ sendParam, totalItemsCount }) {
const textarea = textareaRef.current; const textarea = textareaRef.current;
if (textarea) { if (textarea) {
const handleResize = () => { const handleResize = () => {
textarea.style.height = 'auto'; textarea.style.height = "auto";
textarea.style.height = `${textarea.scrollHeight}px`; textarea.style.height = `${textarea.scrollHeight}px`;
}; };
textarea.addEventListener('input', handleResize); textarea.addEventListener("input", handleResize);
handleResize(); handleResize();
return () => textarea.removeEventListener('input', handleResize); return () => textarea.removeEventListener("input", handleResize);
} }
}, [shopId]); }, [shopId]);
@@ -64,20 +67,22 @@ export default function Cart({ sendParam, totalItemsCount }) {
try { try {
const items = await getItemsByCafeId(shopId); const items = await getItemsByCafeId(shopId);
const updatedTotalPrice = items.reduce((total, localItem) => { const updatedTotalPrice = items.reduce((total, localItem) => {
const cartItem = cartItems.find(itemType => const cartItem = cartItems.find((itemType) =>
itemType.itemList.some(item => item.itemId === localItem.itemId) itemType.itemList.some((item) => item.itemId === localItem.itemId),
); );
if (cartItem) { if (cartItem) {
const itemDetails = cartItem.itemList.find(item => item.itemId === localItem.itemId); const itemDetails = cartItem.itemList.find(
return total + (localItem.qty * itemDetails.price); (item) => item.itemId === localItem.itemId,
);
return total + localItem.qty * itemDetails.price;
} }
return total; return total;
}, 0); }, 0);
setTotalPrice(updatedTotalPrice); setTotalPrice(updatedTotalPrice);
} catch (error) { } catch (error) {
console.error('Error refreshing total price:', error); console.error("Error refreshing total price:", error);
} }
}; };
@@ -96,28 +101,30 @@ export default function Cart({ sendParam, totalItemsCount }) {
const handlCloseModal = () => { const handlCloseModal = () => {
setIsModalOpen(false); setIsModalOpen(false);
setIsCheckoutLoading(false); setIsCheckoutLoading(false);
} };
const isValidEmail = (email) => { const isValidEmail = (email) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email); return emailRegex.test(email);
} };
const handleCheckout = async () => { const handleCheckout = async () => {
setIsCheckoutLoading(true); // Start loading animation setIsCheckoutLoading(true); // Start loading animation
if (email != '' && !isValidEmail(email)) { if (email != "" && !isValidEmail(email)) {
setModalContent(<div>Please enter a valid email address.</div>); setModalContent(<div>Please enter a valid email address.</div>);
setIsModalOpen(true); setIsModalOpen(true);
setIsCheckoutLoading(false); // Stop loading animation setIsCheckoutLoading(false); // Stop loading animation
return; return;
} }
if (orderType === 'serve') { if (orderType === "serve") {
if (tableNumber !== '') { if (tableNumber !== "") {
const table = await getTable(shopId, tableNumber); const table = await getTable(shopId, tableNumber);
if (!table) { if (!table) {
setModalContent(<div>Table not found. Please enter a valid table number.</div>); setModalContent(
<div>Table not found. Please enter a valid table number.</div>,
);
setIsModalOpen(true); setIsModalOpen(true);
} else { } else {
goToInvoice(orderType, tableNumber, email); goToInvoice(orderType, tableNumber, email);
@@ -135,8 +142,8 @@ export default function Cart({ sendParam, totalItemsCount }) {
if (loading) if (loading)
return ( return (
<div className='Loader'> <div className="Loader">
<div className='LoaderChild'> <div className="LoaderChild">
<ThreeDots /> <ThreeDots />
</div> </div>
</div> </div>
@@ -144,10 +151,12 @@ export default function Cart({ sendParam, totalItemsCount }) {
else else
return ( return (
<div className={styles.Cart}> <div className={styles.Cart}>
<div style={{ marginTop: '30px' }}></div> <div style={{ marginTop: "30px" }}></div>
<h2 className={styles['Cart-title']}>{totalItemsCount} {totalItemsCount !== 1 ? 'items' : 'item'} in Cart</h2> <h2 className={styles["Cart-title"]}>
<div style={{ marginTop: '-45px' }}></div> {totalItemsCount} {totalItemsCount !== 1 ? "items" : "item"} in Cart
{cartItems.map(itemType => ( </h2>
<div style={{ marginTop: "-45px" }}></div>
{cartItems.map((itemType) => (
<ItemLister <ItemLister
key={itemType.itemTypeId} key={itemType.itemTypeId}
refreshTotal={refreshTotal} refreshTotal={refreshTotal}
@@ -170,11 +179,15 @@ export default function Cart({ sendParam, totalItemsCount }) {
</div> </div>
<div className={styles.OrderTypeContainer}> <div className={styles.OrderTypeContainer}>
<span htmlFor="orderType">Order Type:</span> <span htmlFor="orderType">Order Type:</span>
<select id="orderType" value={orderType} onChange={handleOrderTypeChange}> <select
id="orderType"
value={orderType}
onChange={handleOrderTypeChange}
>
<option value="pickup">Pickup</option> <option value="pickup">Pickup</option>
<option value="serve">Serve</option> <option value="serve">Serve</option>
</select> </select>
{orderType === 'serve' && ( {orderType === "serve" && (
<input <input
type="text" type="text"
placeholder="Table Number" placeholder="Table Number"
@@ -201,9 +214,15 @@ export default function Cart({ sendParam, totalItemsCount }) {
<span>Rp {totalPrice}</span> <span>Rp {totalPrice}</span>
</div> </div>
<button onClick={handleCheckout} className={styles.CheckoutButton}> <button onClick={handleCheckout} className={styles.CheckoutButton}>
{isCheckoutLoading ? <ColorRing height="50" width="50" color="white" /> : 'Checkout'} {isCheckoutLoading ? (
<ColorRing height="50" width="50" color="white" />
) : (
"Checkout"
)}
</button> </button>
<div onClick={goToShop} className={styles.BackToMenu}>Back to menu</div> <div onClick={goToShop} className={styles.BackToMenu}>
Back to menu
</div>
<Modal isOpen={isModalOpen} onClose={() => handlCloseModal()}> <Modal isOpen={isModalOpen} onClose={() => handlCloseModal()}>
{modalContent} {modalContent}