From 198d0b3053ed08b87c262e69a72bedc72f40ff81 Mon Sep 17 00:00:00 2001 From: zadit <75159257+insvrgent@users.noreply.github.com> Date: Wed, 4 Dec 2024 21:40:36 +0700 Subject: [PATCH] ok --- src/App.js | 137 ++++++++++++++---- src/components/Modal.js | 18 ++- src/components/Modal.module.css | 4 +- src/helpers/transactionHelpers.js | 4 +- src/pages/Transaction.js | 83 ++++++++--- src/pages/Transaction_confirmed.js | 24 +++- src/pages/Transaction_pending.js | 222 +++++++++++++++++++++++++---- src/pages/Transactions.js | 2 +- src/pages/Transactions.module.css | 132 ++++++++++++++--- 9 files changed, 517 insertions(+), 109 deletions(-) diff --git a/src/App.js b/src/App.js index 9e0e3ed..828008a 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useRef } from "react"; import "./App.css"; import "./components/Loading.css"; import { @@ -26,6 +26,9 @@ import GuestSide from "./pages/GuestSide"; import { getItemTypesWithItems } from "./helpers/itemHelper.js"; import { getTableByCode } from "./helpers/tableHelper.js"; +import { + getTransactionsFromCafe, +} from "./helpers/transactionHelpers"; import { getConnectedGuestSides, getClerks, @@ -57,8 +60,21 @@ function App() { const [shopItems, setShopItems] = useState([]); const [isModalOpen, setIsModalOpen] = useState(false); const [modalContent, setModalContent] = useState(null); + const transactionList = useRef(null); const [queue, setQueue] = useState([]); + + const validTransactionStates = [ + 'new_transaction', + 'transaction_canceled', + 'transaction_pending', + 'transaction_confirmed', + 'payment_claimed', + 'transaction_success', + 'transaction_end', + 'transaction_failed', + ]; + useEffect(() => { const calculateTotalsFromLocalStorage = () => { const { totalCount } = calculateTotals(shopId); @@ -193,30 +209,16 @@ function App() { setModal("transaction_canceled", data); }); - //for clerk - socket.on("transaction_created", async (data) => { - console.log("transaction notification"); - setModal("new_transaction", data); - - let permission = Notification.permission; - if (permission != "granted") return; - navigator.serviceWorker.ready.then((registration) => { - registration.showNotification("New Transaction", { - body: `A new transaction was created: ${data.transactionDetails}`, // Customize as needed - icon: "icon.png", // Optional icon - }); - }); - }); const checkNotifications = () => { let permission = Notification.permission; - + // Check current permission if (permission !== "granted") { setModal("req_notification"); } }; - + socket.on("checkUserTokenRes", async (data) => { if (data.status !== 200) { removeLocalStorage("auth"); @@ -266,15 +268,85 @@ function App() { }); socket.on("updateQueue", (response) => { - setQueue(response); // Only set the queue if it's a valid non-empty array - console.log("Updated Queue:", response); // Log the valid queue - + setQueue(response); // Only set the queue if it's a valid non-empty array + console.log("Updated Queue:", response); // Log the valid queue + }); return () => { socket.off("signout-guest-session"); }; }, [socket, shopId]); + useEffect(() => { + // This will ensure that searchParams and transaction_info get updated on each render + socket.on("transaction_created", async (data) => { + console.log("transaction notification"); + console.log(modalContent); + + let response; + response = await getTransactionsFromCafe(shopId, 0, true); + console.log(data); + transactionList.current = response; + + // Get current URL's search parameters inside the socket event handler + const searchParams = new URLSearchParams(location.search); + let transaction_info = searchParams.get("transactionId") || ''; // Get transactionId or set it to empty string + console.log(transaction_info); // Log the updated transaction_info + + // If transaction_info is an empty string, set the modal + if (transaction_info === '') { + setModal("new_transaction", data); + } + + // Show browser notification + let permission = Notification.permission; + if (permission !== "granted") return; + navigator.serviceWorker.ready.then((registration) => { + registration.showNotification("New Transaction", { + body: `A new transaction was created: ${data.transactionDetails}`, + icon: "icon.png", // Optional icon + }); + }); + }); + + // Clean up the socket event listener on unmount or when dependencies change + return () => { + socket.off("transaction_created"); + }; + }, [socket, shopId, location]); // Ensure location is in the dependencies to respond to changes in the URL + + function handleMoveToTransaction(direction, from) { + console.log(direction); + console.log(from); + + // Find the current index based on the 'from' transactionId + const currentIndex = transactionList.current.findIndex(item => item.transactionId == from); + + // Determine the new transactionId based on the direction + let newTransactionId; + if (direction === 'next') { + // If we're not at the last transaction, get the next transactionId + newTransactionId = currentIndex < transactionList.current.length - 1 + ? transactionList.current[currentIndex + 1].transactionId + : from; // If already at the end, stay on the current transactionId + } else if (direction === 'previous') { + // If we're not at the first transaction, get the previous transactionId + newTransactionId = currentIndex > 0 + ? transactionList.current[currentIndex - 1].transactionId + : from; // If already at the beginning, stay on the current transactionId + } + + // Log the new transactionId + console.log('New Transaction ID:', newTransactionId); + + // Update the URL with the new transactionId using navigate + navigate(`?transactionId=${newTransactionId}`, { replace: true }); + + // Optionally, update state or perform further actions based on the new transactionId + // Example: + // setModalContent({ cafeId: shopId, transactionId: newTransactionId }); + } + const handleModalFromURL = () => { const queryParams = new URLSearchParams(location.search); @@ -307,7 +379,7 @@ function App() { document.body.style.overflow = "hidden"; setIsModalOpen(true); - setModalContent(content); + setModalContent(content) }; // Function to close the modal @@ -318,6 +390,7 @@ function App() { closeTheseContent.includes(modalContent)) ) { setIsModalOpen(false); + setModalContent(null); document.body.style.overflow = "auto"; const queryParams = new URLSearchParams(location.search); @@ -334,15 +407,15 @@ function App() { // useEffect(() => { // const askNotificationPermission = async () => { // let permission = Notification.permission; - + // // Check current permission // if (permission === "default") { // setModal("req_notification"); - + // // Request permission and wait for the result // permission = await Notification.requestPermission(); // } - + // // Handle permission results // if (permission === "granted") { // await resetNotificationSubscription(); @@ -352,22 +425,22 @@ function App() { // console.error("Notification permission denied."); // } // }; - + // const handleTransactionConfirmed = async (data) => { // console.log("transaction notification", data); // await askNotificationPermission(); // setModal("transaction_success", data); // }; - + // // Add socket listener for transaction confirmations // socket.on("transaction_success", handleTransactionConfirmed); - + // // Cleanup the socket listener on component unmount // return () => { // socket.off("transaction_success", handleTransactionConfirmed); // }; // }, [user]); - + useEffect(() => { const startPermissionPolling = async () => { const checkInterval = 5000; // Check every 5 seconds @@ -386,7 +459,7 @@ function App() { startPermissionPolling(); }, []); - + useEffect(() => { if ("serviceWorker" in navigator) { navigator.serviceWorker.register("/service-worker.js") @@ -398,7 +471,7 @@ function App() { }); } }, []); - + return (