ok
This commit is contained in:
@@ -211,6 +211,7 @@ const Child = styled.div`
|
|||||||
const Header = ({
|
const Header = ({
|
||||||
HeaderText,
|
HeaderText,
|
||||||
shopId,
|
shopId,
|
||||||
|
showProfile,
|
||||||
user,
|
user,
|
||||||
isEdit,
|
isEdit,
|
||||||
isLogout,
|
isLogout,
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
Reference in New Issue
Block a user