feat(payment): expose secure APIs and themed pages
This commit is contained in:
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> }
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user