Compare commits

..

1 Commits

Author SHA1 Message Date
karyamanswasta
2add1c5090 ok 2025-08-27 08:15:48 +07:00
2 changed files with 219 additions and 212 deletions

View File

@@ -30,6 +30,15 @@ export default function Transactions({ shop, shopId, propsShopId, sendParam, dev
const [loading, setLoading] = useState(false); 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(() => { useEffect(() => {
setMatchedItems(searchAndAggregateItems(transactions, searchTerm)); setMatchedItems(searchAndAggregateItems(transactions, searchTerm));
}, [searchTerm, transactions]); }, [searchTerm, transactions]);
@@ -154,7 +163,7 @@ console.log(aggregatedItems.values())
return ( return (
<div className={styles.Transactions}> <div className={styles.Transactions}>
<h2 className={styles["Transactions-title"]}> <h2 className={styles["Transactions-title"]}>
Transaksi selesai Rp {calculateAllTransactionsTotal(transactions)} Transaksi selesai {formatRp(calculateAllTransactionsTotal(transactions))}
</h2> </h2>
<input <input
@@ -162,13 +171,13 @@ console.log(aggregatedItems.values())
placeholder="Cari nama item..." placeholder="Cari nama item..."
value={searchTerm} value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)} onChange={(e) => 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) */} {/* Existing Transactions List (keep all your JSX below unchanged) */}
<div className={styles.TransactionListContainer} style={{ padding: '0 8px' }}> <div className={styles.TransactionListContainer}>
{matchedItems.length > 0 && matchedItems.map(item => ( {matchedItems.length > 0 && matchedItems.map(item => (
<div <div
@@ -183,7 +192,7 @@ console.log(aggregatedItems.values())
</ul> </ul>
<div className={styles.TotalContainer}> <div className={styles.TotalContainer}>
<span>Total:</span> <span>Total:</span>
<span>Rp {item.totalPrice}</span> <span>{formatRp(item.totalPrice)}</span>
</div> </div>
</div> </div>
))} ))}
@@ -191,94 +200,60 @@ console.log(aggregatedItems.values())
transactions.map((transaction) => ( transactions.map((transaction) => (
<div <div
key={transaction.transactionId} key={transaction.transactionId}
className={styles.RoundedRectangle} className={`${styles.RoundedRectangle} ${!transaction.is_paid ? styles.unpaid : ''}`}
style={{ overflow: 'hidden' }}
> >
<div className={styles['receipt-header']}> <div className={styles['receipt-header']}>
{transaction.confirmed === 1 ? ( {transaction.confirmed === 1 ? (
<ColorRing className={styles['receipt-logo']} /> <ColorRing className={styles['receipt-logo']} />
) : transaction.confirmed === -1 && !transaction.is_paid || transaction.confirmed === -2 && !transaction.is_paid ? ( ) : (transaction.confirmed === -1 && !transaction.is_paid) || (transaction.confirmed === -2 && !transaction.is_paid) ? (
<div style={{ display: 'flex', justifyContent: 'center', margin: '16px 0px' }}> <div style={{ display: 'flex', justifyContent: 'center', margin: '12px 0' }}>
<svg <svg width="60" height="60" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
style={{ width: '60px', transform: 'Rotate(45deg)' }} <path d="M18.3 5.7a1 1 0 0 0-1.4 0L12 10.6 7.1 5.7A1 1 0 0 0 5.7 7.1L10.6 12l-4.9 4.9a1 1 0 1 0 1.4 1.4L12 13.4l4.9 4.9a1 1 0 0 0 1.4-1.4L13.4 12l4.9-4.9a1 1 0 0 0 0-1.4z" fill="#E45454"/>
clipRule="evenodd"
fillRule="evenodd"
strokeLinejoin="round"
strokeMiterlimit="2"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="m12.002 2c5.518 0 9.998 4.48 9.998 9.998 0 5.517-4.48 9.997-9.998 9.997-5.517 0-9.997-4.48-9.997-9.997 0-5.518 4.48-9.998 9.997-9.998zm0 1.5c-4.69 0-8.497 3.808-8.497 8.498s3.807 8.497 8.497 8.497 8.498-3.807 8.498-8.497-3.808-8.498-8.498-8.498zm-.747 7.75h-3.5c-.414 0-.75.336-.75.75s.336.75.75.75h3.5v3.5c0 .414.336.75.75.75s.75-.336.75-.75v-3.5h3.5c.414 0 .75-.336.75-.75s-.336-.75-.75-.75h-3.5v-3.5c0-.414-.336-.75-.75-.75s-.75.336-.75.75z"
fillRule="nonzero"
/>
</svg> </svg>
</div> </div>
) : transaction.confirmed === 2 && !transaction.is_paid ? ( ) : transaction.confirmed === 2 && !transaction.is_paid ? (
<ColorRing className={styles['receipt-logo']} /> <ColorRing className={styles['receipt-logo']} />
) : transaction.confirmed === 3 || transaction.is_paid ? ( ) : transaction.confirmed === 3 || transaction.is_paid ? (
<div> <div style={{ display: 'flex', justifyContent: 'center', margin: '12px 0' }}>
<svg <svg width="60" height="60" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
height="60px" <path d="M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z" fill="#54B265"/>
width="60px"
version="1.1"
id="Layer_1"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
viewBox="0 0 506.4 506.4"
xmlSpace="preserve"
fill="#000000"
style={{ marginTop: '12px', marginBottom: '12px' }}
>
<g id="SVGRepo_bgCarrier" strokeWidth="0"></g>
<g id="SVGRepo_tracerCarrier" strokeLinecap="round" strokeLinejoin="round"></g>
<g id="SVGRepo_iconCarrier">
<circle style={{ fill: '#54B265' }} cx="253.2" cy="253.2" r="249.2" />
<path
style={{ fill: '#F4EFEF' }}
d="M372.8,200.4l-11.2-11.2c-4.4-4.4-12-4.4-16.4,0L232,302.4l-69.6-69.6c-4.4-4.4-12-4.4-16.4,0 L134.4,244c-4.4,4.4-4.4,12,0,16.4l89.2,89.2c4.4,4.4,12,4.4,16.4,0l0,0l0,0l10.4-10.4l0.8-0.8l121.6-121.6 C377.2,212.4,377.2,205.2,372.8,200.4z"
></path>
<path d="M253.2,506.4C113.6,506.4,0,392.8,0,253.2S113.6,0,253.2,0s253.2,113.6,253.2,253.2S392.8,506.4,253.2,506.4z M253.2,8 C118,8,8,118,8,253.2s110,245.2,245.2,245.2s245.2-110,245.2-245.2S388.4,8,253.2,8z"></path>
<path d="M231.6,357.2c-4,0-8-1.6-11.2-4.4l-89.2-89.2c-6-6-6-16,0-22l11.6-11.6c6-6,16.4-6,22,0l66.8,66.8L342,186.4 c2.8-2.8,6.8-4.4,11.2-4.4c4,0,8,1.6,11.2,4.4l11.2,11.2l0,0c6,6,6,16,0,22L242.8,352.4C239.6,355.6,235.6,357.2,231.6,357.2z M154,233.6c-2,0-4,0.8-5.6,2.4l-11.6,11.6c-2.8,2.8-2.8,8,0,10.8l89.2,89.2c2.8,2.8,8,2.8,10.8,0l132.8-132.8c2.8-2.8,2.8-8,0-10.8 l-11.2-11.2c-2.8-2.8-8-2.8-10.8,0L234.4,306c-1.6,1.6-4,1.6-5.6,0l-69.6-69.6C158,234.4,156,233.6,154,233.6z"></path>
</g>
</svg> </svg>
</div> </div>
) : ( ) : (
<ColorRing className={styles['receipt-logo']} /> <ColorRing className={styles['receipt-logo']} />
)} )}
<div className={styles['receipt-info']}> <div className={styles['receipt-info']}>
{deviceType == 'clerk' ? {deviceType == 'clerk' ?
<h3>{transaction.confirmed === 1 && !transaction.is_paid ? ( <h3 className={getStatusClass(transaction)}>{transaction.confirmed === 1 && !transaction.is_paid ? (
"Silahkan Cek Pembayaran" "Silahkan Cek Pembayaran"
) : transaction.confirmed === -1 && !transaction.is_paid ? ( ) : transaction.confirmed === -1 && !transaction.is_paid ? (
"Dibatalkan Oleh Kasir" "Dibatalkan Oleh Kasir"
) : transaction.confirmed === -2 && !transaction.is_paid ? ( ) : transaction.confirmed === -2 && !transaction.is_paid ? (
"Dibatalkan Oleh Pelanggan" "Dibatalkan Oleh Pelanggan"
) : transaction.confirmed === 2 && !transaction.is_paid ? ( ) : transaction.confirmed === 2 && !transaction.is_paid ? (
"Sedang Diproses" "Sedang Diproses"
) : transaction.confirmed === 3 || transaction.is_paid ? ( ) : transaction.confirmed === 3 || transaction.is_paid ? (
"Transaksi Sukses" "Transaksi Sukses"
) : ( ) : (
"Silahkan Cek Ketersediaan" "Silahkan Cek Ketersediaan"
)}</h3> )}</h3>
: :
<h3>{transaction.confirmed === 1 ? ( <h3 className={getStatusClass(transaction)}>{transaction.confirmed === 1 ? (
(transaction.payment_type == 'cash' ? 'Silahkan Bayar Ke Kasir' : "Silahkan Bayar Dengan QRIS") (transaction.payment_type == 'cash' ? 'Silahkan Bayar Ke Kasir' : "Silahkan Bayar Dengan QRIS")
) : transaction.confirmed === -1 ? ( ) : transaction.confirmed === -1 ? (
"Dibatalkan Oleh Kasir" "Dibatalkan Oleh Kasir"
) : transaction.confirmed === -2 ? ( ) : transaction.confirmed === -2 ? (
"Dibatalkan Oleh Pelanggan" "Dibatalkan Oleh Pelanggan"
) : transaction.confirmed === 2 ? ( ) : transaction.confirmed === 2 ? (
"Sedang diproses" "Sedang diproses"
) : transaction.confirmed === 3 ? ( ) : transaction.confirmed === 3 ? (
"Transaksi Sukses" "Transaksi Sukses"
) : ( ) : (
"Memeriksa Ketersediaan " "Memeriksa Ketersediaan "
)}</h3>} )}</h3>}
<p>Transaction ID: {transaction.transactionId}</p> <p>Transaction ID: {transaction.transactionId}</p>
<p>Payment Type: {transaction.payment_type}</p> <p>Payment Type: {transaction.payment_type}</p>
@@ -304,12 +279,11 @@ console.log(aggregatedItems.values())
<ul> <ul>
{transaction.DetailedTransactions.map((detail) => ( {transaction.DetailedTransactions.map((detail) => (
<li key={detail.detailedTransactionId}> <li key={detail.detailedTransactionId}>
<span>{detail.Item.name}</span> - {detail.qty < 1 ? 'tidak tersedia' : `${detail.qty} x Rp <span>{detail.Item.name}</span> - {detail.qty < 1 ? 'tidak tersedia' : `${detail.qty} x ${formatRp(detail.promoPrice ? detail.promoPrice : detail.price)}`}
${detail.promoPrice ? detail.promoPrice : detail.price}`}
</li> </li>
))} ))}
</ul> </ul>
{!transaction.is_paid && transaction.confirmed > -1 && {!transaction.is_paid && transaction.confirmed > -1 && (
<div <div
onClick={() => { onClick={() => {
localStorage.setItem('lastTransaction', JSON.stringify(transaction)); localStorage.setItem('lastTransaction', JSON.stringify(transaction));
@@ -322,12 +296,11 @@ console.log(aggregatedItems.values())
> >
Tambah pesanan Tambah pesanan
</div> </div>
} )}
<h2 className={styles["Transactions-detail"]}> <h2 className={styles["Transactions-detail"]}>
{transaction.serving_type === "pickup" {transaction.serving_type === "pickup"
? "Self pickup" ? "Self pickup"
: `Serve to ${transaction.Table ? transaction.Table.tableNo : "N/A" : `Serve to ${transaction.Table ? transaction.Table.tableNo : "N/A"}`}
}`}
</h2> </h2>
{transaction.notes && ( {transaction.notes && (
@@ -350,38 +323,44 @@ console.log(aggregatedItems.values())
<div className={styles.TotalContainer}> <div className={styles.TotalContainer}>
<span>Total:</span> <span>Total:</span>
<span> <span>
Rp {calculateTotalPrice(transaction.DetailedTransactions)} {formatRp(calculateTotalPrice(transaction.DetailedTransactions))}
</span> </span>
</div> </div>
<div className={styles.TotalContainer}> <div className={styles.TotalContainer}>
{(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)) && (
<button <div className={styles.ActionRow}>
className={styles.PayButton} <button
onClick={() => handleConfirm(transaction.transactionId)} className={styles.PayButton}
disabled={isPaymentLoading} onClick={() => handleConfirm(transaction.transactionId)}
> disabled={isPaymentLoading}
{ >
isPaymentLoading ? ( {
<ColorRing height="50" width="50" color="white" /> isPaymentLoading ? (
) : transaction.confirmed === 1 ? ( <ColorRing height="28" width="28" color="white" />
"Konfirmasi Telah Bayar" ) : transaction.confirmed === 1 ? (
) : transaction.confirmed === 2 ? ( "Konfirmasi"
"Confirm item is ready" ) : transaction.confirmed === 2 ? (
) : ( "Confirm item is ready"
"Confirm availability" ) : (
) "Confirm availability"
} )
}
</button> </button>
} <button
className={styles.DeclineButton}
onClick={() => handleDecline(transaction.transactionId)}
disabled={isPaymentLoading}
>
{isPaymentLoading ? '...' : 'Batalkan'}
</button>
</div>
)}
{deviceType == 'guestDevice' && transaction.confirmed < 2 && transaction.payment_type != 'cash' && transaction.payment_type != 'paylater/cash' && {deviceType == 'guestDevice' && transaction.confirmed < 2 && transaction.payment_type != 'cash' && transaction.payment_type != 'paylater/cash' &&
<ButtonWithReplica <ButtonWithReplica
paymentUrl={paymentUrl} paymentUrl={paymentUrl}
price={ price={formatRp(calculateTotalPrice(transaction.DetailedTransactions))}
"Rp" + calculateTotalPrice(transaction.DetailedTransactions)
}
disabled={isPaymentLoading} disabled={isPaymentLoading}
isPaymentLoading={isPaymentLoading} isPaymentLoading={isPaymentLoading}
handleClick={() => handleConfirm(transaction.transactionId)} handleClick={() => handleConfirm(transaction.transactionId)}
@@ -404,40 +383,30 @@ console.log(aggregatedItems.values())
} }
</div> </div>
{deviceType == 'guestDevice' && transaction.confirmed >= 0 && transaction.confirmed < 2 && transaction.payment_type == 'cash' ? {deviceType == 'guestDevice' && (
<button transaction.confirmed >= 0 && transaction.confirmed < 2 && transaction.payment_type == 'cash' ? (
className={styles.PayButton} <button
onClick={() => handleDecline(transaction.transactionId)} className={styles.DeclineButton}
disabled={ onClick={() => handleDecline(transaction.transactionId)}
transaction.confirmed === -1 || disabled={
transaction.confirmed === 3 || transaction.confirmed === -1 ||
isPaymentLoading transaction.confirmed === 3 ||
} // Disable button if confirmed (1) or declined (-1) or isPaymentLoading
>
{isPaymentLoading ? (
<ColorRing height="50" width="50" color="white" />
) : transaction.confirmed === -1 ? (
"Ditolak" // Display "Declined" if the transaction is declined (-1)
) : transaction.confirmed === -2 ? (
"Dibatalkan" // Display "Declined" if the transaction is declined (-1)
) : (
"Batalkan" // Display "Confirm availability" if the transaction is not confirmed (0)
)}
</button>
:
((transaction.confirmed >= 0 && transaction.confirmed < 2 && transaction.payment_type != 'paylater/cash' && transaction.payment_type != 'paylater/cashless' || isPaymentOpen) &&
<h5
className={`${styles.DeclineButton}`}
onClick={() =>
isPaymentOpen
? setIsPaymentOpen(false)
: handleDecline(transaction.transactionId)
} }
> >
{isPaymentOpen ? "kembali" : "batalkan"} {isPaymentLoading ? '...' : 'Batalkan'}
</h5> </button>
) : (
(transaction.confirmed >= 0 && transaction.confirmed < 2 && (transaction.payment_type != 'paylater/cash' && transaction.payment_type != 'paylater/cashless' || isPaymentOpen)) && (
<button
className={styles.DeclineButton}
onClick={() => isPaymentOpen ? setIsPaymentOpen(false) : handleDecline(transaction.transactionId)}
>
{isPaymentOpen ? 'Kembali' : 'Batalkan'}
</button>
)
) )
} )}
</div> </div>
))} ))}
</div> </div>

View File

@@ -13,41 +13,43 @@
} }
.Transactions { .Transactions {
overflow-x: hidden; overflow-x: hidden;
background-color: white; background-color: #f5f7f6;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: flex-start;
font-size: calc(10px + 2vmin); font-size: calc(10px + 2vmin);
color: rgba(88, 55, 50, 1); color: rgba(40, 40, 40, 1);
background-color: #e9e9e9;
} }
.Transactions-title { .Transactions-title {
font-family: "Plus Jakarta Sans", sans-serif; font-family: "Plus Jakarta Sans", sans-serif;
font-weight: 500; font-weight: 700;
font-style: normal; font-style: normal;
font-size: 6vw; font-size: clamp(18px, 3.6vw, 24px);
color: black; color: var(--brand-sage, #6B8F71);
text-align: left; text-align: left;
margin-left: 20px; margin: 16px 16px 8px 16px;
margin-top: 57px;
} }
.Transactions-detail { .Transactions-detail {
font-family: "Plus Jakarta Sans", sans-serif; font-family: "Plus Jakarta Sans", sans-serif;
font-weight: 500; font-weight: 500;
font-style: normal; font-style: normal;
font-size: 15px; font-size: 13px;
color: rgba(88, 55, 50, 1); color: #555;
text-align: left; text-align: left;
margin-left: 20px; margin-left: 16px;
margin-top: 17px; margin-top: 12px;
} }
.TransactionListContainer { .TransactionListContainer {
overflow-y: auto; /* Enables vertical scrolling */ overflow-y: auto; /* Enables vertical scrolling */
background-color: #dbdbdb; background-color: transparent;
overflow: visible; overflow: visible;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 12px;
padding: 8px 12px 16px;
} }
.TotalContainer { .TotalContainer {
@@ -57,14 +59,14 @@
/* width: 100%; */ /* width: 100%; */
margin: 0 auto; margin: 0 auto;
font-family: "Plus Jakarta Sans", sans-serif; font-family: "Plus Jakarta Sans", sans-serif;
font-weight: 600; font-weight: 700;
font-style: normal; font-style: normal;
font-size: 15px; font-size: 13px;
/* padding: 10px; */ /* padding: 10px; */
box-sizing: border-box; box-sizing: border-box;
margin-bottom: 17px; margin-bottom: 12px;
margin-left: 20px; margin-left: 16px;
margin-right: 20px; margin-right: 16px;
} }
.PaymentContainer { .PaymentContainer {
@@ -83,61 +85,66 @@
.PayButton { .PayButton {
font-family: "Plus Jakarta Sans", sans-serif; font-family: "Plus Jakarta Sans", sans-serif;
font-weight: 500; font-weight: 600;
font-style: normal; font-style: normal;
font-size: 12px; /* Adjusted for better readability */ font-size: 12px;
padding: 12px 16px; /* Added padding for a better look */ padding: 10px 14px;
border-radius: 50px; border-radius: 10px; /* square rounded */
background-color: rgba(88, 55, 50, 1); background-color: var(--brand-primary, #73a585);
color: white; color: white;
border: none; border: none;
margin: 0 auto;
cursor: pointer; cursor: pointer;
display: block; /* Centering the button */ display: inline-flex;
align-items: center;
justify-content: center;
text-align: center; text-align: center;
} }
.DeclineButton { .DeclineButton {
font-family: "Plus Jakarta Sans", sans-serif; font-family: "Plus Jakarta Sans", sans-serif;
z-index: 201; font-weight: 600;
position: relative;
font-weight: 500;
font-style: normal; font-style: normal;
font-size: 15px; font-size: 12px;
padding: 12px 24px; /* Add some padding for spacing */ padding: 10px 14px;
color: rgba(88, 55, 50, 1); color: #444;
background-color: transparent; /* No background */ background-color: #f0f0f0;
border: none; /* No border */ border: 1px solid #e0e0e0;
margin: 0 auto; /* Center horizontally */ border-radius: 10px; /* square rounded */
cursor: pointer; cursor: pointer;
display: block; /* Center the text horizontally */ display: inline-flex;
text-align: center; /* Center the text within the button */ align-items: center;
justify-content: center;
} }
.DeclineButton.active { .DeclineButton.active { opacity: 0.9; }
position: relative;
z-index: 201; /* Row for primary/secondary action buttons */
font-family: "Plus Jakarta Sans", sans-serif; .ActionRow {
font-weight: 500; display: flex;
font-style: normal; gap: 8px;
font-size: 20px; width: 100%;
padding: 12px 24px; /* Add some padding for spacing */ justify-content: center;
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 */
} }
.RoundedRectangle { .RoundedRectangle {
position: relative; position: relative;
border-radius: 20px; border-radius: 16px;
padding: 15px; /* Adjusted for better spacing */ padding: 12px 12px 10px;
margin: 12px; margin: 0;
background-color: #f9f9f9; 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 { .expression {
width: 100%; width: 100%;
} }
@@ -201,20 +208,28 @@
} }
.receipt-logo { .receipt-logo {
width: 80px; width: 60px;
height: 80px; height: 60px;
border-radius: 50%; /* Circular logo */ border-radius: 50%; /* Circular logo */
object-fit: cover; object-fit: cover;
margin-bottom: 10px; margin-bottom: 8px;
} }
.receipt-info h3 { .receipt-info h3 {
font-size: 16px; font-size: 13px;
margin: 5px 0; 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 { .receipt-info p {
font-size: 14px; font-size: 12px;
color: #666;
margin: 2px 0; margin: 2px 0;
} }
/* Dotted line with circular cutouts */ /* Dotted line with circular cutouts */
@@ -222,39 +237,61 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin: 15px 0; margin: 12px 0 10px;
} }
.dotted-line .line { .dotted-line .line {
border-top: 13px dotted #dbdbdb; border-top: 10px dotted #e9e9e9;
width: 100%; width: 100%;
margin: 0 18px; margin: 0 18px;
} }
.dotted-line .circle-left { .dotted-line .circle-left {
left: -25px; left: -18px;
position: absolute; position: absolute;
width: 50px; width: 36px;
height: 50px; height: 36px;
border-radius: 50%; border-radius: 50%;
background-color: #dbdbdb; background-color: #e9e9e9;
display: flex; /* Use flexbox to center the inner circle */ display: flex; /* Use flexbox to center the inner circle */
justify-content: center; /* Center horizontally */ justify-content: center; /* Center horizontally */
align-items: center; /* Center vertically */ align-items: center; /* Center vertically */
} }
.dotted-line .circle-right { .dotted-line .circle-right {
right: -25px; right: -18px;
position: absolute; position: absolute;
width: 50px; width: 36px;
height: 50px; height: 36px;
border-radius: 50%; border-radius: 50%;
background-color: #dbdbdb; background-color: #e9e9e9;
display: flex; /* Use flexbox to center the inner circle */ display: flex; /* Use flexbox to center the inner circle */
justify-content: center; /* Center horizontally */ justify-content: center; /* Center horizontally */
align-items: center; /* Center vertically */ 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 { .inner-circle {
width: 80%; width: 80%;
height: 80%; height: 80%;
@@ -389,10 +426,11 @@
.addNewItem{ .addNewItem{
width: 100%; width: 100%;
height: 27px; height: 28px;
background-color: rgb(115, 165, 133); background-color: var(--brand-primary, rgb(115, 165, 133));
border-radius: 11px; border-radius: 10px; /* square rounded */
text-align: center; text-align: center;
color: white; color: white;
line-height: 27px; line-height: 28px;
font-size: 12px; /* compact */
} }