import React, { useRef, useEffect, useState } from "react"; import styles from "./Invoice.module.css"; import { useParams } from "react-router-dom"; // Changed from useSearchParams to useLocation import { ThreeDots, ColorRing } from "react-loader-spinner"; import ItemLister from "../components/ItemLister"; import { getCartDetails } from "../helpers/itemHelper"; import { getPaymentMethods } from "../helpers/cafeHelpers.js"; import { handlePaymentFromClerk, handlePaymentFromGuestSide, handlePaymentFromGuestDevice, handleExtendFromGuestDevice, handleCloseBillFromGuestDevice } from "../helpers/transactionHelpers"; import { getItemsByCafeId } from "../helpers/cartHelpers.js"; import Dropdown from "./Dropdown.js"; import { useNavigationHelpers } from "../helpers/navigationHelpers"; export default function Invoice({ shopId, setModal, table, sendParam, deviceType, socket, shopItems, setShopItems }) { const { shopIdentifier, tableCode } = useParams(); sendParam({ shopIdentifier, tableCode }); const { goToShop } = useNavigationHelpers(shopIdentifier, table.tableCode); const [cartItems, setCartItems] = useState([]); const [totalPrice, setTotalPrice] = useState(0); const [isPaymentLoading, setIsPaymentLoading] = useState(false); // State for payment button loading animation const textareaRef = useRef(null); const [orderType, setOrderType] = useState("pickup"); const [orderMethod, setOrderMethod] = useState("cash"); const [tableNumber, setTableNumber] = useState(""); const [email, setEmail] = useState(""); const [isLoading, setIsLoading] = useState(true); const [dropdownKey, setDropdownKey] = useState(0); const [paymentMethods, setPaymentMethods] = useState(null); useEffect(() => { const fetchPaymentMethods = async () => { try { const methods = await getPaymentMethods(shopId); console.log(methods) const lastTransaction = JSON.parse(localStorage.getItem('lastTransaction')); if (lastTransaction?.payment_type == 'paylater') methods.isOpenBillAvailable = false; setPaymentMethods(methods) } catch (err) { } }; if (shopId) { fetchPaymentMethods(); } }, [shopId, dropdownKey]); useEffect(() => { const fetchCartItems = async () => { try { const cart = getItemsByCafeId(shopId); const itemMap = new Map(cart.map(item => [item.itemId, item.qty])); // Step 2: Filter and transform shopItems const filteredItems = shopItems .map(itemType => ({ itemTypeId: itemType.itemTypeId, cafeId: itemType.cafeId, typeName: itemType.name, itemList: itemType.itemList .filter(item => itemMap.has(item.itemId)) // Keep only items in getItemsByCafeId .map(item => ({ itemId: item.itemId, price: (item.promoPrice ? item.promoPrice : item.price), name: item.name, image: item.image, qty: itemMap.get(item.itemId), // Add qty from getItemsByCafeId availability: item.availability })) })) .filter(itemType => itemType.itemList.length > 0); // Remove empty itemTypes console.log(filteredItems) // Update local storage by removing unavailable items const updatedLocalStorage = JSON.parse(localStorage.getItem("cart")) || []; const newLocalStorage = updatedLocalStorage.map((cafe) => { if (cafe.cafeId === shopId) { return { ...cafe, items: cafe.items.filter((item) => filteredItems.some((filtered) => filtered.itemList.some( (i) => i.itemId === item.itemId && i.availability ) ) ), }; } return cafe; }); localStorage.setItem("cart", JSON.stringify(newLocalStorage)); window.dispatchEvent(new Event("localStorageUpdated")); // Calculate total price based on filtered cart items const totalPrice = filteredItems.reduce((total, itemType) => { return ( total + itemType.itemList.reduce((subtotal, item) => { return subtotal + item.qty * (item.promoPrice ? item.promoPrice : item.price); }, 0) ); }, 0); setTimeout(function () { setCartItems(filteredItems); setTotalPrice(totalPrice); setIsLoading(false) }, 100); //delay is in milliseconds } catch (error) { console.error("Error fetching cart items:", error); // Handle error if needed } }; fetchCartItems(); const getNewestCartItems = async () => { try { // Fetch items from the cart details (latest state) const items = await getCartDetails(shopId); // Loop through each item type in the items from the cart details items.forEach(itemType => { itemType.itemList.forEach(item => { // Loop through the shopItems and find the corresponding itemId shopItems.forEach(shopItemType => { shopItemType.itemList.forEach(shopItem => { if (shopItem.itemId === item.itemId) { // Update shopItems with the new data from items (e.g., availability, price) shopItem.availability = item.availability; shopItem.price = item.price; // If needed, update other properties like price shopItem.promoPrice = item.promoPrice; } }); }); }); }); // After updating shopItems, set the new state setShopItems(shopItems); // Filter out unavailable items const filteredItems = items .map((itemType) => ({ ...itemType, itemList: itemType.itemList.filter((item) => item.availability), })) .filter((itemType) => itemType.itemList.length > 0); // Remove empty itemTypes setIsLoading(true); setTimeout(function () { setCartItems(filteredItems); setIsLoading(false); }, 100); // delay is in milliseconds // Update local storage by removing unavailable items and updating prices const updatedLocalStorage = JSON.parse(localStorage.getItem("cart")) || []; const newLocalStorage = updatedLocalStorage.map((cafe) => { if (cafe.cafeId === shopId) { return { ...cafe, items: cafe.items.map((item) => { // Find the updated item in filteredItems and set its updated price const updatedItem = filteredItems .flatMap((itemType) => itemType.itemList) .find((filtered) => filtered.itemId === item.itemId); if (updatedItem) { // Update the price in the local storage item return { ...item, price: updatedItem.promoPrice ? updatedItem.promoPrice : updatedItem.price, availability: updatedItem.availability }; } // If no updated item found, return the original item return item; }), }; } return cafe; }); const newLocalStoragee = newLocalStorage.map((cafe) => { if (cafe.cafeId === shopId) { return { ...cafe, items: cafe.items.filter((item) => filteredItems.some((filtered) => filtered.itemList.some( (i) => i.itemId === item.itemId && i.availability ) ) ), }; } return cafe; }); localStorage.setItem("cart", JSON.stringify(newLocalStoragee)); window.dispatchEvent(new Event("localStorageUpdated")); // Calculate total price based on filtered cart items const totalPrice = filteredItems.reduce((total, itemType) => { return ( total + itemType.itemList.reduce((subtotal, item) => { return subtotal + item.qty * (item.promoPrice ? item.promoPrice : item.price); }, 0) ); }, 0); setTotalPrice(totalPrice); } catch (error) { console.error("Error fetching cart items:", error); // Handle error if needed } }; getNewestCartItems(); }, [shopId]); const handlePayCloseBill = async (orderMethod) =>{ setIsPaymentLoading(true); console.log("tipe" + deviceType); if (transactionData) { const socketId = socket.id; const pay = await handleCloseBillFromGuestDevice( transactionData.transactionId, orderMethod, socketId ); } } const handlePay = async (orderMethod) => { setIsPaymentLoading(true); console.log("tipe" + deviceType); if (transactionData) { const socketId = socket.id; const pay = await handleExtendFromGuestDevice( shopId, transactionData.transactionId, textareaRef.current.value, orderMethod, socketId ); localStorage.removeItem('lastTransaction') } else if (deviceType == "clerk") { const pay = await handlePaymentFromClerk( shopId, email, orderMethod, orderType, tableNumber ); } else if (deviceType == "guestSide") { const pay = await handlePaymentFromGuestSide( shopId, email, orderMethod, orderType, tableNumber ); } else if (deviceType == "guestDevice") { const socketId = socket.id; const pay = await handlePaymentFromGuestDevice( shopId, orderMethod, orderType, table.tableNo || tableNumber, textareaRef.current.value, socketId ); } console.log("transaction from " + deviceType + "success"); setIsPaymentLoading(false); }; useEffect(() => { const textarea = textareaRef.current; if (textarea) { const handleResize = () => { textarea.style.height = "auto"; textarea.style.height = `${textarea.scrollHeight}px`; }; handleResize(); // Initial resize textarea.addEventListener("input", handleResize); return () => textarea.removeEventListener("input", handleResize); } }, [textareaRef.current]); useEffect(() => { if (table?.tableId != undefined) setOrderType("serve"); console.log(table); }, [table]); useEffect(() => { console.log(localStorage.getItem('cart')) console.log(cartItems) if (localStorage.getItem('cart') == null || localStorage.getItem('cart') == '' || localStorage.getItem('cart') == '[]') return; // Parse the local storage cart const localStorageCart = JSON.parse(localStorage.getItem('cart')); console.log(localStorageCart) // Create a set of itemIds from the local storage cart for quick lookup const localStorageItemIds = new Set(localStorageCart[0].items.map(item => item.itemId)); // Filter out items from cartItems that do not exist in the local storage cart const updatedCartItems = cartItems.map(itemType => ({ ...itemType, itemList: itemType.itemList.filter(item => localStorageItemIds.has(item.itemId)) })); setCartItems(updatedCartItems); const totalPrice = updatedCartItems.reduce((total, itemType) => { return ( total + itemType.itemList.reduce((subtotal, item) => { return subtotal + item.qty * item.price; }, 0) ); }, 0); setTotalPrice(totalPrice); }, [localStorage.getItem('cart')]); const handleOrderTypeChange = (event) => { setOrderType(event.target.value); }; const handleOrderMethodChange = (event) => { setOrderMethod(event.target.value); }; const handleTableNumberChange = (event) => { setTableNumber(event.target.value); }; const handleEmailChange = (event) => { setEmail(event.target.value); }; const transactionData = JSON.parse(localStorage.getItem('lastTransaction')); return (