This commit is contained in:
everythingonblack
2025-05-20 17:47:43 +07:00
parent b726ae6919
commit df7c4f737c
7 changed files with 119 additions and 81 deletions

View File

@@ -18,7 +18,7 @@ import ButtonWithReplica from "../components/ButtonWithReplica";
dayjs.extend(utc);
dayjs.extend(timezone);
export default function Transactions({ shop, shopId, propsShopId, sendParam, deviceType, paymentUrl }) {
export default function Transactions({ shop, shopId, propsShopId, sendParam, deviceType, paymentUrl, setModal }) {
const { shopIdentifier, tableId } = useParams();
if (sendParam) sendParam({ shopIdentifier, tableId });
@@ -26,13 +26,13 @@ export default function Transactions({ shop, shopId, propsShopId, sendParam, dev
const [isPaymentLoading, setIsPaymentLoading] = useState(false);
const [isPaymentOpen, setIsPaymentOpen] = useState(false);
const [searchTerm, setSearchTerm] = useState('');
const [matchedItems, setMatchedItems] = useState([]);
const [matchedItems, setMatchedItems] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
setMatchedItems(searchAndAggregateItems(transactions, searchTerm));
}, [searchTerm, transactions]);
useEffect(() => {
setMatchedItems(searchAndAggregateItems(transactions, searchTerm));
}, [searchTerm, transactions]);
useEffect(() => {
@@ -40,9 +40,13 @@ useEffect(() => {
try {
setLoading(true);
let response = await getTransactionsFromCafe(shopId || propsShopId, 5, false);
setLoading(false);
if (response) setTransactions(response);
// response = await getMyTransactions(shopId || propsShopId, 5);
// setMyTransactions(response);
} catch (error) {
console.error("Error fetching transactions:", error);
}
@@ -62,38 +66,38 @@ useEffect(() => {
return grandTotal + calculateTotalPrice(transaction.DetailedTransactions);
}, 0);
};
const searchAndAggregateItems = (transactions, searchTerm) => {
if (!searchTerm.trim()) return [];
const searchAndAggregateItems = (transactions, searchTerm) => {
if (!searchTerm.trim()) return [];
const normalizedTerm = searchTerm.trim().toLowerCase();
const aggregatedItems = new Map();
const normalizedTerm = searchTerm.trim().toLowerCase();
const aggregatedItems = new Map();
transactions.forEach(transaction => {
transaction.DetailedTransactions.forEach(detail => {
const itemName = detail.Item.name;
const itemNameLower = itemName.toLowerCase();
transactions.forEach(transaction => {
transaction.DetailedTransactions.forEach(detail => {
const itemName = detail.Item.name;
const itemNameLower = itemName.toLowerCase();
if (itemNameLower.includes(normalizedTerm)) {
const key = detail.itemId;
if (itemNameLower.includes(normalizedTerm)) {
const key = detail.itemId;
if (!aggregatedItems.has(key)) {
aggregatedItems.set(key, {
itemId: detail.itemId,
name: itemName,
totalQty: 0,
totalPrice: 0,
});
if (!aggregatedItems.has(key)) {
aggregatedItems.set(key, {
itemId: detail.itemId,
name: itemName,
totalQty: 0,
totalPrice: 0,
});
}
const current = aggregatedItems.get(key);
current.totalQty += detail.qty;
current.totalPrice += detail.qty * (detail.promoPrice || detail.price);
}
const current = aggregatedItems.get(key);
current.totalQty += detail.qty;
current.totalPrice += detail.qty * (detail.promoPrice || detail.price);
}
});
});
});
return Array.from(aggregatedItems.values());
};
return Array.from(aggregatedItems.values());
};
const handleConfirm = async (transactionId) => {
@@ -103,7 +107,7 @@ const searchAndAggregateItems = (transactions, searchTerm) => {
if (result) {
setTransactions(prev =>
prev.map(t =>
t.transactionId === transactionId ? { ...t, confirmed: 1 } : t
t.transactionId === transactionId ? result : t
)
);
}
@@ -148,35 +152,35 @@ const searchAndAggregateItems = (transactions, searchTerm) => {
</h2>
<input
type="text"
placeholder="Cari nama item..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
style={{ border:'0px',height: '42px',borderRadius: '15px', margin: '7px auto 10px', width: '88%', paddingLeft: '8px' }}
/>
type="text"
placeholder="Cari nama item..."
value={searchTerm}
onChange={(e) => 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) */}
<div className={styles.TransactionListContainer} style={{ padding: '0 8px' }}>
{matchedItems.length > 0 && matchedItems.map(item => (
<div
key={item.itemId}
className={styles.RoundedRectangle}
style={{ overflow: "hidden" }}
>
<ul>
<li>
<strong>{item.name}</strong> x {item.totalQty}
</li>
</ul>
<div className={styles.TotalContainer}>
<span>Total:</span>
<span>Rp {item.totalPrice}</span>
</div>
</div>
))}
{matchedItems.length > 0 && matchedItems.map(item => (
<div
key={item.itemId}
className={styles.RoundedRectangle}
style={{ overflow: "hidden" }}
>
<ul>
<li>
<strong>{item.name}</strong> x {item.totalQty}
</li>
</ul>
<div className={styles.TotalContainer}>
<span>Total:</span>
<span>Rp {item.totalPrice}</span>
</div>
</div>
))}
{transactions &&
transactions.map((transaction) => (
<div
@@ -188,7 +192,7 @@ const searchAndAggregateItems = (transactions, searchTerm) => {
<div className={styles['receipt-header']}>
{transaction.confirmed === 1 ? (
<ColorRing className={styles['receipt-logo']} />
) : transaction.confirmed === -1 || transaction.confirmed === -2 ? (
) : transaction.confirmed === -1 && !transaction.is_paid || transaction.confirmed === -2 && !transaction.is_paid ? (
<div style={{ display: 'flex', justifyContent: 'center', margin: '16px 0px' }}>
<svg
style={{ width: '60px', transform: 'Rotate(45deg)' }}
@@ -205,9 +209,9 @@ const searchAndAggregateItems = (transactions, searchTerm) => {
/>
</svg>
</div>
) : transaction.confirmed === 2 ? (
) : transaction.confirmed === 2 && !transaction.is_paid ? (
<ColorRing className={styles['receipt-logo']} />
) : transaction.confirmed === 3 ? (
) : transaction.confirmed === 3 || transaction.is_paid ? (
<div>
<svg
height="60px"
@@ -242,15 +246,15 @@ const searchAndAggregateItems = (transactions, searchTerm) => {
<div className={styles['receipt-info']}>
{deviceType == 'clerk' ?
<h3>{transaction.confirmed === 1 ? (
<h3>{transaction.confirmed === 1 && !transaction.is_paid ? (
"Silahkan Cek Pembayaran"
) : transaction.confirmed === -1 ? (
) : transaction.confirmed === -1 && !transaction.is_paid ? (
"Dibatalkan Oleh Kasir"
) : transaction.confirmed === -2 ? (
) : transaction.confirmed === -2 && !transaction.is_paid ? (
"Dibatalkan Oleh Pelanggan"
) : transaction.confirmed === 2 ? (
) : transaction.confirmed === 2 && !transaction.is_paid ? (
"Sedang Diproses"
) : transaction.confirmed === 3 ? (
) : transaction.confirmed === 3 || transaction.is_paid ? (
"Transaksi Sukses"
) : (
"Silahkan Cek Ketersediaan"
@@ -299,6 +303,20 @@ const searchAndAggregateItems = (transactions, searchTerm) => {
</li>
))}
</ul>
{!transaction.is_paid && transaction.confirmed > -1 &&
<div
onClick={() => {
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
</div>
}
<h2 className={styles["Transactions-detail"]}>
{transaction.serving_type === "pickup"
? "Self pickup"
@@ -331,7 +349,7 @@ const searchAndAggregateItems = (transactions, searchTerm) => {
</div>
<div className={styles.TotalContainer}>
{(deviceType == 'clerk' && (transaction.confirmed == 0 || transaction.confirmed == 1 || transaction.confirmed == 2)) &&
{(deviceType == 'clerk' && !transaction.is_paid && (transaction.confirmed == 0 || transaction.confirmed == 1 || transaction.confirmed == 2)) &&
<button
className={styles.PayButton}
onClick={() => handleConfirm(transaction.transactionId)}