diff --git a/src/pages/Transactions.js b/src/pages/Transactions.js index 91f8ed1..7ee4f77 100644 --- a/src/pages/Transactions.js +++ b/src/pages/Transactions.js @@ -30,6 +30,15 @@ export default function Transactions({ shop, shopId, propsShopId, sendParam, dev const [loading, setLoading] = useState(false); + // Currency formatter (thousand separators, with Rp prefix) + const formatRp = (value) => `Rp ${new Intl.NumberFormat('id-ID').format(Math.round(Number(value || 0)))}`; + + const getStatusClass = (t) => { + if (t.confirmed === 3 || t.is_paid) return styles.statusSuccess; + if (t.confirmed === -1 || t.confirmed === -2) return styles.statusCancelled; + return styles.statusNeutral; + }; + useEffect(() => { setMatchedItems(searchAndAggregateItems(transactions, searchTerm)); }, [searchTerm, transactions]); @@ -154,7 +163,7 @@ console.log(aggregatedItems.values()) return (

- Transaksi selesai Rp {calculateAllTransactionsTotal(transactions)} + Transaksi selesai {formatRp(calculateAllTransactionsTotal(transactions))}

setSearchTerm(e.target.value)} - style={{ border: '0px', height: '42px', borderRadius: '15px', margin: '7px auto 10px', width: '88%', paddingLeft: '8px' }} + style={{ border: '0px', height: '36px', borderRadius: '12px', margin: '6px auto 10px', width: '88%', padding: '0 8px', fontSize: '14px' }} /> {/* Existing Transactions List (keep all your JSX below unchanged) */} -
+
{matchedItems.length > 0 && matchedItems.map(item => (
Total: - Rp {item.totalPrice} + {formatRp(item.totalPrice)}
))} @@ -191,94 +200,60 @@ console.log(aggregatedItems.values()) transactions.map((transaction) => (
{transaction.confirmed === 1 ? ( - ) : transaction.confirmed === -1 && !transaction.is_paid || transaction.confirmed === -2 && !transaction.is_paid ? ( -
- - + ) : (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 " - )}

} + {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}

@@ -304,12 +279,11 @@ console.log(aggregatedItems.values())
    {transaction.DetailedTransactions.map((detail) => (
  • - {detail.Item.name} - {detail.qty < 1 ? 'tidak tersedia' : `${detail.qty} x Rp - ${detail.promoPrice ? detail.promoPrice : detail.price}`} + {detail.Item.name} - {detail.qty < 1 ? 'tidak tersedia' : `${detail.qty} x ${formatRp(detail.promoPrice ? detail.promoPrice : detail.price)}`}
  • ))}
- {!transaction.is_paid && transaction.confirmed > -1 && + {!transaction.is_paid && transaction.confirmed > -1 && (
{ localStorage.setItem('lastTransaction', JSON.stringify(transaction)); @@ -322,12 +296,11 @@ console.log(aggregatedItems.values()) > Tambah pesanan
- } + )}

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

{transaction.notes && ( @@ -350,38 +323,44 @@ console.log(aggregatedItems.values())
Total: - Rp {calculateTotalPrice(transaction.DetailedTransactions)} + {formatRp(calculateTotalPrice(transaction.DetailedTransactions))}
- {(deviceType == 'clerk' && !transaction.is_paid && (transaction.confirmed == 0 || transaction.confirmed == 1 || transaction.confirmed == 2)) && - - } + {(deviceType == 'clerk' && !transaction.is_paid && (transaction.confirmed == 0 || transaction.confirmed == 1 || transaction.confirmed == 2)) && ( +
+ + +
+ )} {deviceType == 'guestDevice' && transaction.confirmed < 2 && transaction.payment_type != 'cash' && transaction.payment_type != 'paylater/cash' && handleConfirm(transaction.transactionId)} @@ -404,40 +383,30 @@ console.log(aggregatedItems.values()) }
- {deviceType == 'guestDevice' && transaction.confirmed >= 0 && transaction.confirmed < 2 && transaction.payment_type == 'cash' ? - - : - ((transaction.confirmed >= 0 && transaction.confirmed < 2 && transaction.payment_type != 'paylater/cash' && transaction.payment_type != 'paylater/cashless' || isPaymentOpen) && -
- isPaymentOpen - ? setIsPaymentOpen(false) - : handleDecline(transaction.transactionId) + {deviceType == 'guestDevice' && ( + transaction.confirmed >= 0 && transaction.confirmed < 2 && transaction.payment_type == 'cash' ? ( +
+ {isPaymentLoading ? '...' : 'Batalkan'} + + ) : ( + (transaction.confirmed >= 0 && transaction.confirmed < 2 && (transaction.payment_type != 'paylater/cash' && transaction.payment_type != 'paylater/cashless' || isPaymentOpen)) && ( + + ) ) - } + )}
))}
diff --git a/src/pages/Transactions.module.css b/src/pages/Transactions.module.css index 6002bde..1a86521 100644 --- a/src/pages/Transactions.module.css +++ b/src/pages/Transactions.module.css @@ -13,41 +13,43 @@ } .Transactions { overflow-x: hidden; - background-color: white; + background-color: #f5f7f6; display: flex; flex-direction: column; justify-content: flex-start; font-size: calc(10px + 2vmin); - color: rgba(88, 55, 50, 1); - background-color: #e9e9e9; + color: rgba(40, 40, 40, 1); } .Transactions-title { font-family: "Plus Jakarta Sans", sans-serif; - font-weight: 500; + font-weight: 700; font-style: normal; - font-size: 6vw; - color: black; + font-size: clamp(18px, 3.6vw, 24px); + color: var(--brand-sage, #6B8F71); text-align: left; - margin-left: 20px; - margin-top: 57px; + margin: 16px 16px 8px 16px; } .Transactions-detail { font-family: "Plus Jakarta Sans", sans-serif; font-weight: 500; font-style: normal; - font-size: 15px; - color: rgba(88, 55, 50, 1); + font-size: 13px; + color: #555; text-align: left; - margin-left: 20px; - margin-top: 17px; + margin-left: 16px; + margin-top: 12px; } .TransactionListContainer { overflow-y: auto; /* Enables vertical scrolling */ - background-color: #dbdbdb; + background-color: transparent; overflow: visible; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); + gap: 12px; + padding: 8px 12px 16px; } .TotalContainer { @@ -57,14 +59,14 @@ /* width: 100%; */ margin: 0 auto; font-family: "Plus Jakarta Sans", sans-serif; - font-weight: 600; + font-weight: 700; font-style: normal; - font-size: 15px; + font-size: 13px; /* padding: 10px; */ box-sizing: border-box; - margin-bottom: 17px; - margin-left: 20px; - margin-right: 20px; + margin-bottom: 12px; + margin-left: 16px; + margin-right: 16px; } .PaymentContainer { @@ -83,61 +85,66 @@ .PayButton { font-family: "Plus Jakarta Sans", sans-serif; - font-weight: 500; + font-weight: 600; font-style: normal; - font-size: 12px; /* Adjusted for better readability */ - padding: 12px 16px; /* Added padding for a better look */ - border-radius: 50px; - background-color: rgba(88, 55, 50, 1); + font-size: 12px; + padding: 10px 14px; + border-radius: 10px; /* square rounded */ + background-color: var(--brand-primary, #73a585); color: white; border: none; - margin: 0 auto; cursor: pointer; - display: block; /* Centering the button */ + display: inline-flex; + align-items: center; + justify-content: center; text-align: center; } .DeclineButton { font-family: "Plus Jakarta Sans", sans-serif; - z-index: 201; - position: relative; - font-weight: 500; + font-weight: 600; font-style: normal; - font-size: 15px; - padding: 12px 24px; /* Add some padding for spacing */ - color: rgba(88, 55, 50, 1); - background-color: transparent; /* No background */ - border: none; /* No border */ - margin: 0 auto; /* Center horizontally */ + font-size: 12px; + padding: 10px 14px; + color: #444; + background-color: #f0f0f0; + border: 1px solid #e0e0e0; + border-radius: 10px; /* square rounded */ cursor: pointer; - display: block; /* Center the text horizontally */ - text-align: center; /* Center the text within the button */ + display: inline-flex; + align-items: center; + justify-content: center; } -.DeclineButton.active { - position: relative; - z-index: 201; - font-family: "Plus Jakarta Sans", sans-serif; - font-weight: 500; - font-style: normal; - font-size: 20px; - padding: 12px 24px; /* Add some padding for spacing */ - color: rgba(88, 55, 50, 1); - background-color: transparent; /* No background */ - border: none; /* No border */ - margin: 0 auto; /* Center horizontally */ - cursor: pointer; - display: block; /* Center the text horizontally */ - text-align: center; /* Center the text within the button */ - margin-bottom: 23px; /* Space at the bottom to match the PayButton */ +.DeclineButton.active { opacity: 0.9; } + +/* Row for primary/secondary action buttons */ +.ActionRow { + display: flex; + gap: 8px; + width: 100%; + justify-content: center; } .RoundedRectangle { position: relative; - border-radius: 20px; - padding: 15px; /* Adjusted for better spacing */ - margin: 12px; - background-color: #f9f9f9; + border-radius: 16px; + padding: 12px 12px 10px; + margin: 0; + background-color: #ffffff; + border: 1px solid var(--brand-sage-100, #E9F3ED); + box-shadow: 0 6px 18px rgba(0, 0, 0, 0.06); + display: flex; + flex-direction: column; + min-height: 280px; /* base height, grows with content */ } +/* Unpaid tickets: taller to keep content inside ticket design */ +.unpaid { + min-height: 380px; +} + +/* Self pickup accent: subtle brand accent */ +/* removed pickup accent and badge per request */ + .expression { width: 100%; } @@ -201,20 +208,28 @@ } .receipt-logo { - width: 80px; - height: 80px; + width: 60px; + height: 60px; border-radius: 50%; /* Circular logo */ object-fit: cover; - margin-bottom: 10px; + margin-bottom: 8px; } .receipt-info h3 { - font-size: 16px; - margin: 5px 0; + font-size: 13px; + font-weight: 700; + color: var(--brand-sage, #6B8F71); + margin: 4px 0 2px; } +/* Status-colors override */ +.receipt-info h3.statusNeutral { color: var(--brand-sage, #6B8F71); } +.receipt-info h3.statusSuccess { color: #54B265; } +.receipt-info h3.statusCancelled { color: #E45454; } + .receipt-info p { - font-size: 14px; + font-size: 12px; + color: #666; margin: 2px 0; } /* Dotted line with circular cutouts */ @@ -222,39 +237,61 @@ display: flex; align-items: center; justify-content: center; - margin: 15px 0; + margin: 12px 0 10px; } .dotted-line .line { - border-top: 13px dotted #dbdbdb; + border-top: 10px dotted #e9e9e9; width: 100%; margin: 0 18px; } .dotted-line .circle-left { - left: -25px; + left: -18px; position: absolute; - width: 50px; - height: 50px; + width: 36px; + height: 36px; border-radius: 50%; - background-color: #dbdbdb; + background-color: #e9e9e9; display: flex; /* Use flexbox to center the inner circle */ justify-content: center; /* Center horizontally */ align-items: center; /* Center vertically */ } .dotted-line .circle-right { - right: -25px; + right: -18px; position: absolute; - width: 50px; - height: 50px; + width: 36px; + height: 36px; border-radius: 50%; - background-color: #dbdbdb; + background-color: #e9e9e9; display: flex; /* Use flexbox to center the inner circle */ justify-content: center; /* Center horizontally */ align-items: center; /* Center vertically */ } +/* No scroll body for items per request */ + +/* Compact list text */ +.RoundedRectangle ul { + list-style: none; + padding: 0 12px 6px; + margin: 0; +} +.RoundedRectangle ul li { + font-size: 12px; + color: #333; + padding: 3px 0; +} + +/* Grid density tweaks */ +@media (min-width: 640px) { + .TransactionListContainer { gap: 14px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); } +} +@media (min-width: 1024px) { + .TransactionListContainer { gap: 16px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); } +} + .inner-circle { width: 80%; height: 80%; @@ -389,10 +426,11 @@ .addNewItem{ width: 100%; - height: 27px; - background-color: rgb(115, 165, 133); - border-radius: 11px; + height: 28px; + background-color: var(--brand-primary, rgb(115, 165, 133)); + border-radius: 10px; /* square rounded */ text-align: center; color: white; - line-height: 27px; -} \ No newline at end of file + line-height: 28px; + font-size: 12px; /* compact */ +}