@openrails/billing-ui 0.249.0 → 0.251.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/README.md +32 -14
- package/dist/account/account-billing.d.ts +2 -2
- package/dist/account/cancel-dialog.d.ts +2 -2
- package/dist/account/change-card-dialog.d.ts +2 -2
- package/dist/account/payment-history.d.ts +2 -2
- package/dist/account/payment-methods-panel.d.ts +2 -2
- package/dist/account/section.d.ts +2 -2
- package/dist/account/subscriptions-panel.d.ts +2 -2
- package/dist/admin/context.d.ts +2 -2
- package/dist/admin/lib/queries.d.ts +1 -1
- package/dist/admin/messages.d.ts +3 -3
- package/dist/admin/pages/catalog/psp-links.d.ts +1 -1
- package/dist/admin/theme.d.ts +2 -2
- package/dist/admin/types.d.ts +2 -2
- package/dist/{admin-attempts-lAoW-Urd.js → admin-attempts-DxRHTODq.js} +8 -8
- package/dist/{admin-attempts-lAoW-Urd.js.map → admin-attempts-DxRHTODq.js.map} +1 -1
- package/dist/{admin-auth-DQGHtt0j.js → admin-auth-CiuZ-Hlm.js} +2 -2
- package/dist/{admin-auth-DQGHtt0j.js.map → admin-auth-CiuZ-Hlm.js.map} +1 -1
- package/dist/{admin-badge-DR5-1qd8.js → admin-badge-VCGbnfiN.js} +2 -2
- package/dist/{admin-badge-DR5-1qd8.js.map → admin-badge-VCGbnfiN.js.map} +1 -1
- package/dist/{admin-button-CTL3DgOt.js → admin-button-Oip73Plq.js} +2 -2
- package/dist/{admin-button-CTL3DgOt.js.map → admin-button-Oip73Plq.js.map} +1 -1
- package/dist/{admin-capabilities-BuigAgtm.js → admin-capabilities-BGv7oG8v.js} +2 -2
- package/dist/{admin-capabilities-BuigAgtm.js.map → admin-capabilities-BGv7oG8v.js.map} +1 -1
- package/dist/{admin-card-bzAks3-3.js → admin-card-DGbi6ZHZ.js} +2 -2
- package/dist/{admin-card-bzAks3-3.js.map → admin-card-DGbi6ZHZ.js.map} +1 -1
- package/dist/{admin-catalog-CK6CM9I2.js → admin-catalog-3pPEAuDY.js} +19 -19
- package/dist/{admin-catalog-CK6CM9I2.js.map → admin-catalog-3pPEAuDY.js.map} +1 -1
- package/dist/{admin-customers-D8u5gq3M.js → admin-customers-cnKMEV4q.js} +6 -6
- package/dist/{admin-customers-D8u5gq3M.js.map → admin-customers-cnKMEV4q.js.map} +1 -1
- package/dist/{admin-dashboard-DqqFjOzq.js → admin-dashboard-DfSsUyo-.js} +14 -14
- package/dist/{admin-dashboard-DqqFjOzq.js.map → admin-dashboard-DfSsUyo-.js.map} +1 -1
- package/dist/{admin-data-table-qfXLOFmN.js → admin-data-table-CgeWv__T.js} +6 -6
- package/dist/{admin-data-table-qfXLOFmN.js.map → admin-data-table-CgeWv__T.js.map} +1 -1
- package/dist/{admin-detail-X82kR2f7.js → admin-detail-BATuJjVs.js} +12 -12
- package/dist/{admin-detail-X82kR2f7.js.map → admin-detail-BATuJjVs.js.map} +1 -1
- package/dist/{admin-detail-DUAJQg8G.js → admin-detail-Cq59e14B.js} +15 -15
- package/dist/{admin-detail-DUAJQg8G.js.map → admin-detail-Cq59e14B.js.map} +1 -1
- package/dist/{admin-detail-BHe51ma9.js → admin-detail-DG-YaHhS.js} +11 -11
- package/dist/{admin-detail-BHe51ma9.js.map → admin-detail-DG-YaHhS.js.map} +1 -1
- package/dist/{admin-detail-CGOyqs7s.js → admin-detail-Dc7rU4mM.js} +15 -15
- package/dist/{admin-detail-CGOyqs7s.js.map → admin-detail-Dc7rU4mM.js.map} +1 -1
- package/dist/{admin-dialog-BjuKI5Hp.js → admin-dialog-Ffx95AIT.js} +3 -3
- package/dist/{admin-dialog-BjuKI5Hp.js.map → admin-dialog-Ffx95AIT.js.map} +1 -1
- package/dist/{admin-dom-uMmZzRvU.js → admin-dom-lnNSQ7ke.js} +4 -4
- package/dist/{admin-dom-uMmZzRvU.js.map → admin-dom-lnNSQ7ke.js.map} +1 -1
- package/dist/{admin-dropdown-menu-BW1D_h6s.js → admin-dropdown-menu-CCiW4-oz.js} +2 -2
- package/dist/{admin-dropdown-menu-BW1D_h6s.js.map → admin-dropdown-menu-CCiW4-oz.js.map} +1 -1
- package/dist/{admin-fact-card-DO_fHosg.js → admin-fact-card-D6mZgxpN.js} +2 -2
- package/dist/{admin-fact-card-DO_fHosg.js.map → admin-fact-card-D6mZgxpN.js.map} +1 -1
- package/dist/{admin-health-B4jN2LwR.js → admin-health-CvJX9prw.js} +13 -13
- package/dist/{admin-health-B4jN2LwR.js.map → admin-health-CvJX9prw.js.map} +1 -1
- package/dist/{admin-input-CcfQfJFN.js → admin-input-DO5lvCLL.js} +2 -2
- package/dist/{admin-input-CcfQfJFN.js.map → admin-input-DO5lvCLL.js.map} +1 -1
- package/dist/{admin-label-BiEN5cjb.js → admin-label-BzJpr3lg.js} +2 -2
- package/dist/{admin-label-BiEN5cjb.js.map → admin-label-BzJpr3lg.js.map} +1 -1
- package/dist/{admin-linked-table-row-BsaUruCN.js → admin-linked-table-row-5vFb6rXY.js} +4 -4
- package/dist/{admin-linked-table-row-BsaUruCN.js.map → admin-linked-table-row-5vFb6rXY.js.map} +1 -1
- package/dist/{admin-metering-COFcSPQy.js → admin-metering-BksTFRRP.js} +14 -14
- package/dist/{admin-metering-COFcSPQy.js.map → admin-metering-BksTFRRP.js.map} +1 -1
- package/dist/{admin-ops-B3mcr76u.js → admin-ops-Ch2-BmUp.js} +11 -11
- package/dist/{admin-ops-B3mcr76u.js.map → admin-ops-Ch2-BmUp.js.map} +1 -1
- package/dist/{admin-orders-dxC99Idl.js → admin-orders-8XzHf7b-.js} +8 -8
- package/dist/{admin-orders-dxC99Idl.js.map → admin-orders-8XzHf7b-.js.map} +1 -1
- package/dist/{admin-payments-Bs7HSfP0.js → admin-payments-pNLNIU0X.js} +9 -9
- package/dist/{admin-payments-Bs7HSfP0.js.map → admin-payments-pNLNIU0X.js.map} +1 -1
- package/dist/{admin-price-detail-DRquxpA9.js → admin-price-detail-BeGDPxKX.js} +11 -11
- package/dist/admin-price-detail-BeGDPxKX.js.map +1 -0
- package/dist/{admin-price-wizard-CI7K-2Nz.js → admin-price-wizard-ferZSTfO.js} +7 -7
- package/dist/{admin-price-wizard-CI7K-2Nz.js.map → admin-price-wizard-ferZSTfO.js.map} +1 -1
- package/dist/{admin-range-picker-Dr2M1EZr.js → admin-range-picker-DaIvC1oC.js} +5 -5
- package/dist/{admin-range-picker-Dr2M1EZr.js.map → admin-range-picker-DaIvC1oC.js.map} +1 -1
- package/dist/{admin-reports-CywKLiSA.js → admin-reports-CA-cnNur.js} +8 -8
- package/dist/{admin-reports-CywKLiSA.js.map → admin-reports-CA-cnNur.js.map} +1 -1
- package/dist/{admin-select-DBgprVW6.js → admin-select-CUXvh6j1.js} +2 -2
- package/dist/{admin-select-DBgprVW6.js.map → admin-select-CUXvh6j1.js.map} +1 -1
- package/dist/{admin-settings-Bmoy95uO.js → admin-settings-C6eWFkDn.js} +16 -16
- package/dist/{admin-settings-Bmoy95uO.js.map → admin-settings-C6eWFkDn.js.map} +1 -1
- package/dist/{admin-skeleton-DsM7crYi.js → admin-skeleton-DEY3Q8Dg.js} +2 -2
- package/dist/{admin-skeleton-DsM7crYi.js.map → admin-skeleton-DEY3Q8Dg.js.map} +1 -1
- package/dist/{admin-status-badge-BFPgo71d.js → admin-status-badge-CwqIU8tK.js} +2 -2
- package/dist/{admin-status-badge-BFPgo71d.js.map → admin-status-badge-CwqIU8tK.js.map} +1 -1
- package/dist/{admin-subscriptions-CLYc_HEV.js → admin-subscriptions-lJG_EzMe.js} +9 -9
- package/dist/{admin-subscriptions-CLYc_HEV.js.map → admin-subscriptions-lJG_EzMe.js.map} +1 -1
- package/dist/{admin-switch-BJUxLCsa.js → admin-switch-S4g_ppaU.js} +2 -2
- package/dist/{admin-switch-BJUxLCsa.js.map → admin-switch-S4g_ppaU.js.map} +1 -1
- package/dist/{admin-table-CH9TrXJf.js → admin-table-CWhiCb9d.js} +2 -2
- package/dist/{admin-table-CH9TrXJf.js.map → admin-table-CWhiCb9d.js.map} +1 -1
- package/dist/{admin-tabs-528FJMjt.js → admin-tabs-Cjm5a6UJ.js} +2 -2
- package/dist/{admin-tabs-528FJMjt.js.map → admin-tabs-Cjm5a6UJ.js.map} +1 -1
- package/dist/{admin-textarea-DEz38RaI.js → admin-textarea-DK1Fq31x.js} +2 -2
- package/dist/{admin-textarea-DEz38RaI.js.map → admin-textarea-DK1Fq31x.js.map} +1 -1
- package/dist/{admin-typed-confirm-dialog-DU7m9-O7.js → admin-typed-confirm-dialog-BloZvFPA.js} +6 -6
- package/dist/{admin-typed-confirm-dialog-DU7m9-O7.js.map → admin-typed-confirm-dialog-BloZvFPA.js.map} +1 -1
- package/dist/{admin-utils-BK4Vh1o_.js → admin-utils-DnVY5fYd.js} +3 -3
- package/dist/admin-utils-DnVY5fYd.js.map +1 -0
- package/dist/{admin-widget-viz-Da48c-Zf.js → admin-widget-viz-RCkxUspL.js} +8 -8
- package/dist/{admin-widget-viz-Da48c-Zf.js.map → admin-widget-viz-RCkxUspL.js.map} +1 -1
- package/dist/admin.js +31 -31
- package/dist/admin.js.map +1 -1
- package/dist/appearance.d.ts +7 -7
- package/dist/buy-button.d.ts +3 -3
- package/dist/cart.d.ts +4 -4
- package/dist/client/client.d.ts +4 -4
- package/dist/client/generated/error-codes.d.ts +1 -1
- package/dist/client/generated/routes.d.ts +6 -6
- package/dist/client/generated/wire.d.ts +38 -40
- package/dist/client/types.d.ts +18 -17
- package/dist/{client-rFrCMrkn.js → client-imFR1UCe.js} +91 -92
- package/dist/client-imFR1UCe.js.map +1 -0
- package/dist/client.js +2 -2
- package/dist/embedded-payment.d.ts +25 -0
- package/dist/hooks-C9JkHcRt.js +553 -0
- package/dist/hooks-C9JkHcRt.js.map +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +768 -735
- package/dist/index.js.map +1 -1
- package/dist/locales/de.js +1 -1
- package/dist/locales/de.js.map +1 -1
- package/dist/locales/en.d.ts +1 -1
- package/dist/locales/en.js +1 -1
- package/dist/locales/en.js.map +1 -1
- package/dist/locales/es.js +1 -1
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/ja.js +1 -1
- package/dist/locales/ja.js.map +1 -1
- package/dist/locales/ko.js +1 -1
- package/dist/locales/ko.js.map +1 -1
- package/dist/locales/zh.js +1 -1
- package/dist/locales/zh.js.map +1 -1
- package/dist/modal.d.ts +8 -8
- package/dist/{order-checkout.d.ts → order-payment.d.ts} +4 -4
- package/dist/product-list.d.ts +3 -3
- package/dist/psp.d.ts +2 -2
- package/dist/react/config.d.ts +12 -3
- package/dist/react/provider.d.ts +17 -4
- package/dist/react.js +1 -1
- package/dist/save-payment-method.d.ts +2 -2
- package/dist/scope-context.d.ts +4 -4
- package/dist/scope.d.ts +2 -2
- package/dist/tokenized-card-form.d.ts +2 -2
- package/docs/payment-form-contract.md +3 -3
- package/package.json +2 -2
- package/dist/admin-price-detail-DRquxpA9.js.map +0 -1
- package/dist/admin-utils-BK4Vh1o_.js.map +0 -1
- package/dist/client-rFrCMrkn.js.map +0 -1
- package/dist/embedded-checkout.d.ts +0 -25
- package/dist/hooks-B1TffejB.js +0 -537
- package/dist/hooks-B1TffejB.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## The host supplies the configuration
|
|
4
|
+
|
|
5
|
+
- `BillingProvider` takes `config` (`GET /config`'s document; Go:
|
|
6
|
+
`Engine.PublicConfig` or `Client.GetPublicConfig`) and `customerConfig`
|
|
7
|
+
(`GET /me/config`'s; Go: `Engine.CustomerConfig`) from the host's own page
|
|
8
|
+
response. Supplied, billing-ui does not request them to load; a retry still
|
|
9
|
+
reads the server's copy. `useConfig()`, `useCurrencyScales()` and
|
|
10
|
+
`useCustomerConfig()` read them.
|
|
11
|
+
|
|
12
|
+
## Fallback PSPs
|
|
13
|
+
|
|
14
|
+
- `OrderPayment` offers a payment option marked `fallback` (CCBill once the
|
|
15
|
+
card PSP failed or is unavailable) under "Card payment isn't working?", and
|
|
16
|
+
a customer back from a PSP's page before it reported continues there.
|
|
17
|
+
`OrderPaymentOption` gains `fallback`.
|
|
18
|
+
|
|
19
|
+
## An order and its pay URL
|
|
20
|
+
|
|
21
|
+
- Breaking: "checkout" is gone. `EmbeddedCheckout` is `EmbeddedPayment`,
|
|
22
|
+
`OrderCheckout` is `OrderPayment` (with `EmbeddedPaymentProps`,
|
|
23
|
+
`EmbeddedPaymentCompletion`, `OrderPaymentProps`), and
|
|
24
|
+
`CHECKOUT_COMPLETE_MESSAGE` / `CHECKOUT_RESIZE_MESSAGE` are
|
|
25
|
+
`PAYMENT_COMPLETE_MESSAGE` / `PAYMENT_RESIZE_MESSAGE`, whose types are
|
|
26
|
+
`openrails.payment.complete` and `openrails.payment.resize`.
|
|
27
|
+
- Breaking: `createOrder({ payUrl: { embedded: true } })` replaces
|
|
28
|
+
`checkout: { ui_mode: "embedded" }`. The order answers `pay_url`,
|
|
29
|
+
`pay_url_expires_at`, `embedded`, `success_url`, `cancel_url` and
|
|
30
|
+
`saved_payment_methods` in place of `order.checkout`. The pay URL is
|
|
31
|
+
`/pay/<order>#<secret>` on the payment origin.
|
|
32
|
+
- Breaking: `CheckoutAppearance`, `CheckoutTheme` and `CheckoutVariables` are
|
|
33
|
+
`BillingAppearance`, `BillingTheme` and `BillingVariables`; `checkoutPsps`
|
|
34
|
+
is `routedPsps`, reading a PSP's `routed`.
|
|
35
|
+
|
|
3
36
|
## Hosts sell the products their pages carry
|
|
4
37
|
|
|
5
38
|
- Breaking: the browser never reads the catalog. `listProducts`, `useProducts`,
|
package/README.md
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# @openrails/billing-ui
|
|
2
2
|
|
|
3
|
-
Embeddable OpenRails billing UI:
|
|
3
|
+
Embeddable OpenRails billing UI: purchase, customer account billing, and staff
|
|
4
4
|
administration inside the host's application.
|
|
5
5
|
|
|
6
6
|
| Import | Contents |
|
|
7
7
|
| --------------------------------- | ---------------------------------------------------------------------------------- |
|
|
8
8
|
| `@openrails/billing-ui/client` | Framework-free typed client for `/billing/v1/me/*` and the catalog, `BillingError` |
|
|
9
9
|
| `@openrails/billing-ui/react` | `BillingProvider` and headless hooks, without styles |
|
|
10
|
-
| `@openrails/billing-ui` | `BillingProvider`, styled
|
|
10
|
+
| `@openrails/billing-ui` | `BillingProvider`, styled purchase and account components, i18n |
|
|
11
11
|
| `@openrails/billing-ui/locales/*` | `en de es ja ko zh` message bundles |
|
|
12
12
|
| `@openrails/billing-ui/admin` | `BillingAdmin`, `BillingCustomerSummary`, access and confirmation helpers |
|
|
13
13
|
| `@openrails/billing-ui/admin.css` | Scoped staff administration styles |
|
|
14
14
|
|
|
15
|
-
The
|
|
16
|
-
and `<
|
|
15
|
+
The purchase owns the browser payment flow, behind `<BuyButton>`, `<ProductList>`
|
|
16
|
+
and `<OrderPayment>`: the signed-in customer's order, read and paid with
|
|
17
17
|
their own credential. Card data is tokenized in the PSP's own fields
|
|
18
18
|
(Collect.js, Stripe Elements) and never enters the host application.
|
|
19
19
|
|
|
@@ -74,11 +74,11 @@ price ("$4.99", "Rent for 3 days, $1.99", "$10.00 every 30 days").
|
|
|
74
74
|
|
|
75
75
|
The purchase is theirs from start to payment: a button creates the customer's
|
|
76
76
|
order (`POST /me/orders`) and pays it in a dialog. On a page of a site the
|
|
77
|
-
merchant registered to frame its
|
|
78
|
-
`GET /me/config`), it creates the order with its embedded
|
|
79
|
-
call (`createOrder({ lines,
|
|
80
|
-
`order.
|
|
81
|
-
else it pays on the page (`<
|
|
77
|
+
merchant registered to frame its pay URLs (`merchant.embed_origins` in
|
|
78
|
+
`GET /me/config`), it creates the order with its embedded pay URL in the same
|
|
79
|
+
call (`createOrder({ lines, payUrl: { embedded: true } })`) and frames
|
|
80
|
+
`order.pay_url` from the payment origin (`<EmbeddedPayment>`); anywhere
|
|
81
|
+
else it pays on the page (`<OrderPayment>`). The embedded pay URL returns
|
|
82
82
|
nowhere: the frame says it is paid and tells the page (`onPaid`), and a
|
|
83
83
|
redirect PSP comes back inside it. Nothing is stored: OpenRails answers the
|
|
84
84
|
customer's open order of the same lines, so a second click, a reopened dialog
|
|
@@ -110,7 +110,7 @@ must be on one of your app's return origins.
|
|
|
110
110
|
|
|
111
111
|
For prepaid credits, a fixed pack is another product/price. A
|
|
112
112
|
`customer_amount` price takes the buyer's `amount`: collect it on your product
|
|
113
|
-
page, and the
|
|
113
|
+
page, and the purchase charges exactly that:
|
|
114
114
|
|
|
115
115
|
```tsx
|
|
116
116
|
import { decimalToAmount } from "@openrails/billing-ui/client"
|
|
@@ -140,11 +140,14 @@ A server that decides what its customer buys creates the order with the Go
|
|
|
140
140
|
customer's browser, which pays it signed in:
|
|
141
141
|
|
|
142
142
|
```tsx
|
|
143
|
-
<
|
|
143
|
+
<OrderPayment orderId={orderId} returnUrl={returnUrl} onSettled={(order) => refetchAccess(order)} />
|
|
144
144
|
```
|
|
145
145
|
|
|
146
146
|
`onSettled` follows a complete order, or one processing on an asynchronous
|
|
147
|
-
rail. A subscription line names its subscription once paid.
|
|
147
|
+
rail. A subscription line names its subscription once paid. A fallback PSP
|
|
148
|
+
the order lists (CCBill once the card PSP has failed or is unavailable) is
|
|
149
|
+
offered under "Card payment isn't working?"; a customer back from a PSP's
|
|
150
|
+
page before it reported is offered to continue there.
|
|
148
151
|
|
|
149
152
|
## Account billing
|
|
150
153
|
|
|
@@ -182,6 +185,21 @@ deployment's (`GET /config`), whose currency registry amounts use over the
|
|
|
182
185
|
pinned copy. `useCustomerConfig()`, `useConfig()` and `useCurrencyScales()`
|
|
183
186
|
read the same copies for host components.
|
|
184
187
|
|
|
188
|
+
A page your server renders can carry both documents in its own response, so
|
|
189
|
+
the page loads from that one response: `config` in `GET /config`'s shape (Go:
|
|
190
|
+
`engine.PublicConfig(routes)` with the `Routes` you mount, or a remote client's
|
|
191
|
+
`GetPublicConfig`) and `customerConfig` in `GET /me/config`'s (Go:
|
|
192
|
+
`engine.CustomerConfig(routes, r)`, `r` your own signed-in request). billing-ui
|
|
193
|
+
then does not request them to load; a retry still reads the server's copy:
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
<BillingProvider
|
|
197
|
+
client={billing}
|
|
198
|
+
config={page.billingConfig}
|
|
199
|
+
customerConfig={page.customerBillingConfig}
|
|
200
|
+
>
|
|
201
|
+
```
|
|
202
|
+
|
|
185
203
|
## Staff administration
|
|
186
204
|
|
|
187
205
|
Install the admin entry's optional peer with `pnpm add @tanstack/react-query`.
|
|
@@ -261,14 +279,14 @@ provider:
|
|
|
261
279
|
|
|
262
280
|
- An order's `payment_options` are exactly the armed PSPs whose rail can make
|
|
263
281
|
this sale (Solana for one-time lines when it is configured, never CCBill),
|
|
264
|
-
each with what it `accepts`. `
|
|
282
|
+
each with what it `accepts`. `OrderPayment` renders one panel: the
|
|
265
283
|
customer's saved cards on them, newest first, an inline new card and one Pay
|
|
266
284
|
button. No provider chooser with one rail.
|
|
267
285
|
- A new card is charged and saved in one pay; an `authenticate` next action
|
|
268
286
|
runs 3-D Secure in the page, then `confirm`. A decline stays on the panel
|
|
269
287
|
with its message, so the buyer can pick another card under a new
|
|
270
288
|
idempotency key.
|
|
271
|
-
- Only PSPs with `
|
|
289
|
+
- Only PSPs with `routed !== false` (`routedPsps`) take new cards; others
|
|
272
290
|
stay listed so existing cards and subscriptions keep working.
|
|
273
291
|
- `<SavePaymentMethod psp={psp} onSaved={(id) => ...} />` saves a card in the
|
|
274
292
|
page (needs `BillingProvider`); `canSavePaymentMethod(psp)` filters PSPs
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BillingAppearance } from '../appearance';
|
|
2
2
|
import { SendSolanaTransaction } from '../client/client';
|
|
3
3
|
import { SubscriptionsPanelProps } from './subscriptions-panel';
|
|
4
4
|
export interface AccountBillingProps {
|
|
@@ -13,7 +13,7 @@ export interface AccountBillingProps {
|
|
|
13
13
|
plansHref?: string;
|
|
14
14
|
renderSubscriptionFooter?: SubscriptionsPanelProps["renderSubscriptionFooter"];
|
|
15
15
|
historyPageSize?: number;
|
|
16
|
-
appearance?:
|
|
16
|
+
appearance?: BillingAppearance;
|
|
17
17
|
className?: string;
|
|
18
18
|
}
|
|
19
19
|
/** Subscriptions, payment methods and history in one column. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BillingAppearance } from '../appearance';
|
|
2
2
|
import { BillingError } from '../client/errors';
|
|
3
3
|
import { SubscriptionAction } from '../react/hooks';
|
|
4
4
|
import * as React from "react";
|
|
@@ -13,6 +13,6 @@ export interface CancelSubscriptionDialogProps {
|
|
|
13
13
|
pending?: SubscriptionAction;
|
|
14
14
|
/** Resolves null on success; the dialog then closes. */
|
|
15
15
|
onConfirm: (reason: string) => Promise<BillingError | null>;
|
|
16
|
-
appearance?:
|
|
16
|
+
appearance?: BillingAppearance;
|
|
17
17
|
}
|
|
18
18
|
export declare function CancelSubscriptionDialog({ open, onOpenChange, name, onChain, pending, onConfirm, appearance, }: CancelSubscriptionDialogProps): React.JSX.Element;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BillingAppearance } from '../appearance';
|
|
2
2
|
import { BillingError } from '../client/errors';
|
|
3
3
|
import { Subscription } from '../client/types';
|
|
4
4
|
import * as React from "react";
|
|
@@ -12,6 +12,6 @@ export interface ChangeCardDialogProps {
|
|
|
12
12
|
* null on success; the dialog then closes.
|
|
13
13
|
*/
|
|
14
14
|
onConfirm: (paymentMethodId: string | null) => Promise<BillingError | null>;
|
|
15
|
-
appearance?:
|
|
15
|
+
appearance?: BillingAppearance;
|
|
16
16
|
}
|
|
17
17
|
export declare function ChangeCardDialog({ subscription, name, onOpenChange, pending, onConfirm, appearance, }: ChangeCardDialogProps): React.JSX.Element;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BillingAppearance } from '../appearance';
|
|
2
2
|
import { PaymentsOptions } from '../react/hooks';
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
export interface PaymentHistoryProps extends PaymentsOptions {
|
|
5
|
-
appearance?:
|
|
5
|
+
appearance?: BillingAppearance;
|
|
6
6
|
className?: string;
|
|
7
7
|
}
|
|
8
8
|
export declare function PaymentHistory({ appearance, className, ...options }: PaymentHistoryProps): React.JSX.Element;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BillingAppearance } from '../appearance';
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
export interface PaymentMethodsPanelProps {
|
|
4
4
|
/**
|
|
@@ -8,7 +8,7 @@ export interface PaymentMethodsPanelProps {
|
|
|
8
8
|
defaultCurrency?: string;
|
|
9
9
|
/** Billing country to preselect when adding a card. */
|
|
10
10
|
defaultCountry?: string;
|
|
11
|
-
appearance?:
|
|
11
|
+
appearance?: BillingAppearance;
|
|
12
12
|
className?: string;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BillingAppearance } from '../appearance';
|
|
2
2
|
import { BillingError } from '../client/errors';
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
export interface SectionProps {
|
|
5
5
|
title: string;
|
|
6
6
|
description?: string;
|
|
7
7
|
action?: React.ReactNode;
|
|
8
|
-
appearance?:
|
|
8
|
+
appearance?: BillingAppearance;
|
|
9
9
|
className?: string;
|
|
10
10
|
children?: React.ReactNode;
|
|
11
11
|
"data-testid"?: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BillingAppearance } from '../appearance';
|
|
2
2
|
import { SendSolanaTransaction } from '../client/client';
|
|
3
3
|
import { Subscription } from '../client/types';
|
|
4
4
|
import { SubscriptionsOptions } from '../react/hooks';
|
|
@@ -13,7 +13,7 @@ export interface SubscriptionsPanelProps extends SubscriptionsOptions {
|
|
|
13
13
|
plansHref?: string;
|
|
14
14
|
/** Host content under a row, e.g. a plan-change control. */
|
|
15
15
|
renderSubscriptionFooter?: (subscription: Subscription) => React.ReactNode;
|
|
16
|
-
appearance?:
|
|
16
|
+
appearance?: BillingAppearance;
|
|
17
17
|
className?: string;
|
|
18
18
|
}
|
|
19
19
|
export declare function SubscriptionsPanel({ sendSolanaTransaction, plansHref, renderSubscriptionFooter, appearance, className, ...options }: SubscriptionsPanelProps): React.JSX.Element;
|
package/dist/admin/context.d.ts
CHANGED
|
@@ -428,7 +428,7 @@ export declare function createAdminServices(options: AdminClientOptions): {
|
|
|
428
428
|
limit: number;
|
|
429
429
|
cursor: string | undefined;
|
|
430
430
|
})[], import('./lib/api/credit-types').ListPage<import('./lib/api/types').Finding>, Error>;
|
|
431
|
-
|
|
431
|
+
pspRouting: (priceId: string) => import('@tanstack/react-query').OmitKeyof<import('@tanstack/react-query').UseQueryOptions<import('./lib/api/types').PSPRoutingPreview, Error, import('./lib/api/types').PSPRoutingPreview, string[]>, "queryFn"> & {
|
|
432
432
|
queryFn?: import('@tanstack/react-query').QueryFunction<import('./lib/api/types').PSPRoutingPreview, string[], never> | undefined;
|
|
433
433
|
} & import('@tanstack/react-query').QueryKeyWithDataTag<string[], import('./lib/api/types').PSPRoutingPreview, Error>;
|
|
434
434
|
usageMeters: (limit?: number, cursor?: string) => import('@tanstack/react-query').OmitKeyof<import('@tanstack/react-query').UseQueryOptions<import('./lib/api/credit-types').ListPage<import('../client/generated/wire').Meter>, Error, import('./lib/api/credit-types').ListPage<import('../client/generated/wire').Meter>, (string | {
|
|
@@ -1028,7 +1028,7 @@ export declare const useAdminServices: () => {
|
|
|
1028
1028
|
limit: number;
|
|
1029
1029
|
cursor: string | undefined;
|
|
1030
1030
|
})[], import('./lib/api/credit-types').ListPage<import('./lib/api/types').Finding>, Error>;
|
|
1031
|
-
|
|
1031
|
+
pspRouting: (priceId: string) => import('@tanstack/react-query').OmitKeyof<import('@tanstack/react-query').UseQueryOptions<import('./lib/api/types').PSPRoutingPreview, Error, import('./lib/api/types').PSPRoutingPreview, string[]>, "queryFn"> & {
|
|
1032
1032
|
queryFn?: import('@tanstack/react-query').QueryFunction<import('./lib/api/types').PSPRoutingPreview, string[], never> | undefined;
|
|
1033
1033
|
} & import('@tanstack/react-query').QueryKeyWithDataTag<string[], import('./lib/api/types').PSPRoutingPreview, Error>;
|
|
1034
1034
|
usageMeters: (limit?: number, cursor?: string) => import('@tanstack/react-query').OmitKeyof<import('@tanstack/react-query').UseQueryOptions<import('./lib/api/credit-types').ListPage<import('../client/generated/wire').Meter>, Error, import('./lib/api/credit-types').ListPage<import('../client/generated/wire').Meter>, (string | {
|
|
@@ -301,7 +301,7 @@ export declare function createQueries(client: AdminClient, api: AdminAPI): {
|
|
|
301
301
|
limit: number;
|
|
302
302
|
cursor: string | undefined;
|
|
303
303
|
})[], ListPage<import('./api/types').Finding>, Error>;
|
|
304
|
-
|
|
304
|
+
pspRouting: (priceId: string) => import('@tanstack/react-query').OmitKeyof<import('@tanstack/react-query').UseQueryOptions<import('./api/types').PSPRoutingPreview, Error, import('./api/types').PSPRoutingPreview, string[]>, "queryFn"> & {
|
|
305
305
|
queryFn?: import('@tanstack/react-query').QueryFunction<import('./api/types').PSPRoutingPreview, string[], never> | undefined;
|
|
306
306
|
} & import('@tanstack/react-query').QueryKeyWithDataTag<string[], import('./api/types').PSPRoutingPreview, Error>;
|
|
307
307
|
usageMeters: (limit?: number, cursor?: string) => import('@tanstack/react-query').OmitKeyof<import('@tanstack/react-query').UseQueryOptions<ListPage<import('../../client/generated/wire').Meter>, Error, ListPage<import('../../client/generated/wire').Meter>, (string | {
|
package/dist/admin/messages.d.ts
CHANGED
|
@@ -323,11 +323,11 @@ export declare const billingAdminMessages: {
|
|
|
323
323
|
readonly "New batch": "New batch";
|
|
324
324
|
readonly "New cards by AVS result": "New cards by AVS result";
|
|
325
325
|
readonly "New cards by CVV result": "New cards by CVV result";
|
|
326
|
-
readonly "New
|
|
326
|
+
readonly "New purchase on this rail is refused until another PSP is armed. Existing subscriptions, refunds and webhooks keep using this one.": "New purchase on this rail is refused until another PSP is armed. Existing subscriptions, refunds and webhooks keep using this one.";
|
|
327
327
|
readonly "New merchant": "New merchant";
|
|
328
328
|
readonly "New plan": "New plan";
|
|
329
329
|
readonly "New price": "New price";
|
|
330
|
-
readonly "New-card
|
|
330
|
+
readonly "New-card purchase failure rate": "New-card purchase failure rate";
|
|
331
331
|
readonly "New-card decline rate": "New-card decline rate";
|
|
332
332
|
readonly "New-card decline rate by week": "New-card decline rate by week";
|
|
333
333
|
readonly Next: "Next";
|
|
@@ -619,7 +619,7 @@ export declare const billingAdminMessages: {
|
|
|
619
619
|
readonly "Webhook URL": "Webhook URL";
|
|
620
620
|
readonly Webhooks: "Webhooks";
|
|
621
621
|
readonly "What the customer asked for": "What the customer asked for";
|
|
622
|
-
readonly "Which provider would take the money if someone bought this right now, and why the others were passed over. This asks the same question a real
|
|
622
|
+
readonly "Which provider would take the money if someone bought this right now, and why the others were passed over. This asks the same question a real purchase asks, without starting one.": "Which provider would take the money if someone bought this right now, and why the others were passed over. This asks the same question a real purchase asks, without starting one.";
|
|
623
623
|
readonly "Which providers this price has been sent to, and whether their copy still matches yours. Publishing the catalog is what sends it; this page only reports. Verify asks each provider what it currently holds, and changes nothing.": "Which providers this price has been sent to, and whether their copy still matches yours. Publishing the catalog is what sends it; this page only reports. Verify asks each provider what it currently holds, and changes nothing.";
|
|
624
624
|
readonly Why: "Why";
|
|
625
625
|
readonly "Why it was granted": "Why it was granted";
|
|
@@ -5,6 +5,6 @@ export declare function PSPLinksCard({ price, verifying, verified, onVerify, }:
|
|
|
5
5
|
verified: boolean;
|
|
6
6
|
onVerify: () => void;
|
|
7
7
|
}): import("react").JSX.Element;
|
|
8
|
-
export declare function
|
|
8
|
+
export declare function PSPReadinessCard({ price }: {
|
|
9
9
|
price: Price;
|
|
10
10
|
}): import("react").JSX.Element;
|
package/dist/admin/theme.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function useAdminTheme(theme?:
|
|
1
|
+
import { BillingTheme } from '../appearance';
|
|
2
|
+
export declare function useAdminTheme(theme?: BillingTheme): "inherit" | "light" | "dark";
|
package/dist/admin/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CSSProperties, ReactNode } from 'react';
|
|
2
2
|
import { QueryClient } from '@tanstack/react-query';
|
|
3
|
-
import {
|
|
3
|
+
import { BillingAppearance } from '../appearance';
|
|
4
4
|
import { Customer } from '../client/generated/wire';
|
|
5
5
|
/** The host's authenticated transport. Tokens remain with the host. */
|
|
6
6
|
export interface BillingAdminAuth {
|
|
@@ -47,7 +47,7 @@ export interface BillingAdminProps {
|
|
|
47
47
|
userHref?: (id: string) => string;
|
|
48
48
|
newMerchantHref?: string;
|
|
49
49
|
emptyState?: ReactNode;
|
|
50
|
-
appearance?:
|
|
50
|
+
appearance?: BillingAppearance;
|
|
51
51
|
className?: string;
|
|
52
52
|
style?: CSSProperties;
|
|
53
53
|
queryClient?: QueryClient;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { E as e, c as t, l as n, p as r, r as i, s as a, v as o, w as s, x as c, y as l } from "./admin-utils-
|
|
2
|
-
import { t as u } from "./admin-button-
|
|
1
|
+
import { E as e, c as t, l as n, p as r, r as i, s as a, v as o, w as s, x as c, y as l } from "./admin-utils-DnVY5fYd.js";
|
|
2
|
+
import { t as u } from "./admin-button-Oip73Plq.js";
|
|
3
3
|
import { i as d, o as f, s as p, u as m } from "./admin-format-DoohJ7Fg.js";
|
|
4
|
-
import { i as h, n as g } from "./admin-dom-
|
|
5
|
-
import { t as _ } from "./admin-status-badge-
|
|
6
|
-
import { a as v, o as y, r as b, t as x } from "./admin-card-
|
|
7
|
-
import { t as S } from "./admin-fact-card-
|
|
8
|
-
import { t as C } from "./admin-data-table-
|
|
4
|
+
import { i as h, n as g } from "./admin-dom-lnNSQ7ke.js";
|
|
5
|
+
import { t as _ } from "./admin-status-badge-CwqIU8tK.js";
|
|
6
|
+
import { a as v, o as y, r as b, t as x } from "./admin-card-DGbi6ZHZ.js";
|
|
7
|
+
import { t as S } from "./admin-fact-card-D6mZgxpN.js";
|
|
8
|
+
import { t as C } from "./admin-data-table-CgeWv__T.js";
|
|
9
9
|
import { useQuery as w } from "@tanstack/react-query";
|
|
10
10
|
import { jsx as T, jsxs as E } from "react/jsx-runtime";
|
|
11
11
|
import { HugeiconsIcon as D } from "@hugeicons/react";
|
|
@@ -416,4 +416,4 @@ function z() {
|
|
|
416
416
|
//#endregion
|
|
417
417
|
export { I as AttemptDetailPage, N as AttemptsPage, z as CycleDetailPage, R as CyclesPage };
|
|
418
418
|
|
|
419
|
-
//# sourceMappingURL=admin-attempts-
|
|
419
|
+
//# sourceMappingURL=admin-attempts-DxRHTODq.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-attempts-lAoW-Urd.js","names":[],"sources":["../src/admin/pages/payments/attempts.tsx"],"sourcesContent":["import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useAdminServices } from \"#orck/admin/context\"\n// Payments → Attempts and Renewals (#1117): the #1116 lists and details.\n// A list's filters are its URL's query parameters, as the API names them, so\n// the health page links straight into a filtered list.\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { ArrowLeft01Icon, Cancel01Icon } from \"@hugeicons/core-free-icons\"\nimport {\n Link,\n useNavigate,\n useParams,\n useSearchParams,\n} from \"#orck/admin/router\"\nimport { useQuery } from \"@tanstack/react-query\"\nimport type { ColumnDef } from \"@tanstack/react-table\"\n\nimport { CursorPager } from \"#orck/admin/components/cursor-pager\"\nimport { DataTable } from \"#orck/admin/components/data-table\"\nimport { Fact } from \"#orck/admin/components/fact-card\"\nimport { StatusBadge } from \"#orck/admin/components/status-badge\"\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n} from \"#orck/admin/components/ui/card\"\nimport {\n ATTEMPT_FILTERS,\n CYCLE_FILTERS,\n filtersFrom,\n type AttemptFilters,\n type CycleFilters,\n} from \"#orck/admin/lib/api/endpoints\"\nimport type { PaymentAttempt, Renewal } from \"#orck/client/generated/wire\"\nimport { useUrlCursor } from \"#orck/admin/lib/cursor-pages\"\nimport {\n formatCard,\n formatDate,\n formatNativeAmount,\n shortId,\n} from \"#orck/admin/lib/format\"\n\nexport function Outcome({ category }: { category: string }) {\n return (\n <StatusBadge status={category === \"approved\" ? \"approved\" : \"declined\"} />\n )\n}\n\nconst attemptColumns: ColumnDef<PaymentAttempt, unknown>[] = [\n {\n header: \"Attempted\",\n cell: ({ row }) => (\n <span className=\"text-muted-foreground tabular-nums\">\n {formatDate(row.original.attempted_at)}\n </span>\n ),\n },\n { header: \"Kind\", cell: ({ row }) => row.original.kind },\n {\n header: \"Outcome\",\n cell: ({ row }) => <Outcome category={row.original.category} />,\n },\n {\n header: \"Reason\",\n cell: ({ row }) =>\n row.original.category === \"approved\" ? (\n <span className=\"text-muted-foreground\">—</span>\n ) : (\n <span>\n {row.original.reason || row.original.category}\n {row.original.response_code ? (\n <span className=\"ml-1 font-mono text-xs text-muted-foreground\">\n {row.original.response_code}\n </span>\n ) : null}\n </span>\n ),\n },\n { header: \"Owner\", cell: ({ row }) => row.original.owner },\n { header: \"Card\", cell: ({ row }) => formatCard(row.original.card) },\n {\n header: \"Amount\",\n cell: ({ row }) =>\n row.original.currency ? (\n <span className=\"tabular-nums\">\n {formatNativeAmount(row.original.amount, row.original.currency)}\n </span>\n ) : (\n <span className=\"text-muted-foreground\">—</span>\n ),\n },\n { header: \"Rail\", cell: ({ row }) => row.original.rail },\n]\n\nfunction FilterChips({ keys }: { keys: readonly string[] }) {\n const [params, setParams] = useSearchParams()\n const active = keys.filter((k) => params.get(k))\n if (active.length === 0) return null\n const drop = (key?: string) => {\n const p = new URLSearchParams(params)\n for (const k of key ? [key] : active) p.delete(k)\n p.delete(\"cursor\")\n setParams(p)\n }\n return (\n <div className=\"flex flex-wrap items-center gap-2 text-sm\">\n {active.map((k) => (\n <span\n key={k}\n className=\"inline-flex items-center gap-1 rounded-md bg-muted py-0.5 pr-1 pl-2\"\n >\n <span className=\"text-muted-foreground\">{k}</span>\n <span className=\"font-medium\">{params.get(k)}</span>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-5\"\n aria-label={`Clear ${k}`}\n onClick={() => drop(k)}\n >\n <HugeiconsIcon icon={Cancel01Icon} className=\"size-3\" />\n </Button>\n </span>\n ))}\n <Button variant=\"ghost\" size=\"sm\" onClick={() => drop()}>\n <AdminMessage id={\"Clear all\"} />\n </Button>\n </div>\n )\n}\n\nexport function AttemptsPage() {\n const { adminQueries } = useAdminServices()\n\n const [params] = useSearchParams()\n const paging = useUrlCursor()\n const navigate = useNavigate()\n const filters: AttemptFilters = filtersFrom(params, ATTEMPT_FILTERS)\n const { data, isPending, isFetching } = useQuery(\n adminQueries.attempts(filters, paging.size, paging.cursor)\n )\n return (\n <div className=\"flex flex-col gap-4\">\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <AdminMessage id={\"Payment attempts\"} />\n </h1>\n <FilterChips keys={ATTEMPT_FILTERS} />\n <DataTable\n columns={attemptColumns}\n data={data?.data ?? []}\n loading={isPending}\n onRowClick={(row) => navigate(`/payments/attempts/${row.id}`)}\n emptyMessage=\"No attempts match.\"\n />\n <CursorPager\n pages={paging}\n rows={data?.data?.length ?? 0}\n nextCursor={data?.next_cursor}\n busy={isFetching}\n />\n </div>\n )\n}\n\nfunction Back() {\n const { text: adminText } = useAdminUI()\n\n const navigate = useNavigate()\n return (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => navigate(-1)}\n aria-label={adminText(\"Back\")}\n >\n <HugeiconsIcon icon={ArrowLeft01Icon} className=\"size-4\" />\n </Button>\n )\n}\n\nfunction To({ to, children }: { to: string; children: string }) {\n return (\n <Link className=\"text-xs underline-offset-2 hover:underline\" to={to}>\n {children}\n </Link>\n )\n}\n\nexport function AttemptDetailPage() {\n const { text: adminText } = useAdminUI()\n\n const { adminQueries } = useAdminServices()\n\n const { id = \"\" } = useParams()\n const { data: a, isPending } = useQuery(adminQueries.attempt(id))\n if (isPending)\n return (\n <p className=\"text-sm text-muted-foreground\">\n <AdminMessage id={\"Loading…\"} />\n </p>\n )\n if (!a)\n return (\n <p className=\"text-sm text-muted-foreground\">\n <AdminMessage id={\"Attempt not found.\"} />\n </p>\n )\n const answer = [\n [\"Response\", [a.response_code, a.response_text].filter(Boolean).join(\" \")],\n [\"Issuer\", [a.issuer_code, a.issuer_text].filter(Boolean).join(\" \")],\n [\"AVS\", a.avs_result],\n [\"CVV\", a.cvv_result],\n [\"Action\", a.action],\n [\"Token\", a.token_type],\n [\"BIN\", a.card_bin],\n [\"Transaction\", a.transaction_id],\n [\"Observed via\", `${a.source} · ${a.observed_via}`],\n [\"Enriched\", a.enriched_at ? formatDate(a.enriched_at) : \"\"],\n ] as const\n return (\n <div className=\"flex flex-col gap-4\">\n <div className=\"flex items-center gap-3\">\n <Back />\n <div>\n <h2 className=\"flex items-center gap-2 text-sm\">\n {a.id} <Outcome category={a.category} />\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {a.kind} · {a.owner} · {a.rail} · {formatDate(a.attempted_at)}\n </p>\n </div>\n </div>\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n <Fact label={adminText(\"Outcome\")}>\n {a.category === \"approved\"\n ? \"approved\"\n : `${a.category}${a.reason ? ` · ${a.reason}` : \"\"}`}\n </Fact>\n <Fact label={adminText(\"Amount\")}>\n {a.currency ? formatNativeAmount(a.amount, a.currency) : \"—\"}\n </Fact>\n <Fact label={adminText(\"Card\")}>\n {formatCard(a.card)} ({a.card_entry})\n </Fact>\n <Fact label={adminText(\"Customer\")}>\n <To to={`/customers/${a.customer_id}`}>\n {shortId(a.customer_id, 16)}\n </To>\n </Fact>\n <Fact label={adminText(\"Subscription\")}>\n {a.subscription_id ? (\n <To to={`/subscriptions/${a.subscription_id}`}>\n {shortId(a.subscription_id, 16)}\n </To>\n ) : (\n \"—\"\n )}\n </Fact>\n <Fact label={adminText(\"Renewal\")}>\n {a.cycle_id ? (\n <To to={`/payments/cycles/${a.cycle_id}`}>\n {shortId(a.cycle_id, 16)}\n </To>\n ) : (\n \"—\"\n )}\n </Fact>\n <Fact label={adminText(\"Payment\")}>\n {a.payment_id ? (\n <To to={`/payments/${a.payment_id}`}>\n {shortId(a.payment_id, 16)}\n </To>\n ) : (\n \"—\"\n )}\n </Fact>\n <Fact label={adminText(\"Paying\")}>\n {a.order_id ? (\n <To to={`/orders/${a.order_id}`}>{shortId(a.order_id, 16)}</To>\n ) : (\n \"—\"\n )}\n </Fact>\n </div>\n <Card>\n <CardHeader>\n <CardTitle className=\"text-sm\">\n <AdminMessage id={\"PSP answer\"} />\n </CardTitle>\n </CardHeader>\n <CardContent>\n <dl className=\"grid gap-x-6 gap-y-2 text-sm sm:grid-cols-2\">\n {answer.map(([label, value]) => (\n <div key={label} className=\"flex gap-2\">\n <dt className=\"w-28 shrink-0 text-muted-foreground\">{label}</dt>\n <dd className=\"font-mono text-xs break-all\">{value || \"—\"}</dd>\n </div>\n ))}\n </dl>\n </CardContent>\n </Card>\n </div>\n )\n}\n\n// --- renewals ----------------------------------------------------------------------\n\nconst cycleColumns: ColumnDef<Renewal, unknown>[] = [\n {\n header: \"Due\",\n cell: ({ row }) => (\n <span className=\"text-muted-foreground tabular-nums\">\n {formatDate(row.original.due_at)}\n </span>\n ),\n },\n { header: \"Owner\", cell: ({ row }) => row.original.owner },\n {\n header: \"First outcome\",\n cell: ({ row }) =>\n row.original.miss_reason\n ? `missed · ${row.original.miss_reason}`\n : row.original.first_outcome,\n },\n {\n header: \"Outcome\",\n cell: ({ row }) => <StatusBadge status={row.original.outcome} />,\n },\n {\n header: \"Recovered by\",\n cell: ({ row }) => row.original.recovered_by || \"—\",\n },\n {\n header: \"Amount\",\n cell: ({ row }) => (\n <span className=\"tabular-nums\">\n {formatNativeAmount(row.original.amount, row.original.currency)}\n </span>\n ),\n },\n { header: \"Rail\", cell: ({ row }) => row.original.rail },\n]\n\nexport function CyclesPage() {\n const { adminQueries } = useAdminServices()\n\n const [params] = useSearchParams()\n const paging = useUrlCursor()\n const navigate = useNavigate()\n const filters: CycleFilters = filtersFrom(params, CYCLE_FILTERS)\n const { data, isPending, isFetching } = useQuery(\n adminQueries.cycles(filters, paging.size, paging.cursor)\n )\n return (\n <div className=\"flex flex-col gap-4\">\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <AdminMessage id={\"Renewals\"} />\n </h1>\n <FilterChips keys={CYCLE_FILTERS} />\n <DataTable\n columns={cycleColumns}\n data={data?.data ?? []}\n loading={isPending}\n onRowClick={(row) => navigate(`/payments/cycles/${row.id}`)}\n emptyMessage=\"No renewals match.\"\n />\n <CursorPager\n pages={paging}\n rows={data?.data?.length ?? 0}\n nextCursor={data?.next_cursor}\n busy={isFetching}\n />\n </div>\n )\n}\n\nexport function CycleDetailPage() {\n const { text: adminText } = useAdminUI()\n\n const { adminQueries } = useAdminServices()\n\n const { id = \"\" } = useParams()\n const navigate = useNavigate()\n const { data: c, isPending } = useQuery(adminQueries.cycle(id))\n if (isPending)\n return (\n <p className=\"text-sm text-muted-foreground\">\n <AdminMessage id={\"Loading…\"} />\n </p>\n )\n if (!c)\n return (\n <p className=\"text-sm text-muted-foreground\">\n <AdminMessage id={\"Renewal not found.\"} />\n </p>\n )\n return (\n <div className=\"flex flex-col gap-4\">\n <div className=\"flex items-center gap-3\">\n <Back />\n <div>\n <h2 className=\"flex items-center gap-2 text-sm\">\n {c.id} <StatusBadge status={c.outcome} />\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {c.owner} · {c.rail}\n <AdminMessage id={\" · due \"} />\n {formatDate(c.due_at)}\n </p>\n </div>\n </div>\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n <Fact label={adminText(\"Amount\")}>\n {formatNativeAmount(c.amount, c.currency)}\n </Fact>\n <Fact label={adminText(\"First outcome\")}>\n {c.miss_reason ? `missed · ${c.miss_reason}` : c.first_outcome}\n </Fact>\n <Fact label={adminText(\"Collected\")}>\n {c.collected_at\n ? `${formatDate(c.collected_at)}${c.recovered_by ? ` · ${c.recovered_by}` : \"\"}`\n : \"—\"}\n </Fact>\n <Fact label={c.outcome === \"open\" ? \"Closes\" : \"Closed\"}>\n {formatDate(c.closes_at)}\n </Fact>\n <Fact label={adminText(\"Subscription\")}>\n <To to={`/subscriptions/${c.subscription_id}`}>\n {shortId(c.subscription_id, 16)}\n </To>\n </Fact>\n <Fact label={adminText(\"Customer\")}>\n <To to={`/customers/${c.customer_id}`}>\n {shortId(c.customer_id, 16)}\n </To>\n </Fact>\n </div>\n <Card>\n <CardHeader>\n <CardTitle className=\"text-sm\">\n <AdminMessage id={\"Attempts\"} />\n </CardTitle>\n </CardHeader>\n <CardContent>\n <DataTable\n columns={attemptColumns}\n data={c.attempts ?? []}\n onRowClick={(row) => navigate(`/payments/attempts/${row.id}`)}\n emptyMessage={\n c.miss_reason ? \"Never attempted.\" : \"No attempts yet.\"\n }\n />\n </CardContent>\n </Card>\n </div>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"admin-attempts-DxRHTODq.js","names":[],"sources":["../src/admin/pages/payments/attempts.tsx"],"sourcesContent":["import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useAdminServices } from \"#orck/admin/context\"\n// Payments → Attempts and Renewals (#1117): the #1116 lists and details.\n// A list's filters are its URL's query parameters, as the API names them, so\n// the health page links straight into a filtered list.\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { ArrowLeft01Icon, Cancel01Icon } from \"@hugeicons/core-free-icons\"\nimport {\n Link,\n useNavigate,\n useParams,\n useSearchParams,\n} from \"#orck/admin/router\"\nimport { useQuery } from \"@tanstack/react-query\"\nimport type { ColumnDef } from \"@tanstack/react-table\"\n\nimport { CursorPager } from \"#orck/admin/components/cursor-pager\"\nimport { DataTable } from \"#orck/admin/components/data-table\"\nimport { Fact } from \"#orck/admin/components/fact-card\"\nimport { StatusBadge } from \"#orck/admin/components/status-badge\"\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n} from \"#orck/admin/components/ui/card\"\nimport {\n ATTEMPT_FILTERS,\n CYCLE_FILTERS,\n filtersFrom,\n type AttemptFilters,\n type CycleFilters,\n} from \"#orck/admin/lib/api/endpoints\"\nimport type { PaymentAttempt, Renewal } from \"#orck/client/generated/wire\"\nimport { useUrlCursor } from \"#orck/admin/lib/cursor-pages\"\nimport {\n formatCard,\n formatDate,\n formatNativeAmount,\n shortId,\n} from \"#orck/admin/lib/format\"\n\nexport function Outcome({ category }: { category: string }) {\n return (\n <StatusBadge status={category === \"approved\" ? \"approved\" : \"declined\"} />\n )\n}\n\nconst attemptColumns: ColumnDef<PaymentAttempt, unknown>[] = [\n {\n header: \"Attempted\",\n cell: ({ row }) => (\n <span className=\"text-muted-foreground tabular-nums\">\n {formatDate(row.original.attempted_at)}\n </span>\n ),\n },\n { header: \"Kind\", cell: ({ row }) => row.original.kind },\n {\n header: \"Outcome\",\n cell: ({ row }) => <Outcome category={row.original.category} />,\n },\n {\n header: \"Reason\",\n cell: ({ row }) =>\n row.original.category === \"approved\" ? (\n <span className=\"text-muted-foreground\">—</span>\n ) : (\n <span>\n {row.original.reason || row.original.category}\n {row.original.response_code ? (\n <span className=\"ml-1 font-mono text-xs text-muted-foreground\">\n {row.original.response_code}\n </span>\n ) : null}\n </span>\n ),\n },\n { header: \"Owner\", cell: ({ row }) => row.original.owner },\n { header: \"Card\", cell: ({ row }) => formatCard(row.original.card) },\n {\n header: \"Amount\",\n cell: ({ row }) =>\n row.original.currency ? (\n <span className=\"tabular-nums\">\n {formatNativeAmount(row.original.amount, row.original.currency)}\n </span>\n ) : (\n <span className=\"text-muted-foreground\">—</span>\n ),\n },\n { header: \"Rail\", cell: ({ row }) => row.original.rail },\n]\n\nfunction FilterChips({ keys }: { keys: readonly string[] }) {\n const [params, setParams] = useSearchParams()\n const active = keys.filter((k) => params.get(k))\n if (active.length === 0) return null\n const drop = (key?: string) => {\n const p = new URLSearchParams(params)\n for (const k of key ? [key] : active) p.delete(k)\n p.delete(\"cursor\")\n setParams(p)\n }\n return (\n <div className=\"flex flex-wrap items-center gap-2 text-sm\">\n {active.map((k) => (\n <span\n key={k}\n className=\"inline-flex items-center gap-1 rounded-md bg-muted py-0.5 pr-1 pl-2\"\n >\n <span className=\"text-muted-foreground\">{k}</span>\n <span className=\"font-medium\">{params.get(k)}</span>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-5\"\n aria-label={`Clear ${k}`}\n onClick={() => drop(k)}\n >\n <HugeiconsIcon icon={Cancel01Icon} className=\"size-3\" />\n </Button>\n </span>\n ))}\n <Button variant=\"ghost\" size=\"sm\" onClick={() => drop()}>\n <AdminMessage id={\"Clear all\"} />\n </Button>\n </div>\n )\n}\n\nexport function AttemptsPage() {\n const { adminQueries } = useAdminServices()\n\n const [params] = useSearchParams()\n const paging = useUrlCursor()\n const navigate = useNavigate()\n const filters: AttemptFilters = filtersFrom(params, ATTEMPT_FILTERS)\n const { data, isPending, isFetching } = useQuery(\n adminQueries.attempts(filters, paging.size, paging.cursor)\n )\n return (\n <div className=\"flex flex-col gap-4\">\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <AdminMessage id={\"Payment attempts\"} />\n </h1>\n <FilterChips keys={ATTEMPT_FILTERS} />\n <DataTable\n columns={attemptColumns}\n data={data?.data ?? []}\n loading={isPending}\n onRowClick={(row) => navigate(`/payments/attempts/${row.id}`)}\n emptyMessage=\"No attempts match.\"\n />\n <CursorPager\n pages={paging}\n rows={data?.data?.length ?? 0}\n nextCursor={data?.next_cursor}\n busy={isFetching}\n />\n </div>\n )\n}\n\nfunction Back() {\n const { text: adminText } = useAdminUI()\n\n const navigate = useNavigate()\n return (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => navigate(-1)}\n aria-label={adminText(\"Back\")}\n >\n <HugeiconsIcon icon={ArrowLeft01Icon} className=\"size-4\" />\n </Button>\n )\n}\n\nfunction To({ to, children }: { to: string; children: string }) {\n return (\n <Link className=\"text-xs underline-offset-2 hover:underline\" to={to}>\n {children}\n </Link>\n )\n}\n\nexport function AttemptDetailPage() {\n const { text: adminText } = useAdminUI()\n\n const { adminQueries } = useAdminServices()\n\n const { id = \"\" } = useParams()\n const { data: a, isPending } = useQuery(adminQueries.attempt(id))\n if (isPending)\n return (\n <p className=\"text-sm text-muted-foreground\">\n <AdminMessage id={\"Loading…\"} />\n </p>\n )\n if (!a)\n return (\n <p className=\"text-sm text-muted-foreground\">\n <AdminMessage id={\"Attempt not found.\"} />\n </p>\n )\n const answer = [\n [\"Response\", [a.response_code, a.response_text].filter(Boolean).join(\" \")],\n [\"Issuer\", [a.issuer_code, a.issuer_text].filter(Boolean).join(\" \")],\n [\"AVS\", a.avs_result],\n [\"CVV\", a.cvv_result],\n [\"Action\", a.action],\n [\"Token\", a.token_type],\n [\"BIN\", a.card_bin],\n [\"Transaction\", a.transaction_id],\n [\"Observed via\", `${a.source} · ${a.observed_via}`],\n [\"Enriched\", a.enriched_at ? formatDate(a.enriched_at) : \"\"],\n ] as const\n return (\n <div className=\"flex flex-col gap-4\">\n <div className=\"flex items-center gap-3\">\n <Back />\n <div>\n <h2 className=\"flex items-center gap-2 text-sm\">\n {a.id} <Outcome category={a.category} />\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {a.kind} · {a.owner} · {a.rail} · {formatDate(a.attempted_at)}\n </p>\n </div>\n </div>\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n <Fact label={adminText(\"Outcome\")}>\n {a.category === \"approved\"\n ? \"approved\"\n : `${a.category}${a.reason ? ` · ${a.reason}` : \"\"}`}\n </Fact>\n <Fact label={adminText(\"Amount\")}>\n {a.currency ? formatNativeAmount(a.amount, a.currency) : \"—\"}\n </Fact>\n <Fact label={adminText(\"Card\")}>\n {formatCard(a.card)} ({a.card_entry})\n </Fact>\n <Fact label={adminText(\"Customer\")}>\n <To to={`/customers/${a.customer_id}`}>\n {shortId(a.customer_id, 16)}\n </To>\n </Fact>\n <Fact label={adminText(\"Subscription\")}>\n {a.subscription_id ? (\n <To to={`/subscriptions/${a.subscription_id}`}>\n {shortId(a.subscription_id, 16)}\n </To>\n ) : (\n \"—\"\n )}\n </Fact>\n <Fact label={adminText(\"Renewal\")}>\n {a.cycle_id ? (\n <To to={`/payments/cycles/${a.cycle_id}`}>\n {shortId(a.cycle_id, 16)}\n </To>\n ) : (\n \"—\"\n )}\n </Fact>\n <Fact label={adminText(\"Payment\")}>\n {a.payment_id ? (\n <To to={`/payments/${a.payment_id}`}>\n {shortId(a.payment_id, 16)}\n </To>\n ) : (\n \"—\"\n )}\n </Fact>\n <Fact label={adminText(\"Paying\")}>\n {a.order_id ? (\n <To to={`/orders/${a.order_id}`}>{shortId(a.order_id, 16)}</To>\n ) : (\n \"—\"\n )}\n </Fact>\n </div>\n <Card>\n <CardHeader>\n <CardTitle className=\"text-sm\">\n <AdminMessage id={\"PSP answer\"} />\n </CardTitle>\n </CardHeader>\n <CardContent>\n <dl className=\"grid gap-x-6 gap-y-2 text-sm sm:grid-cols-2\">\n {answer.map(([label, value]) => (\n <div key={label} className=\"flex gap-2\">\n <dt className=\"w-28 shrink-0 text-muted-foreground\">{label}</dt>\n <dd className=\"font-mono text-xs break-all\">{value || \"—\"}</dd>\n </div>\n ))}\n </dl>\n </CardContent>\n </Card>\n </div>\n )\n}\n\n// --- renewals ----------------------------------------------------------------------\n\nconst cycleColumns: ColumnDef<Renewal, unknown>[] = [\n {\n header: \"Due\",\n cell: ({ row }) => (\n <span className=\"text-muted-foreground tabular-nums\">\n {formatDate(row.original.due_at)}\n </span>\n ),\n },\n { header: \"Owner\", cell: ({ row }) => row.original.owner },\n {\n header: \"First outcome\",\n cell: ({ row }) =>\n row.original.miss_reason\n ? `missed · ${row.original.miss_reason}`\n : row.original.first_outcome,\n },\n {\n header: \"Outcome\",\n cell: ({ row }) => <StatusBadge status={row.original.outcome} />,\n },\n {\n header: \"Recovered by\",\n cell: ({ row }) => row.original.recovered_by || \"—\",\n },\n {\n header: \"Amount\",\n cell: ({ row }) => (\n <span className=\"tabular-nums\">\n {formatNativeAmount(row.original.amount, row.original.currency)}\n </span>\n ),\n },\n { header: \"Rail\", cell: ({ row }) => row.original.rail },\n]\n\nexport function CyclesPage() {\n const { adminQueries } = useAdminServices()\n\n const [params] = useSearchParams()\n const paging = useUrlCursor()\n const navigate = useNavigate()\n const filters: CycleFilters = filtersFrom(params, CYCLE_FILTERS)\n const { data, isPending, isFetching } = useQuery(\n adminQueries.cycles(filters, paging.size, paging.cursor)\n )\n return (\n <div className=\"flex flex-col gap-4\">\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <AdminMessage id={\"Renewals\"} />\n </h1>\n <FilterChips keys={CYCLE_FILTERS} />\n <DataTable\n columns={cycleColumns}\n data={data?.data ?? []}\n loading={isPending}\n onRowClick={(row) => navigate(`/payments/cycles/${row.id}`)}\n emptyMessage=\"No renewals match.\"\n />\n <CursorPager\n pages={paging}\n rows={data?.data?.length ?? 0}\n nextCursor={data?.next_cursor}\n busy={isFetching}\n />\n </div>\n )\n}\n\nexport function CycleDetailPage() {\n const { text: adminText } = useAdminUI()\n\n const { adminQueries } = useAdminServices()\n\n const { id = \"\" } = useParams()\n const navigate = useNavigate()\n const { data: c, isPending } = useQuery(adminQueries.cycle(id))\n if (isPending)\n return (\n <p className=\"text-sm text-muted-foreground\">\n <AdminMessage id={\"Loading…\"} />\n </p>\n )\n if (!c)\n return (\n <p className=\"text-sm text-muted-foreground\">\n <AdminMessage id={\"Renewal not found.\"} />\n </p>\n )\n return (\n <div className=\"flex flex-col gap-4\">\n <div className=\"flex items-center gap-3\">\n <Back />\n <div>\n <h2 className=\"flex items-center gap-2 text-sm\">\n {c.id} <StatusBadge status={c.outcome} />\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {c.owner} · {c.rail}\n <AdminMessage id={\" · due \"} />\n {formatDate(c.due_at)}\n </p>\n </div>\n </div>\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n <Fact label={adminText(\"Amount\")}>\n {formatNativeAmount(c.amount, c.currency)}\n </Fact>\n <Fact label={adminText(\"First outcome\")}>\n {c.miss_reason ? `missed · ${c.miss_reason}` : c.first_outcome}\n </Fact>\n <Fact label={adminText(\"Collected\")}>\n {c.collected_at\n ? `${formatDate(c.collected_at)}${c.recovered_by ? ` · ${c.recovered_by}` : \"\"}`\n : \"—\"}\n </Fact>\n <Fact label={c.outcome === \"open\" ? \"Closes\" : \"Closed\"}>\n {formatDate(c.closes_at)}\n </Fact>\n <Fact label={adminText(\"Subscription\")}>\n <To to={`/subscriptions/${c.subscription_id}`}>\n {shortId(c.subscription_id, 16)}\n </To>\n </Fact>\n <Fact label={adminText(\"Customer\")}>\n <To to={`/customers/${c.customer_id}`}>\n {shortId(c.customer_id, 16)}\n </To>\n </Fact>\n </div>\n <Card>\n <CardHeader>\n <CardTitle className=\"text-sm\">\n <AdminMessage id={\"Attempts\"} />\n </CardTitle>\n </CardHeader>\n <CardContent>\n <DataTable\n columns={attemptColumns}\n data={c.attempts ?? []}\n onRowClick={(row) => navigate(`/payments/attempts/${row.id}`)}\n emptyMessage={\n c.miss_reason ? \"Never attempted.\" : \"No attempts yet.\"\n }\n />\n </CardContent>\n </Card>\n </div>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as e } from "./admin-utils-
|
|
1
|
+
import { f as e } from "./admin-utils-DnVY5fYd.js";
|
|
2
2
|
//#region src/admin/lib/auth.tsx
|
|
3
3
|
function t() {
|
|
4
4
|
let { merchants: t, activeMerchant: n, selectMerchant: r } = e();
|
|
@@ -11,4 +11,4 @@ function t() {
|
|
|
11
11
|
//#endregion
|
|
12
12
|
export { t };
|
|
13
13
|
|
|
14
|
-
//# sourceMappingURL=admin-auth-
|
|
14
|
+
//# sourceMappingURL=admin-auth-CiuZ-Hlm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-auth-
|
|
1
|
+
{"version":3,"file":"admin-auth-CiuZ-Hlm.js","names":[],"sources":["../src/admin/lib/auth.tsx"],"sourcesContent":["import { useAdminContext } from \"../context\"\n\n// BillingAdmin uses its host's session and merchant directory.\nexport function useAuth() {\n const { merchants, activeMerchant, selectMerchant } = useAdminContext()\n return { merchants, activeMerchant, selectMerchant }\n}\n\nexport function useSelectedMerchant() {\n return useAdminContext().activeMerchant?.slug\n}\n"],"mappings":";;AAGA,SAAgB,IAAU;CACxB,IAAM,EAAE,cAAW,mBAAgB,sBAAmB,EAAgB;CACtE,OAAO;EAAE;EAAW;EAAgB;CAAe;AACrD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "./admin-utils-
|
|
1
|
+
import { t as e } from "./admin-utils-DnVY5fYd.js";
|
|
2
2
|
import { mergeProps as t } from "@base-ui/react/merge-props";
|
|
3
3
|
import { useRender as n } from "@base-ui/react/use-render";
|
|
4
4
|
import { cva as r } from "class-variance-authority";
|
|
@@ -28,4 +28,4 @@ function a({ className: r, variant: a = "default", render: o, ...s }) {
|
|
|
28
28
|
//#endregion
|
|
29
29
|
export { a as t };
|
|
30
30
|
|
|
31
|
-
//# sourceMappingURL=admin-badge-
|
|
31
|
+
//# sourceMappingURL=admin-badge-VCGbnfiN.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-badge-
|
|
1
|
+
{"version":3,"file":"admin-badge-VCGbnfiN.js","names":[],"sources":["../src/admin/components/ui/badge.tsx"],"sourcesContent":["import { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"#orck/admin/lib/utils\"\n\nconst badgeVariants = cva(\n \"group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground [a]:hover:bg-primary/80\",\n secondary:\n \"bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80\",\n destructive:\n \"bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20\",\n outline:\n \"border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground\",\n ghost:\n \"hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction Badge({\n className,\n variant = \"default\",\n render,\n ...props\n}: useRender.ComponentProps<\"span\"> & VariantProps<typeof badgeVariants>) {\n return useRender({\n defaultTagName: \"span\",\n props: mergeProps<\"span\">(\n {\n className: cn(badgeVariants({ variant }), className),\n },\n props\n ),\n render,\n state: {\n slot: \"badge\",\n variant,\n },\n })\n}\n\nexport { Badge, badgeVariants }\n"],"mappings":";;;;;AAMA,IAAM,IAAgB,EACpB,8eACA;CACE,UAAU,EACR,SAAS;EACP,SAAS;EACT,WACE;EACF,aACE;EACF,SACE;EACF,OACE;EACF,MAAM;CACR,EACF;CACA,iBAAiB,EACf,SAAS,UACX;AACF,CACF;AAEA,SAAS,EAAM,EACb,cACA,aAAU,WACV,WACA,GAAG,KACqE;CACxE,OAAO,EAAU;EACf,gBAAgB;EAChB,OAAO,EACL,EACE,WAAW,EAAG,EAAc,EAAE,WAAQ,CAAC,GAAG,CAAS,EACrD,GACA,CACF;EACA;EACA,OAAO;GACL,MAAM;GACN;EACF;CACF,CAAC;AACH"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "./admin-utils-
|
|
1
|
+
import { t as e } from "./admin-utils-DnVY5fYd.js";
|
|
2
2
|
import { jsx as t } from "react/jsx-runtime";
|
|
3
3
|
import { cva as n } from "class-variance-authority";
|
|
4
4
|
import { Button as r } from "@base-ui/react/button";
|
|
@@ -43,4 +43,4 @@ function a({ className: n, variant: a = "default", size: o = "default", ...s })
|
|
|
43
43
|
//#endregion
|
|
44
44
|
export { a as t };
|
|
45
45
|
|
|
46
|
-
//# sourceMappingURL=admin-button-
|
|
46
|
+
//# sourceMappingURL=admin-button-Oip73Plq.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-button-
|
|
1
|
+
{"version":3,"file":"admin-button-Oip73Plq.js","names":[],"sources":["../src/admin/components/ui/button.tsx"],"sourcesContent":["import { Button as ButtonPrimitive } from \"@base-ui/react/button\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"#orck/admin/lib/utils\"\n\nconst buttonVariants = cva(\n \"group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/80\",\n outline:\n \"border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\n ghost:\n \"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50\",\n destructive:\n \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default:\n \"h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n xs: \"h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5\",\n lg: \"h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n icon: \"size-8\",\n \"icon-xs\":\n \"size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\":\n \"size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg\",\n \"icon-lg\": \"size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\n return (\n <ButtonPrimitive\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n"],"mappings":";;;;;AAKA,IAAM,IAAiB,EACrB,8lBACA;CACE,UAAU;EACR,SAAS;GACP,SAAS;GACT,SACE;GACF,WACE;GACF,OACE;GACF,aACE;GACF,MAAM;EACR;EACA,MAAM;GACJ,SACE;GACF,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,MAAM;GACN,WACE;GACF,WACE;GACF,WAAW;EACb;CACF;CACA,iBAAiB;EACf,SAAS;EACT,MAAM;CACR;AACF,CACF;AAEA,SAAS,EAAO,EACd,cACA,aAAU,WACV,UAAO,WACP,GAAG,KAC2D;CAC9D,OACE,kBAAC,GAAD;EACE,aAAU;EACV,WAAW,EAAG,EAAe;GAAE;GAAS;GAAM;EAAU,CAAC,CAAC;EAC1D,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { p as e } from "./admin-utils-
|
|
1
|
+
import { p as e } from "./admin-utils-DnVY5fYd.js";
|
|
2
2
|
import { useQuery as t } from "@tanstack/react-query";
|
|
3
3
|
//#region src/admin/lib/capabilities.ts
|
|
4
4
|
function n() {
|
|
@@ -56,4 +56,4 @@ function h(e, t, n, r = []) {
|
|
|
56
56
|
//#endregion
|
|
57
57
|
export { a, f as c, u as d, d as f, i, l, h as n, o, n as r, c as s, r as t, s as u };
|
|
58
58
|
|
|
59
|
-
//# sourceMappingURL=admin-capabilities-
|
|
59
|
+
//# sourceMappingURL=admin-capabilities-BGv7oG8v.js.map
|