feat(payment): expose secure APIs and themed pages

This commit is contained in:
Clintchiz committed 2026-08-28 09:59:07 +05:30
1 parent dd8d6ecc3b
commit 2d77f5457c
15 files changed
+654 -13

No files matched your search

@@ -0,0 +1,16 @@
import PaymentSheet from "./PaymentSheet.wrn"
component PaymentCheckoutPage {
props {
checkoutUrl: string
gateway: string
title?: string = "Secure checkout"
description?: string = "Complete payment through the selected secure provider."
securityLabel?: string = "Your payment credentials are handled by the payment provider."
}
view {
<section class="wrn-payment-page wrn-payment-checkout-page">
<header class="wrn-payment-page__header"><div><span class="wrn-payment-page__eyebrow">{gateway}</span><h1>{title}</h1><p>{description}</p></div></header>
<div class="wrn-payment-panel"><PaymentSheet checkoutUrl={checkoutUrl} gateway={gateway} /><p class="wrn-payment-security">{securityLabel}</p></div>
</section>
}
}
@@ -0,0 +1,22 @@
import PaymentStatus from "./PaymentStatus.wrn"
component PaymentDetailsPage {
props {
payment: object
title?: string = "Payment details"
amountLabel?: string = "Amount"
providerLabel?: string = "Provider"
referenceLabel?: string = "Reference"
createdLabel?: string = "Created"
}
view {
<section class="wrn-payment-page">
<header class="wrn-payment-page__header"><div><span class="wrn-payment-page__eyebrow">{title}</span><h1>{title}</h1></div><PaymentStatus status={payment.status} /></header>
<dl class="wrn-payment-details">
<div><dt>{amountLabel}</dt><dd>{payment.currency} {payment.amount}</dd></div>
<div><dt>{providerLabel}</dt><dd>{payment.gateway}</dd></div>
<div><dt>{referenceLabel}</dt><dd>{payment.id}</dd></div>
<div><dt>{createdLabel}</dt><dd>{payment.createdAt}</dd></div>
</dl>
</section>
}
}
@@ -0,0 +1,15 @@
import PaymentMethodList from "./PaymentMethodList.wrn"
component PaymentMethodsPage {
props {
methods: array = []
title?: string = "Payment methods"
description?: string = "Manage provider-vaulted payment methods."
emptyLabel?: string = "No saved payment methods."
}
view {
<section class="wrn-payment-page">
<header class="wrn-payment-page__header"><div><span class="wrn-payment-page__eyebrow">{title}</span><h1>{title}</h1><p>{description}</p></div></header>
<div class="wrn-payment-panel">{#if methods.length}<PaymentMethodList methods={methods} />{:else}<div class="wrn-payment-empty">{emptyLabel}</div>{/if}</div>
</section>
}
}
@@ -0,0 +1,21 @@
import PaymentHistory from "./PaymentHistory.wrn"
import PaymentSummary from "./PaymentSummary.wrn"
component PaymentOverviewPage {
props {
payments: array = []
captured: number = 0
refunded: number = 0
net: number = 0
currency: string = "USD"
title?: string = "Payments"
description?: string = "Review payment activity, statuses, and totals."
emptyLabel?: string = "No payments yet."
}
view {
<section class="wrn-payment-page">
<header class="wrn-payment-page__header"><div><span class="wrn-payment-page__eyebrow">{title}</span><h1>{title}</h1><p>{description}</p></div></header>
<PaymentSummary captured={captured} refunded={refunded} net={net} currency={currency} />
<div class="wrn-payment-panel"><h2>{title}</h2>{#if payments.length}<PaymentHistory payments={payments} />{:else}<div class="wrn-payment-empty">{emptyLabel}</div>{/if}</div>
</section>
}
}
@@ -5,5 +5,5 @@ component PaymentSummary {
net: number = 0
currency: string
}
view { <dl><dt>Captured</dt><dd>{currency} {captured}</dd><dt>Refunded</dt><dd>{currency} {refunded}</dd><dt>Net</dt><dd>{currency} {net}</dd></dl> }
view { <dl class="wrn-payment-summary"><div><dt>Captured</dt><dd>{currency} {captured}</dd></div><div><dt>Refunded</dt><dd>{currency} {refunded}</dd></div><div><dt>Net</dt><dd>{currency} {net}</dd></div></dl> }
}
+154
View File
@@ -0,0 +1,154 @@
.wrn-payment-page {
color: var(--color-text, var(--wrn-color-text, #f5f7f6));
display: grid;
gap: 1.25rem;
width: 100%;
}
.wrn-payment-page__header {
align-items: flex-start;
display: flex;
gap: 1rem;
justify-content: space-between;
}
.wrn-payment-page__header h1 {
font-size: clamp(1.75rem, 4vw, 2.75rem);
letter-spacing: -0.04em;
margin: 0.35rem 0;
}
.wrn-payment-page__header p {
color: var(--color-text-muted, var(--wrn-color-muted, #a7afab));
margin: 0;
max-width: 42rem;
}
.wrn-payment-page__eyebrow {
color: var(--color-primary, var(--wrn-color-primary, #10b981));
font-size: 0.72rem;
font-weight: 700;
letter-spacing: 0.14em;
text-transform: uppercase;
}
.wrn-payment-panel,
.wrn-payment-details,
.wrn-payment-summary {
background: var(--color-surface, var(--wrn-color-surface, #111412));
border: 1px solid var(--color-border, var(--wrn-color-border, #29302c));
border-radius: var(--radius-lg, 1rem);
padding: 1.25rem;
}
.wrn-payment-summary {
display: grid;
gap: 1rem;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.wrn-payment-summary div,
.wrn-payment-details div {
display: grid;
gap: 0.35rem;
}
.wrn-payment-summary dt,
.wrn-payment-details dt {
color: var(--color-text-muted, var(--wrn-color-muted, #a7afab));
font-size: 0.75rem;
text-transform: uppercase;
}
.wrn-payment-summary dd,
.wrn-payment-details dd {
font-size: 1.1rem;
font-weight: 700;
margin: 0;
}
.wrn-payment-details {
display: grid;
gap: 1rem;
grid-template-columns: repeat(2, minmax(0, 1fr));
margin: 0;
}
.wrn-payment-history,
.wrn-payment-methods {
display: grid;
gap: 0.25rem;
list-style: none;
margin: 0;
padding: 0;
}
.wrn-payment-history li,
.wrn-payment-methods li {
align-items: center;
border-bottom: 1px solid var(--color-border, var(--wrn-color-border, #29302c));
display: flex;
justify-content: space-between;
padding: 0.85rem 0;
}
.wrn-payment-history li:last-child,
.wrn-payment-methods li:last-child {
border-bottom: 0;
}
.wrn-payment-status {
align-items: center;
background: color-mix(
in srgb,
var(--color-primary, var(--wrn-color-primary, #10b981)) 12%,
transparent
);
border: 1px solid
color-mix(in srgb, var(--color-primary, var(--wrn-color-primary, #10b981)) 32%, transparent);
border-radius: 999px;
display: inline-flex;
gap: 0.5rem;
padding: 0.45rem 0.75rem;
}
.wrn-payment-status strong {
font-size: 0.72rem;
}
.wrn-payment-status span {
text-transform: capitalize;
}
.wrn-payment-sheet {
display: grid;
gap: 1rem;
}
.wrn-payment-sheet a,
.wrn-payment-button {
align-items: center;
background: var(--color-primary, var(--wrn-color-primary, #10b981));
border-radius: var(--radius-md, 0.7rem);
color: var(--color-on-primary, #fff);
display: inline-flex;
font-weight: 700;
justify-content: center;
min-height: 2.75rem;
padding: 0.65rem 1rem;
text-decoration: none;
}
.wrn-payment-button[aria-disabled="true"] {
cursor: not-allowed;
opacity: 0.5;
pointer-events: none;
}
.wrn-payment-empty {
color: var(--color-text-muted, var(--wrn-color-muted, #a7afab));
padding: 2rem;
text-align: center;
}
.wrn-payment-security {
color: var(--color-text-muted, var(--wrn-color-muted, #a7afab));
font-size: 0.8rem;
}
.wrn-payment-panel h2 {
font-size: 1rem;
margin: 0 0 0.75rem;
}
@media (max-width: 640px) {
.wrn-payment-page__header {
display: grid;
}
.wrn-payment-summary,
.wrn-payment-details {
grid-template-columns: 1fr;
}
.wrn-payment-panel,
.wrn-payment-details,
.wrn-payment-summary {
padding: 1rem;
}
}