diff --git a/src/App.js b/src/App.js index b1ac7ec..e62a01b 100644 --- a/src/App.js +++ b/src/App.js @@ -75,10 +75,11 @@ function App() { const handleSetParam = async ({ shopId, tableCode }) => { setShopId(shopId); - if (table.length == 0) { - const gettable = await getTableByCode(tableCode); - if (gettable) setTable(gettable); - } + if (tableCode) + if (table.length == 0) { + const gettable = await getTableByCode(tableCode); + if (gettable) setTable(gettable); + } }; useEffect(() => { @@ -124,7 +125,7 @@ function App() { socket.on("transaction_pending", async (data) => { console.log("transaction notification"); // Call `setModal` with content and parameters - setModal("transaction_pending"); + setModal("transaction_pending", data); }); socket.on("transaction_confirmed", async (data) => { @@ -134,18 +135,23 @@ function App() { socket.on("transaction_success", async (data) => { console.log("transaction notification"); - setModal("transaction_success"); + setModal("transaction_success", data); + }); + + socket.on("payment_claimed", async (data) => { + console.log(data); + setModal("payment_claimed", data); }); socket.on("transaction_failed", async (data) => { console.log("transaction notification"); - setModal("transaction_failed"); + setModal("transaction_failed", data); }); //for clerk socket.on("transaction_created", async (data) => { console.log("transaction notification"); - setModal("new_transaction"); + setModal("new_transaction", data); }); socket.on("checkUserTokenRes", async (data) => { @@ -214,9 +220,6 @@ function App() { // Function to open the modal const setModal = (content, params = {}) => { - setIsModalOpen(true); - setModalContent(content); - // Prepare query parameters const queryParams = new URLSearchParams({ modal: content, @@ -227,6 +230,9 @@ function App() { // Prevent scrolling when modal is open document.body.style.overflow = "hidden"; + + setIsModalOpen(true); + setModalContent(content); }; // Function to close the modal diff --git a/src/components/Modal.js b/src/components/Modal.js index 16617a3..0411edc 100644 --- a/src/components/Modal.js +++ b/src/components/Modal.js @@ -3,11 +3,12 @@ import styles from "./Modal.module.css"; import TablesPage from "./TablesPage.js"; import PaymentOptions from "./PaymentOptions.js"; import TableMaps from "../components/TableMaps"; -import Transactions from "../pages/Transactions"; +import Transaction from "../pages/Transaction"; import Transaction_pending from "../pages/Transaction_pending"; import Transaction_confirmed from "../pages/Transaction_confirmed"; import Transaction_success from "../pages/Transaction_success"; import Transaction_failed from "../pages/Transaction_failed"; +import Payment_claimed from "../pages/Payment_claimed"; import MaterialList from "../pages/MaterialList.js"; import MaterialMutationsPage from "../pages/MaterialMutationsPage.js"; import Reports from "../pages/Reports.js"; @@ -26,7 +27,7 @@ const Modal = ({ shop, isOpen, onClose, modalContent }) => { // Prevent click event from propagating to the overlay event.stopPropagation(); }; - console.log(shop.qrPayment) + console.log(shop.qrPayment); return (
@@ -35,12 +36,15 @@ const Modal = ({ shop, isOpen, onClose, modalContent }) => { {modalContent === "edit_tables" && } {modalContent === "new_transaction" && ( - + )}{" "} {modalContent === "transaction_pending" && } {modalContent === "transaction_confirmed" && ( )} + {modalContent === "payment_claimed" && ( + + )} {modalContent === "transaction_success" && } {modalContent === "transaction_failed" && } {modalContent === "payment_option" && ( @@ -52,9 +56,7 @@ const Modal = ({ shop, isOpen, onClose, modalContent }) => { {modalContent === "update_stock" && ( )} - {modalContent === "reports" && ( - - )} + {modalContent === "reports" && }
); diff --git a/src/helpers/transactionHelpers.js b/src/helpers/transactionHelpers.js index 50d86b9..c88852f 100644 --- a/src/helpers/transactionHelpers.js +++ b/src/helpers/transactionHelpers.js @@ -52,9 +52,35 @@ export async function declineTransaction(transactionId) { export async function handleClaimHasPaid(transactionId) { try { + console.log(transactionId); const token = getLocalStorage("auth"); const response = await fetch( - `${API_BASE_URL}/transaction/payment-claimed/${transactionId}`, + `${API_BASE_URL}/transaction/claim-transaction/${transactionId}`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${token}`, + }, + } + ); + + if (!response.ok) { + return false; + } + + return true; + } catch (error) { + console.error("Error:", error); + } +} + +export async function handleConfirmHasPaid(transactionId) { + try { + console.log(transactionId); + const token = getLocalStorage("auth"); + const response = await fetch( + `${API_BASE_URL}/transaction/confirm-paid/${transactionId}`, { method: "POST", headers: { @@ -318,6 +344,14 @@ export const getFavourite = async (cafeId) => { }; export const getAnalytics = async (cafeId) => { + const response = await fetch( + `${API_BASE_URL}/transaction/get-analytics/${cafeId}`, + getHeaders() + ); + return response.json(); +}; + +export const getIncome = async (cafeId) => { const response = await fetch( `${API_BASE_URL}/transaction/get-income/${cafeId}`, getHeaders() diff --git a/src/pages/Payment_claimed.js b/src/pages/Payment_claimed.js new file mode 100644 index 0000000..0523085 --- /dev/null +++ b/src/pages/Payment_claimed.js @@ -0,0 +1,99 @@ +import React, { useState, useEffect, useRef } from "react"; +import { ColorRing } from "react-loader-spinner"; +import jsQR from "jsqr"; +import QRCode from "qrcode.react"; +import styles from "./Transactions.module.css"; +import { getImageUrl } from "../helpers/itemHelper"; +import { useSearchParams } from "react-router-dom"; +import { + getTransaction, + handleConfirmHasPaid, +} from "../helpers/transactionHelpers"; + +export default function Transaction_pending() { + const [searchParams] = useSearchParams(); + const [transaction, setTransaction] = useState(null); + + useEffect(() => { + const transactionId = searchParams.get("transactionId") || ""; + + const fetchData = async () => { + try { + const fetchedTransaction = await getTransaction(transactionId); + setTransaction(fetchedTransaction); + console.log(transaction); + } catch (error) { + console.error("Error fetching transaction:", error); + } + }; + fetchData(); + }, [searchParams]); + + const calculateTotalPrice = (detailedTransactions) => { + if (!Array.isArray(detailedTransactions)) return 0; + + return detailedTransactions.reduce((total, dt) => { + if ( + dt.Item && + typeof dt.Item.price === "number" && + typeof dt.qty === "number" + ) { + return total + dt.Item.price * dt.qty; + } + return total; + }, 0); + }; + + return ( +
+
+

Payment Claimed

+
+
+ {transaction && ( +
+

+ Transaction ID: {transaction.transactionId} +

+

+ Payment Type: {transaction.payment_type} +

+
    + {transaction.DetailedTransactions.map((detail) => ( +
  • + {detail.Item.name} - {detail.qty} x Rp{" "} + {detail.Item.price} +
  • + ))} +
+

+ {transaction.serving_type === "pickup" + ? "Self pickup" + : `Serve to ${ + transaction.Table ? transaction.Table.tableNo : "N/A" + }`} +

+
+ Total: + + Rp {calculateTotalPrice(transaction.DetailedTransactions)} + +
+
+ +
+ {transaction.confirmed == 0 && ( +
decline
+ )} +
+ )} +
+
+ ); +} diff --git a/src/pages/Reports.js b/src/pages/Reports.js index c5c0a1c..24e6e2d 100644 --- a/src/pages/Reports.js +++ b/src/pages/Reports.js @@ -1,6 +1,10 @@ import React, { useEffect, useState } from "react"; import { ThreeDots } from "react-loader-spinner"; -import { getFavourite, getAnalytics } from "../helpers/transactionHelpers.js"; +import { + getFavourite, + getAnalytics, + getIncome, +} from "../helpers/transactionHelpers.js"; import CircularDiagram from "./CircularDiagram"; import styles from "./Transactions.module.css"; @@ -104,6 +108,7 @@ const App = ({ cafeId }) => { setLoading(true); const items = await getFavourite(cafeId); const analyticsData = await getAnalytics(cafeId); + const incomeData = await getIncome(cafeId); if (items) setFavouriteItems(items); if (analyticsData) setAnalytics(analyticsData); console.log(analyticsData); @@ -250,10 +255,10 @@ const App = ({ cafeId }) => { /> )} setViewStock(!viewStock)} // onClick should be a function + value={viewStock ? "‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ˅" : "‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ˄"} // Corrected ternary operator syntax + onClick={() => setViewStock(!viewStock)} // onClick should be a function /> { + const transactionId = searchParams.get("transactionId") || ""; + + const fetchData = async () => { + try { + const fetchedTransaction = await getTransaction(transactionId); + setTransaction(fetchedTransaction); + console.log(transaction); + } catch (error) { + console.error("Error fetching transaction:", error); + } + }; + fetchData(); + }, [searchParams]); + + useEffect(() => { + const fetchData = async () => { + try { + const fetchedTables = await getTables(shopId || propsShopId); + setTables(fetchedTables); + } catch (error) { + console.error("Error fetching tables:", error); + } + }; + + fetchData(); + }, [shopId || propsShopId]); + + const calculateTotalPrice = (detailedTransactions) => { + return detailedTransactions.reduce((total, dt) => { + return total + dt.qty * dt.Item.price; + }, 0); + }; + + const handleConfirm = async (transactionId) => { + setIsPaymentLoading(true); + try { + const c = await confirmTransaction(transactionId); + // if (c) { + // // Update the confirmed status locally + // setTransactions((prevTransactions) => + // prevTransactions.map((transaction) => + // transaction.transactionId === transactionId + // ? { ...transaction, confirmed: 1 } // Set to confirmed + // : transaction + // ) + // ); + // } + } catch (error) { + console.error("Error processing payment:", error); + } finally { + setIsPaymentLoading(false); + } + }; + + const handleDecline = async (transactionId) => { + setIsPaymentLoading(true); + try { + const c = await declineTransaction(transactionId); + // if (c) { + // // Update the confirmed status locally + // setTransactions((prevTransactions) => + // prevTransactions.map((transaction) => + // transaction.transactionId === transactionId + // ? { ...transaction, confirmed: -1 } // Set to confirmed + // : transaction + // ) + // ); + // } + } catch (error) { + console.error("Error processing payment:", error); + } finally { + setIsPaymentLoading(false); + } + }; + + return ( +
+
+

Transactions

+
+ {/* */} +
+ {transaction && ( +
+ setSelectedTable(transaction.Table || { tableId: 0 }) + } + > +

+ Transaction ID: {transaction.transactionId} +

+

+ Payment Type: {transaction.payment_type} +

+
    + {transaction.DetailedTransactions.map((detail) => ( +
  • + {detail.Item.name} - {detail.qty} x Rp{" "} + {detail.Item.price} +
  • + ))} +
+

+ {transaction.serving_type === "pickup" + ? "Self pickup" + : `Serve to ${ + transaction.Table ? transaction.Table.tableNo : "N/A" + }`} +

+
+ Total: + + Rp {calculateTotalPrice(transaction.DetailedTransactions)} + +
+
+ +
+ {transaction.confirmed == 0 && ( +
handleDecline(transaction.transactionId)} + > + decline +
+ )} +
+ )} +
+
+ ); +} diff --git a/src/pages/Transaction_confirmed.js b/src/pages/Transaction_confirmed.js index 19eab4a..f3d6ede 100644 --- a/src/pages/Transaction_confirmed.js +++ b/src/pages/Transaction_confirmed.js @@ -179,7 +179,10 @@ export default function Transaction_pending({ paymentUrl }) { )} -