import React, { useEffect, useState } from "react"; import styles from "./Transactions.module.css"; import { useParams } from "react-router-dom"; import { ColorRing } from "react-loader-spinner"; import { getMyTransactions, confirmTransaction, declineTransaction, getTransactionsFromCafe, } from "../helpers/transactionHelpers"; import dayjs from "dayjs"; import utc from "dayjs/plugin/utc"; import timezone from "dayjs/plugin/timezone"; import { ThreeDots } from "react-loader-spinner"; import ButtonWithReplica from "../components/ButtonWithReplica"; dayjs.extend(utc); dayjs.extend(timezone); export default function Transactions({ shop, shopId, propsShopId, sendParam, deviceType, paymentUrl, setModal, newTransaction }) { const { shopIdentifier, tableId } = useParams(); if (sendParam) sendParam({ shopIdentifier, tableId }); const [transactions, setTransactions] = useState([]); const [isPaymentLoading, setIsPaymentLoading] = useState(false); const [isPaymentOpen, setIsPaymentOpen] = useState(false); const [searchTerm, setSearchTerm] = useState(''); const [matchedItems, setMatchedItems] = useState([]); const [loading, setLoading] = useState(false); useEffect(() => { setMatchedItems(searchAndAggregateItems(transactions, searchTerm)); }, [searchTerm, transactions]); useEffect(() => { const fetchTransactions = async () => { try { // response = await getMyTransactions(shopId || propsShopId, 5); // setMyTransactions(response); setLoading(true); let response = await getTransactionsFromCafe(shopId || propsShopId, -1, false); setLoading(false); if (response) setTransactions(response); } catch (error) { console.error("Error fetching transactions:", error); } }; console.log(deviceType) fetchTransactions(); }, [deviceType, newTransaction]); const calculateTotalPrice = (detailedTransactions) => { return detailedTransactions.reduce((total, dt) => { return total + dt.qty * (dt.promoPrice ? dt.promoPrice : dt.price); }, 0); }; const calculateAllTransactionsTotal = (transactions) => { return transactions .filter(transaction => transaction.confirmed > 1) // Filter transactions where confirmed > 1 .reduce((grandTotal, transaction) => { return grandTotal + calculateTotalPrice(transaction.DetailedTransactions); }, 0); }; const searchAndAggregateItems = (transactions, searchTerm) => { if (!searchTerm.trim()) return []; const normalizedTerm = searchTerm.trim().toLowerCase(); // Map with key = `${itemId}-${confirmedGroup}` to keep confirmed groups separate const aggregatedItems = new Map(); transactions.forEach(transaction => { // Determine confirmed group as a string key const confirmedGroup = transaction.confirmed >= 0 && transaction.confirmed > 1 ? 'confirmed_gt_1' : 'confirmed_le_1'; transaction.DetailedTransactions.forEach(detail => { const itemName = detail.Item.name; const itemNameLower = itemName.toLowerCase(); if (itemNameLower.includes(normalizedTerm)) { // Combine itemId and confirmedGroup to keep them separated const key = `${detail.itemId}-${confirmedGroup}`; if (!aggregatedItems.has(key)) { aggregatedItems.set(key, { itemId: detail.itemId, name: itemName, totalQty: 0, totalPrice: 0, confirmedGroup, // Keep track of which group this belongs to }); } const current = aggregatedItems.get(key); current.totalQty += detail.qty; current.totalPrice += detail.qty * (detail.promoPrice || detail.price); } }); }); console.log(aggregatedItems.values()) return Array.from(aggregatedItems.values()); }; const handleConfirm = async (transactionId) => { setIsPaymentLoading(true); try { const result = await confirmTransaction(transactionId); if (result) { setTransactions(prev => prev.map(t => t.transactionId === transactionId ? result : t ) ); } } catch (error) { console.error("Error processing payment:", error); } finally { setIsPaymentLoading(false); } }; const handleDecline = async (transactionId) => { setIsPaymentLoading(true); try { const result = await declineTransaction(transactionId); if (result) { setTransactions(prev => prev.map(t => t.transactionId === transactionId ? result : t ) ); } } catch (error) { console.error("Error processing payment:", error); } finally { setIsPaymentLoading(false); } }; if (loading) return (

); return (

Transaksi selesai Rp {calculateAllTransactionsTotal(transactions)}

setSearchTerm(e.target.value)} style={{ border: '0px', height: '42px', borderRadius: '15px', margin: '7px auto 10px', width: '88%', paddingLeft: '8px' }} /> {/* Existing Transactions List (keep all your JSX below unchanged) */}
{matchedItems.length > 0 && matchedItems.map(item => (
  • {item.name} x {item.totalQty}
Total: Rp {item.totalPrice}
))} {transactions && transactions.map((transaction) => (
{transaction.confirmed === 1 ? ( ) : transaction.confirmed === -1 && !transaction.is_paid || transaction.confirmed === -2 && !transaction.is_paid ? (
) : transaction.confirmed === 2 && !transaction.is_paid ? ( ) : transaction.confirmed === 3 || transaction.is_paid ? (
) : ( )}
{deviceType == 'clerk' ?

{transaction.confirmed === 1 && !transaction.is_paid ? ( "Silahkan Cek Pembayaran" ) : transaction.confirmed === -1 && !transaction.is_paid ? ( "Dibatalkan Oleh Kasir" ) : transaction.confirmed === -2 && !transaction.is_paid ? ( "Dibatalkan Oleh Pelanggan" ) : transaction.confirmed === 2 && !transaction.is_paid ? ( "Sedang Diproses" ) : transaction.confirmed === 3 || transaction.is_paid ? ( "Transaksi Sukses" ) : ( "Silahkan Cek Ketersediaan" )}

:

{transaction.confirmed === 1 ? ( (transaction.payment_type == 'cash' ? 'Silahkan Bayar Ke Kasir' : "Silahkan Bayar Dengan QRIS") ) : transaction.confirmed === -1 ? ( "Dibatalkan Oleh Kasir" ) : transaction.confirmed === -2 ? ( "Dibatalkan Oleh Pelanggan" ) : transaction.confirmed === 2 ? ( "Sedang diproses" ) : transaction.confirmed === 3 ? ( "Transaksi Sukses" ) : ( "Memeriksa Ketersediaan " )}

}

Transaction ID: {transaction.transactionId}

Payment Type: {transaction.payment_type}

{dayjs.utc(transaction.createdAt).tz(shop.timezone).format('YYYY-MM-DD HH:mm:ss')}

{transaction.paymentClaimed && transaction.confirmed < 2 && (

payment claimed

)}
    {transaction.DetailedTransactions.map((detail) => (
  • {detail.Item.name} - {detail.qty < 1 ? 'tidak tersedia' : `${detail.qty} x Rp ${detail.promoPrice ? detail.promoPrice : detail.price}`}
  • ))}
{!transaction.is_paid && transaction.confirmed > -1 &&
{ localStorage.setItem('lastTransaction', JSON.stringify(transaction)); setModal("message", { captMessage: 'Silahkan tambahkan pesanan', descMessage: 'Pembayaran akan ditambahkan ke transaksi sebelumnya.' }, null, null); // Dispatch the custom event window.dispatchEvent(new Event("localStorageUpdated")); }} className={styles["addNewItem"]} > Tambah pesanan
}

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

{transaction.notes && ( <>
Note :