@openrails/billing-ui 0.250.0 → 0.252.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.
Files changed (34) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +19 -1
  3. package/dist/admin/messages.d.ts +8 -0
  4. package/dist/{admin-catalog-3pPEAuDY.js → admin-catalog-Bsxo2gyS.js} +2 -2
  5. package/dist/{admin-catalog-3pPEAuDY.js.map → admin-catalog-Bsxo2gyS.js.map} +1 -1
  6. package/dist/{admin-price-detail-BeGDPxKX.js → admin-price-detail-ByCmrx_W.js} +2 -3
  7. package/dist/admin-price-detail-ByCmrx_W.js.map +1 -0
  8. package/dist/{admin-price-wizard-ferZSTfO.js → admin-price-wizard-m7Qjhq6W.js} +2 -2
  9. package/dist/admin-price-wizard-m7Qjhq6W.js.map +1 -0
  10. package/dist/{admin-settings-C6eWFkDn.js → admin-settings-BIUgvclv.js} +99 -17
  11. package/dist/admin-settings-BIUgvclv.js.map +1 -0
  12. package/dist/admin.js +13 -5
  13. package/dist/admin.js.map +1 -1
  14. package/dist/client/generated/error-codes.d.ts +1 -1
  15. package/dist/client/generated/routes.d.ts +4 -4
  16. package/dist/client/generated/wire.d.ts +7 -6
  17. package/dist/client/types.d.ts +6 -0
  18. package/dist/{client-HWr09qpX.js → client-imFR1UCe.js} +82 -81
  19. package/dist/client-imFR1UCe.js.map +1 -0
  20. package/dist/client.js +2 -2
  21. package/dist/hooks-C9JkHcRt.js +553 -0
  22. package/dist/hooks-C9JkHcRt.js.map +1 -0
  23. package/dist/index.js +778 -745
  24. package/dist/index.js.map +1 -1
  25. package/dist/react/config.d.ts +12 -3
  26. package/dist/react/provider.d.ts +14 -1
  27. package/dist/react.js +1 -1
  28. package/package.json +1 -2
  29. package/dist/admin-price-detail-BeGDPxKX.js.map +0 -1
  30. package/dist/admin-price-wizard-ferZSTfO.js.map +0 -1
  31. package/dist/admin-settings-C6eWFkDn.js.map +0 -1
  32. package/dist/client-HWr09qpX.js.map +0 -1
  33. package/dist/hooks-D9MR20BY.js +0 -537
  34. package/dist/hooks-D9MR20BY.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## A price's PSPs are one map
4
+
5
+ - Breaking: `CreatePriceParams.psps` and `UpdatePriceParams.psps` map each PSP
6
+ key to its settings for the price (`{}` for none; null unlinks in an
7
+ update); `psp_links` is gone. CCBill settings are `flex_id` and
8
+ `recurring_billing_option_id` (no `form_name`).
9
+ - `MerchantProfile.signup_url` is `subscribe_url`; the console's merchant
10
+ profile edits it and `billing_url`.
11
+
12
+ ## The host supplies the configuration
13
+
14
+ - `BillingProvider` takes `config` (`GET /config`'s document; Go:
15
+ `Engine.PublicConfig` or `Client.GetPublicConfig`) and `customerConfig`
16
+ (`GET /me/config`'s; Go: `Engine.CustomerConfig`) from the host's own page
17
+ response. Supplied, billing-ui does not request them to load; a retry still
18
+ reads the server's copy. `useConfig()`, `useCurrencyScales()` and
19
+ `useCustomerConfig()` read them.
20
+
21
+ ## Fallback PSPs
22
+
23
+ - `OrderPayment` offers a payment option marked `fallback` (CCBill once the
24
+ card PSP failed or is unavailable) under "Card payment isn't working?", and
25
+ a customer back from a PSP's page before it reported continues there.
26
+ `OrderPaymentOption` gains `fallback`.
27
+
3
28
  ## An order and its pay URL
4
29
 
5
30
  - Breaking: "checkout" is gone. `EmbeddedCheckout` is `EmbeddedPayment`,
package/README.md CHANGED
@@ -144,7 +144,10 @@ customer's browser, which pays it signed in:
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`.
@@ -97,6 +97,7 @@ export declare const billingAdminMessages: {
97
97
  readonly "Billing contacts": "Billing contacts";
98
98
  readonly "Billing interval": "Billing interval";
99
99
  readonly "Billing support": "Billing support";
100
+ readonly "Billing URL": "Billing URL";
100
101
  readonly "Can this be bought?": "Can this be bought?";
101
102
  readonly Cancel: "Cancel";
102
103
  readonly "Cancel subscription": "Cancel subscription";
@@ -432,6 +433,10 @@ export declare const billingAdminMessages: {
432
433
  readonly "Pick a product": "Pick a product";
433
434
  readonly "Pick a product\u2026": "Pick a product…";
434
435
  readonly "Pick a rail\u2026": "Pick a rail…";
436
+ readonly "Pick an environment\u2026": "Pick an environment…";
437
+ readonly "Live: real money": "Live: real money";
438
+ readonly "Test: the provider's own system, no money moves": "Test: the provider's own system, no money moves";
439
+ readonly "Sandbox: the provider's separate sandbox": "Sandbox: the provider's separate sandbox";
435
440
  readonly "Pick a stored payment method": "Pick a stored payment method";
436
441
  readonly "Pinned to an archived (prior) version": "Pinned to an archived (prior) version";
437
442
  readonly "Points future renewals of this subscription at another of the customer&apos;s stored cards (same rail), or back at their default card for its currency.": "Points future renewals of this subscription at another of the customer&apos;s stored cards (same rail), or back at their default card for its currency.";
@@ -556,6 +561,7 @@ export declare const billingAdminMessages: {
556
561
  readonly Subscriptions: "Subscriptions";
557
562
  readonly "Subscriptions started and canceled each day (UTC), newest first.": "Subscriptions started and canceled each day (UTC), newest first.";
558
563
  readonly "Sum a numeric field": "Sum a numeric field";
564
+ readonly "Subscribe URL": "Subscribe URL";
559
565
  readonly "Support URL": "Support URL";
560
566
  readonly Synced: "Synced";
561
567
  readonly "Take the product back": "Take the product back";
@@ -643,7 +649,9 @@ export declare const billingAdminMessages: {
643
649
  readonly "eu, us": "eu, us";
644
650
  readonly "gpt-5": "gpt-5";
645
651
  readonly "held ": "held ";
652
+ readonly "https://example.com/account": "https://example.com/account";
646
653
  readonly "https://example.com/logo.png": "https://example.com/logo.png";
654
+ readonly "https://example.com/subscribe": "https://example.com/subscribe";
647
655
  readonly "https://example.com/support": "https://example.com/support";
648
656
  readonly "key: ": "key: ";
649
657
  readonly "metadata.model": "metadata.model";
@@ -18,7 +18,7 @@ import { n as re, r as ie } from "./admin-dialog-width-BPrgdYlj.js";
18
18
  import { i as V, n as ae, r as oe, t as se } from "./admin-price-format-DM1qORWI.js";
19
19
  import { t as ce } from "./admin-textarea-DK1Fq31x.js";
20
20
  import { r as le, t as ue } from "./admin-card-DGbi6ZHZ.js";
21
- import { t as de } from "./admin-price-wizard-ferZSTfO.js";
21
+ import { t as de } from "./admin-price-wizard-m7Qjhq6W.js";
22
22
  import * as H from "react";
23
23
  import { useMutation as U, useQuery as W, useQueryClient as G } from "@tanstack/react-query";
24
24
  import { Fragment as fe, jsx as K, jsxs as q } from "react/jsx-runtime";
@@ -1196,4 +1196,4 @@ function $({ label: t, id: n, hint: r, children: i }) {
1196
1196
  //#endregion
1197
1197
  export { ke as CatalogDriftPage, Oe as CatalogPricesPage, De as CatalogProductsPage };
1198
1198
 
1199
- //# sourceMappingURL=admin-catalog-3pPEAuDY.js.map
1199
+ //# sourceMappingURL=admin-catalog-Bsxo2gyS.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin-catalog-3pPEAuDY.js","names":[],"sources":["../src/admin/pages/catalog/application-dialog.tsx","../src/admin/pages/catalog/copilot-panel.tsx","../src/admin/pages/catalog/index.tsx"],"sourcesContent":["import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useAdminServices } from \"#orck/admin/context\"\nimport * as React from \"react\"\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\"\n\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"#orck/admin/components/ui/dialog\"\nimport { Label } from \"#orck/admin/components/ui/label\"\nimport { Textarea } from \"#orck/admin/components/ui/textarea\"\nimport { ApiError } from \"#orck/admin/lib/api/client\"\nimport { type CatalogApplicationReceipt } from \"#orck/admin/lib/api/endpoints\"\nimport type {\n CatalogConflict,\n CatalogFieldConflict,\n} from \"#orck/client/generated/wire\"\nimport { DIALOG_WIDE } from \"#orck/admin/lib/dialog-width\"\nimport { formatHours } from \"#orck/admin/lib/duration\"\nimport { formatDate, formatNativeAmount } from \"#orck/admin/lib/format\"\n\nexport function CatalogApplicationDialog() {\n const { toast, toastApiError, selectedMerchant, adminMutations } =\n useAdminServices()\n\n const { id: adminId, text: adminText } = useAdminUI()\n\n const [open, setOpen] = React.useState(false)\n const [document, setDocument] = React.useState(\"\")\n const [reviewed, setReviewed] = React.useState(false)\n const [submitted, setSubmitted] = React.useState<string>()\n const [receipt, setReceipt] = React.useState<CatalogApplicationReceipt>()\n const [message, setMessage] = React.useState(\"\")\n const [canEdit, setCanEdit] = React.useState(false)\n const [draftMerchant, setDraftMerchant] = React.useState<string>()\n const apply = useMutation(adminMutations.applyCatalog(useQueryClient()))\n\n const start = () => {\n setDraftMerchant(selectedMerchant())\n setDocument(\n JSON.stringify(\n {\n schema_version: 1,\n prune: false,\n products: {},\n },\n null,\n 2\n )\n )\n setSubmitted(undefined)\n setReceipt(undefined)\n setReviewed(false)\n setCanEdit(false)\n setMessage(\"\")\n }\n\n const run = async (force = false) => {\n if (selectedMerchant() !== draftMerchant) {\n setMessage(\n \"This draft belongs to another selected merchant. Return to that merchant before applying it.\"\n )\n return\n }\n const exactDocument = submitted ?? document\n setSubmitted(exactDocument)\n setCanEdit(false)\n setMessage(\"\")\n try {\n const result = await apply.mutateAsync({ document: exactDocument, force })\n setReceipt(result)\n const skipped = result.conflicts?.length ?? 0\n setMessage(\n result.replayed\n ? \"This batch was already applied. No changes were repeated, and later catalog edits were preserved.\"\n : skipped > 0\n ? `Applied everything no edit changed. ${skipped} ${skipped === 1 ? \"object was\" : \"objects were\"} skipped because an edit set ${skipped === 1 ? \"its\" : \"their\"} fields differently: change the batch to agree, remove those fields, or overwrite the edits.`\n : \"Batch applied. Review the current catalog before preparing another batch.\"\n )\n if (skipped > 0) {\n toast.warning(`Catalog batch applied; ${skipped} skipped`)\n } else {\n toast.success(\n result.replayed\n ? \"Original batch receipt returned\"\n : \"Catalog batch applied\"\n )\n }\n } catch (err) {\n const refused =\n err instanceof ApiError &&\n err.status >= 400 &&\n err.status < 500 &&\n err.status !== 408\n setCanEdit(refused)\n setMessage(\n refused\n ? \"Batch refused. Review the error and edit the document before trying again.\"\n : \"The outcome could not be confirmed. Retry this exact document to retrieve its receipt without repeating changes.\"\n )\n toastApiError(err, \"Apply catalog\")\n }\n }\n\n return (\n <Dialog\n open={open}\n onOpenChange={(next) => {\n if (apply.isPending) return\n setOpen(next)\n if (next && !document) start()\n }}\n >\n <DialogTrigger\n render={\n <Button variant=\"outline\" size=\"sm\">\n <AdminMessage id={\"Apply catalog\"} />\n </Button>\n }\n />\n <DialogContent className={DIALOG_WIDE}>\n <DialogHeader>\n <DialogTitle>\n <AdminMessage id={\"Apply catalog changes\"} />\n </DialogTitle>\n <DialogDescription>\n <AdminMessage\n id={\n \"Paste a JSON or YAML catalog batch; products, prices and meters are maps keyed by their key. Each product, price and meter applies whole, unless a field it names was set differently by an edit: it is skipped and listed, and the rest applies. A batch that applied whole is remembered; retries preserve later catalog edits. Omitted records stay unchanged unless prune is true, which archives the omitted ones only batches set.\"\n }\n />\n </DialogDescription>\n </DialogHeader>\n <div className=\"grid gap-3\">\n <Label htmlFor={adminId(\"catalog-application\")}>\n <AdminMessage id={\"Catalog document\"} />\n </Label>\n <Textarea\n id={adminId(\"catalog-application\")}\n className=\"max-h-80 min-h-48 font-mono text-xs\"\n spellCheck={false}\n value={document}\n disabled={submitted !== undefined}\n onChange={(event) => {\n setDocument(event.target.value)\n setReviewed(false)\n }}\n />\n {reviewed && !submitted && (\n <p className=\"text-sm\">\n <AdminMessage\n id={\n \"Review complete. Applying sends this exact document; this is not a database diff.\"\n }\n />\n </p>\n )}\n {message && (\n <p role=\"status\" className=\"text-sm\">\n {message}\n </p>\n )}\n {receipt && receipt.conflicts.length > 0 && (\n <CatalogConflicts conflicts={receipt.conflicts} />\n )}\n {receipt && (\n <pre\n aria-label={adminText(\"Batch receipt\")}\n className=\"max-h-48 overflow-auto rounded-md border p-3 text-xs\"\n >\n {JSON.stringify(receipt, null, 2)}\n </pre>\n )}\n </div>\n <DialogFooter>\n {canEdit && (\n <Button\n variant=\"outline\"\n onClick={() => {\n setSubmitted(undefined)\n setReviewed(false)\n setCanEdit(false)\n setMessage(\"\")\n }}\n >\n <AdminMessage id={\"Edit batch\"} />\n </Button>\n )}\n {receipt && receipt.conflicts.length > 0 && (\n <Button\n variant=\"destructive\"\n disabled={apply.isPending}\n onClick={() => void run(true)}\n >\n <AdminMessage id={\"Overwrite edits\"} />\n </Button>\n )}\n {receipt ? (\n <Button onClick={() => start()}>\n <AdminMessage id={\"New batch\"} />\n </Button>\n ) : submitted !== undefined ? (\n <Button\n disabled={apply.isPending || canEdit}\n onClick={() => void run()}\n >\n {apply.isPending ? \"Applying…\" : \"Retry exact batch\"}\n </Button>\n ) : reviewed ? (\n <Button disabled={!document.trim()} onClick={() => void run()}>\n <AdminMessage id={\"Apply reviewed batch\"} />\n </Button>\n ) : (\n <Button\n disabled={!document.trim()}\n onClick={() => setReviewed(true)}\n >\n <AdminMessage id={\"Review batch\"} />\n </Button>\n )}\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n\n// CatalogConflicts lists each object a batch skipped and the fields an edit\n// set differently, money and durations in readable units.\nfunction CatalogConflicts({ conflicts }: { conflicts: CatalogConflict[] }) {\n const { text: adminText } = useAdminUI()\n\n return (\n <ul\n aria-label={adminText(\"Skipped objects\")}\n className=\"grid gap-2 text-sm\"\n >\n {conflicts.map((conflict) => (\n <li\n key={`${conflict.object}:${conflict.product_key ?? \"\"}:${conflict.key}`}\n className=\"rounded-md border p-2\"\n >\n <p className=\"font-medium\">\n {conflict.product_key\n ? `Price ${conflict.key} of product ${conflict.product_key}`\n : `${conflict.object === \"meter\" ? \"Meter\" : \"Product\"} ${conflict.key}`}{\" \"}\n <AdminMessage id={\"skipped\"} />\n </p>\n <ul className=\"mt-1 grid gap-1 text-xs text-muted-foreground\">\n {conflict.fields.map((field) => (\n <li key={field.field}>\n {field.field}\n <AdminMessage id={\": the batch says\"} />{\" \"}\n {readableValue(field, field.file_value, conflict.currency)}\n <AdminMessage id={\", an edit set\"} />{\" \"}\n {readableValue(field, field.live_value, conflict.currency)} (\n {field.set_by}, {formatDate(field.set_at)})\n </li>\n ))}\n </ul>\n </li>\n ))}\n </ul>\n )\n}\n\nfunction readableValue(\n field: CatalogFieldConflict,\n value: unknown,\n currency: string | null\n): string {\n if (value === null || value === undefined) return \"none\"\n if (\n (field.field === \"unit_amount\" || field.field === \"trial_unit_amount\") &&\n typeof value === \"string\" &&\n currency\n ) {\n return formatNativeAmount(value, currency)\n }\n if (field.field.endsWith(\"_hours\") && typeof value === \"number\") {\n return formatHours(value)\n }\n return JSON.stringify(value)\n}\n","import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useAdminServices } from \"#orck/admin/context\"\n// Catalog copilot: one-shot Q&A over catalog, pricing and migration data, like\n// catalog tools, plus drafts when drafting is enabled. The model\n// never mutates anything: a draft opens, pre-filled, in the price-change\n// wizard or as a create-price call for a person to confirm.\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport {\n BubbleChatQuestionIcon,\n Cancel01Icon,\n Loading02Icon,\n SparklesIcon,\n} from \"@hugeicons/core-free-icons\"\nimport { useForm } from \"@tanstack/react-form\"\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\"\n\nimport { Badge } from \"#orck/admin/components/ui/badge\"\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport { Card, CardContent } from \"#orck/admin/components/ui/card\"\nimport { Input } from \"#orck/admin/components/ui/input\"\nimport type {\n CatalogDraft,\n NewPriceDraft,\n PriceChangeDraft,\n} from \"#orck/admin/lib/api/copilot\"\nimport { ApiError } from \"#orck/admin/lib/api/client\"\nimport { useCatalogWrites } from \"#orck/admin/lib/capabilities\"\nimport { formatNativeAmount } from \"#orck/admin/lib/format\"\n\nimport { PriceChangeWizard } from \"#orck/admin/pages/catalog/price-wizard\"\n\nexport function CatalogCopilotPanel({\n enabled,\n draftingEnabled,\n}: {\n enabled: boolean\n draftingEnabled: boolean\n}) {\n const { text: adminText } = useAdminUI()\n\n const { adminMutations } = useAdminServices()\n\n const askCatalog = useMutation(adminMutations.askCatalogCopilot())\n const form = useForm({\n defaultValues: { question: \"\" },\n onSubmit: async ({ value }) => {\n const question = value.question.trim()\n if (!question) return\n\n askCatalog.reset()\n try {\n await askCatalog.mutateAsync(question)\n } catch {\n // The request error renders inline below the form.\n }\n },\n })\n const result = askCatalog.data\n const error = askCatalog.error\n ? askCatalog.error instanceof ApiError\n ? askCatalog.error.message\n : \"ask failed\"\n : null\n\n // Enabling the copilot is an operator setup step (see docs/billing-admin.md);\n // an unconfigured feature is not page furniture, so render nothing.\n if (!enabled) {\n return null\n }\n\n return (\n <Card>\n <CardContent className=\"flex flex-col gap-3\">\n <form\n className=\"flex items-center gap-2\"\n onSubmit={(event) => {\n event.preventDefault()\n event.stopPropagation()\n void form.handleSubmit()\n }}\n >\n <HugeiconsIcon\n icon={BubbleChatQuestionIcon}\n className=\"size-4 shrink-0 text-muted-foreground\"\n />\n <form.Field name=\"question\">\n {(field) => (\n <Input\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) => field.handleChange(event.target.value)}\n placeholder={\n draftingEnabled\n ? 'Ask about your catalog, or ask for a change — e.g. \"who is still on the old premium price?\" or \"raise premium to $12\"'\n : 'Ask about your catalog — e.g. \"what do we sell?\" or \"who is still on the old premium price?\"'\n }\n className=\"flex-1\"\n />\n )}\n </form.Field>\n <form.Subscribe\n selector={(state) =>\n [state.values.question, state.isSubmitting] as const\n }\n >\n {([question, isSubmitting]) => (\n <Button\n type=\"submit\"\n size=\"sm\"\n disabled={isSubmitting || !question.trim()}\n >\n {isSubmitting ? (\n <HugeiconsIcon\n icon={Loading02Icon}\n className=\"size-3.5 animate-spin\"\n />\n ) : null}\n <AdminMessage id={\"Ask\"} />\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n {askCatalog.isPending ? (\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage id={\"Checking your catalog…\"} />\n </p>\n ) : null}\n {error ? (\n <p\n className=\"text-xs whitespace-pre-wrap text-destructive\"\n role=\"alert\"\n >\n {error}\n </p>\n ) : null}\n\n {result ? (\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex items-start justify-between gap-2\">\n <p className=\"text-sm whitespace-pre-wrap\">{result.answer}</p>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-6 shrink-0\"\n aria-label={adminText(\"Dismiss answer\")}\n onClick={() => {\n askCatalog.reset()\n }}\n >\n <HugeiconsIcon icon={Cancel01Icon} className=\"size-3.5\" />\n </Button>\n </div>\n\n {result.evidence.length > 0 && (\n <div className=\"flex flex-col gap-2\">\n {result.evidence.map((ev, i) => (\n <div key={i} className=\"rounded-lg border bg-muted/30 p-2\">\n <span className=\"mb-1 block text-xs font-medium text-muted-foreground uppercase\">\n {ev.tool}\n </span>\n <pre className=\"max-h-48 overflow-auto text-xs whitespace-pre-wrap\">\n {ev.summary}\n </pre>\n </div>\n ))}\n </div>\n )}\n\n {result.drafts?.map((draft, i) => (\n <DraftCard\n key={i}\n draft={draft}\n draftingEnabled={draftingEnabled}\n />\n ))}\n </div>\n ) : null}\n </CardContent>\n </Card>\n )\n}\n\nfunction DraftCard({\n draft,\n draftingEnabled,\n}: {\n draft: CatalogDraft\n draftingEnabled: boolean\n}) {\n const canApply = useCatalogWrites() && draftingEnabled\n if (draft.kind === \"refused\" && draft.refusal) {\n return (\n <div className=\"rounded-lg border border-dashed p-3 text-xs\">\n <p className=\"mb-1 flex items-center gap-2 font-medium\">\n <Badge variant=\"secondary\">\n <AdminMessage id={\"refused: \"} />\n {draft.refusal.code}\n </Badge>\n </p>\n <p className=\"text-muted-foreground\">{draft.refusal.reason}</p>\n <p className=\"mt-1\">{draft.refusal.workaround}</p>\n </div>\n )\n }\n if (draft.kind === \"price_change\" && draft.price_change) {\n return (\n <PriceChangeDraftCard draft={draft.price_change} canApply={canApply} />\n )\n }\n if (draft.kind === \"new_price\" && draft.new_price) {\n return <NewPriceDraftCard draft={draft.new_price} canApply={canApply} />\n }\n return null\n}\n\n// PriceChangeDraftCard loads the live price, then opens the price-change\n// wizard pre-filled at step 3; a person confirms as for a typed change.\nfunction PriceChangeDraftCard({\n draft,\n canApply,\n}: {\n draft: PriceChangeDraft\n canApply: boolean\n}) {\n const { toastApiError, adminMutations } = useAdminServices()\n\n const loadDraft = useMutation(adminMutations.loadCatalogPriceDraft())\n\n const openWizard = async () => {\n if (!canApply) return\n try {\n await loadDraft.mutateAsync({\n productKey: draft.product_key,\n priceKey: draft.price_key,\n })\n } catch (err) {\n toastApiError(err, \"Load draft for review\")\n }\n }\n\n return (\n <div className=\"rounded-lg border bg-muted/30 p-3 text-sm\">\n <div className=\"mb-1 flex items-center gap-2\">\n <HugeiconsIcon\n icon={SparklesIcon}\n className=\"size-3.5 text-muted-foreground\"\n />\n <span className=\"text-xs font-medium text-muted-foreground uppercase\">\n <AdminMessage id={\"Draft: price change\"} />\n </span>\n <Badge variant=\"secondary\">\n {BigInt(draft.new_amount) > BigInt(draft.current_amount)\n ? \"increase\"\n : \"decrease\"}\n </Badge>\n </div>\n <p>{draft.review_text}</p>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {formatNativeAmount(draft.current_amount, draft.currency)} →{\" \"}\n {formatNativeAmount(draft.new_amount, draft.currency)} ·{\" \"}\n {draft.affected_count.toLocaleString()}\n <AdminMessage id={\" affected · requires human confirm\"} />\n </p>\n {canApply &&\n (loadDraft.data ? (\n <PriceChangeWizard\n price={loadDraft.data.price}\n productName={loadDraft.data.productName}\n productKey={loadDraft.data.productKey}\n draft={draft}\n onDone={() => loadDraft.reset()}\n />\n ) : (\n <Button\n size=\"sm\"\n className=\"mt-2\"\n disabled={loadDraft.isPending}\n onClick={openWizard}\n >\n {loadDraft.isPending ? \"Loading…\" : \"Review in wizard\"}\n </Button>\n ))}\n </div>\n )\n}\n\n// NewPriceDraftCard creates the price only on a person's click, with the same\n// createPrice the New Price form uses.\nfunction NewPriceDraftCard({\n draft,\n canApply,\n}: {\n draft: NewPriceDraft\n canApply: boolean\n}) {\n const { toastApiError, adminMutations } = useAdminServices()\n\n const queryClient = useQueryClient()\n const createDraftPrice = useMutation(\n adminMutations.createCatalogDraftPrice(queryClient)\n )\n\n const confirm = async () => {\n if (!canApply) return\n try {\n await createDraftPrice.mutateAsync(draft.create_price)\n } catch (err) {\n toastApiError(err, \"Create drafted price\")\n }\n }\n\n return (\n <div className=\"rounded-lg border bg-muted/30 p-3 text-sm\">\n <div className=\"mb-1 flex items-center gap-2\">\n <HugeiconsIcon\n icon={SparklesIcon}\n className=\"size-3.5 text-muted-foreground\"\n />\n <span className=\"text-xs font-medium text-muted-foreground uppercase\">\n <AdminMessage id={\"Draft: new price\"} />\n </span>\n </div>\n <p>{draft.review_text}</p>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n <AdminMessage id={\"key: \"} />\n {draft.create_price.key} ·{\" \"}\n {formatNativeAmount(\n draft.create_price.unit_amount,\n draft.create_price.currency\n )}\n </p>\n {canApply && (\n <Button\n size=\"sm\"\n className=\"mt-2\"\n disabled={createDraftPrice.isPending || createDraftPrice.isSuccess}\n onClick={confirm}\n >\n {createDraftPrice.isSuccess\n ? \"Created\"\n : createDraftPrice.isPending\n ? \"Creating…\"\n : \"Create this price\"}\n </Button>\n )}\n </div>\n )\n}\n","import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useAdminServices } from \"#orck/admin/context\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { Add01Icon, Refresh01Icon } from \"@hugeicons/core-free-icons\"\nimport * as React from \"react\"\nimport { Link } from \"#orck/admin/router\"\n\nimport { useForm } from \"@tanstack/react-form\"\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\"\n\nimport { FormFieldErrors } from \"#orck/admin/components/form-field-errors\"\nimport { CursorPager } from \"#orck/admin/components/cursor-pager\"\nimport { useCursorPages } from \"#orck/admin/lib/cursor-pages\"\nimport { LinkedTableRow } from \"#orck/admin/components/linked-table-row\"\nimport { StatusBadge } from \"#orck/admin/components/status-badge\"\nimport { Badge } from \"#orck/admin/components/ui/badge\"\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"#orck/admin/components/ui/dialog\"\nimport { Input } from \"#orck/admin/components/ui/input\"\nimport { Label } from \"#orck/admin/components/ui/label\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"#orck/admin/components/ui/select\"\nimport { Skeleton } from \"#orck/admin/components/ui/skeleton\"\nimport { Switch } from \"#orck/admin/components/ui/switch\"\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"#orck/admin/components/ui/table\"\nimport { DIALOG_FORM } from \"#orck/admin/lib/dialog-width\"\nimport type { Price, Product } from \"#orck/client/generated/wire\"\nimport {\n currencyScale,\n formatDate,\n nativeAmountFromInput,\n shortId,\n supportedCurrencies,\n} from \"#orck/admin/lib/format\"\nimport { parseHours } from \"#orck/admin/lib/duration\"\n\nimport { CatalogApplicationDialog } from \"#orck/admin/pages/catalog/application-dialog\"\nimport { CatalogCopilotPanel } from \"#orck/admin/pages/catalog/copilot-panel\"\nimport {\n priceAmountLabel,\n priceIntervalLabel,\n} from \"#orck/admin/pages/catalog/price-format\"\nimport { PriceChangeWizard } from \"#orck/admin/pages/catalog/price-wizard\"\nimport {\n useAccess,\n useCatalogWrites,\n useMerchantConfig,\n useMerchantConfigUpdates,\n} from \"#orck/admin/lib/capabilities\"\n\n// Each part of the catalog is its own page, reached from the sub-items the\n// sidebar reveals under Catalog. The shell around them is identical, so it\n// lives here rather than being repeated three times.\nconst CatalogWritesContext = React.createContext(false)\n\nfunction CatalogSection({\n title,\n children,\n}: {\n title: string\n children: React.ReactNode\n}) {\n const assistants = useAccess()?.assistants\n const writesAllowed = useCatalogWrites()\n return (\n <CatalogWritesContext.Provider value={writesAllowed}>\n <div className=\"flex flex-col gap-4\">\n <h1 className=\"text-2xl font-semibold tracking-tight\">{title}</h1>\n <CatalogCopilotPanel\n enabled={assistants?.catalog_copilot ?? false}\n draftingEnabled={\n writesAllowed && (assistants?.catalog_drafting ?? false)\n }\n />\n {!writesAllowed && (\n <p className=\"text-sm text-muted-foreground\">\n <AdminMessage\n id={\n \"Catalog updates are unavailable. You can still browse products and prices.\"\n }\n />\n </p>\n )}\n {children}\n </div>\n </CatalogWritesContext.Provider>\n )\n}\n\nexport function CatalogProductsPage() {\n const { text: adminText } = useAdminUI()\n\n return (\n <CatalogSection title={adminText(\"Products\")}>\n <ProductsTab />\n </CatalogSection>\n )\n}\n\nexport function CatalogPricesPage() {\n const { text: adminText } = useAdminUI()\n\n return (\n <CatalogSection title={adminText(\"Prices\")}>\n <PricesTab />\n </CatalogSection>\n )\n}\n\nexport function CatalogDriftPage() {\n const { text: adminText } = useAdminUI()\n const merchantConfig = useMerchantConfig()\n if (!merchantConfig) return null\n return (\n <div className=\"flex flex-col gap-4\">\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n {adminText(\"Drift\")}\n </h1>\n <DriftTab />\n </div>\n )\n}\n\nconst CATALOG_PAGE_SIZE = 100\n\nfunction ProductsTab() {\n const { adminQueries } = useAdminServices()\n\n const writesAllowed = React.useContext(CatalogWritesContext)\n const pages = useCursorPages(\"\", CATALOG_PAGE_SIZE)\n const {\n data,\n isPending: loading,\n isFetching,\n } = useQuery(\n adminQueries.products({\n limit: pages.size,\n cursor: pages.cursor,\n errorAction: \"Load products\",\n })\n )\n\n return (\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex justify-end gap-2\">\n {writesAllowed && (\n <>\n <CatalogApplicationDialog />\n <ProductDialog />\n </>\n )}\n </div>\n {loading ? (\n <div className=\"flex flex-col gap-3 py-2\">\n {Array.from({ length: 4 }).map((_, i) => (\n <Skeleton key={i} className=\"h-6 w-full\" />\n ))}\n </div>\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow className=\"hover:bg-transparent\">\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Product\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Key\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Tier\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Entitlements\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"State\"} />\n </TableHead>\n <TableHead />\n </TableRow>\n </TableHeader>\n <TableBody>\n {(data?.data ?? []).map((p) => (\n <ProductRow key={p.id} product={p} />\n ))}\n {!data?.data?.length && (\n <TableRow>\n <TableCell\n colSpan={6}\n className=\"h-24 text-center text-muted-foreground\"\n >\n <AdminMessage id={\"No products yet.\"} />\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n )}\n <CursorPager\n pages={pages}\n rows={data?.data?.length ?? 0}\n nextCursor={data?.next_cursor}\n busy={isFetching}\n sizes={[50, 100, 200]}\n />\n </div>\n )\n}\n\nfunction ProductRow({ product }: { product: Product }) {\n const { toast, toastApiError, adminMutations } = useAdminServices()\n\n const writesAllowed = React.useContext(CatalogWritesContext)\n const queryClient = useQueryClient()\n const setProductActive = useMutation(\n adminMutations.setProductActive(queryClient)\n )\n const toggle = async () => {\n try {\n await setProductActive.mutateAsync({\n id: product.id,\n active: product.archived,\n revision: product.revision,\n })\n toast.success(\n product.archived ? \"Product activated\" : \"Product deactivated\"\n )\n } catch (err) {\n toastApiError(err, \"Toggle product\")\n }\n }\n return (\n <TableRow className={product.archived ? \"opacity-60\" : undefined}>\n <TableCell className=\"font-medium\">{product.display_name}</TableCell>\n <TableCell className=\"text-xs text-muted-foreground\">\n {product.key}\n </TableCell>\n <TableCell>\n {product.tier_group\n ? `${product.tier_group} #${product.tier_rank}`\n : \"—\"}\n </TableCell>\n <TableCell>\n <span className=\"flex flex-wrap gap-1\">\n {product.entitlements.map((e) => (\n <Badge key={e} variant=\"secondary\" className=\"text-[10px]\">\n {e}\n </Badge>\n ))}\n </span>\n </TableCell>\n <TableCell>\n {product.archived ? (\n <Badge variant=\"secondary\">\n <AdminMessage id={\"archived\"} />\n </Badge>\n ) : (\n <StatusBadge status=\"active\" />\n )}\n </TableCell>\n <TableCell className=\"text-right\">\n {writesAllowed && (\n <div className=\"flex justify-end gap-2\">\n {writesAllowed && <ProductDialog product={product} />}\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={!writesAllowed || setProductActive.isPending}\n onClick={toggle}\n >\n {product.archived ? \"Activate\" : \"Deactivate\"}\n </Button>\n </div>\n )}\n </TableCell>\n </TableRow>\n )\n}\n\nfunction productFormValues(product?: Product) {\n return {\n key: product?.key ?? \"\",\n name: product?.display_name ?? \"\",\n description: product?.description ?? \"\",\n tierGroup: product?.tier_group ?? \"\",\n tierRank: String(product?.tier_rank ?? 0),\n entitlements: (product?.entitlements ?? []).join(\",\"),\n }\n}\n\nfunction ProductDialog({ product }: { product?: Product }) {\n const { toast, toastApiError, adminMutations } = useAdminServices()\n\n const { text: adminText, id: adminId } = useAdminUI()\n\n const [open, setOpen] = React.useState(false)\n const queryClient = useQueryClient()\n const createProduct = useMutation(adminMutations.createProduct(queryClient))\n const updateProduct = useMutation(adminMutations.updateProduct(queryClient))\n const form = useForm({\n defaultValues: productFormValues(product),\n onSubmit: async ({ value }) => {\n const entitlements = value.entitlements\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean)\n\n try {\n if (product) {\n await updateProduct.mutateAsync({\n id: product.id,\n product: {\n display_name: value.name,\n description: value.description,\n tier_group: value.tierGroup || null,\n tier_rank: Number(value.tierRank) || 0,\n entitlements,\n expected_revision: product.revision,\n },\n })\n toast.success(\"Product updated\")\n } else {\n await createProduct.mutateAsync({\n key: value.key,\n display_name: value.name,\n description: value.description,\n tier_group: value.tierGroup || undefined,\n tier_rank: Number(value.tierRank) || 0,\n entitlements,\n })\n toast.success(\"Product created\")\n }\n form.reset(value)\n setOpen(false)\n } catch (err) {\n toastApiError(err, product ? \"Update product\" : \"Create product\")\n }\n },\n })\n\n const handleOpenChange = (next: boolean) => {\n if (next) form.reset(productFormValues(product))\n setOpen(next)\n }\n\n return (\n <Dialog open={open} onOpenChange={handleOpenChange}>\n <DialogTrigger\n render={\n product ? (\n <Button variant=\"outline\" size=\"sm\">\n <AdminMessage id={\"Edit\"} />\n </Button>\n ) : (\n <Button size=\"sm\">\n <HugeiconsIcon icon={Add01Icon} className=\"size-4\" />\n <AdminMessage id={\" Product\"} />\n </Button>\n )\n }\n />\n <DialogContent className={DIALOG_FORM}>\n <DialogHeader>\n <DialogTitle>{product ? \"Edit product\" : \"New product\"}</DialogTitle>\n <DialogDescription>\n <AdminMessage\n id={\n \"A product is the thing a customer gets. You set what it costs afterwards, by adding a price to it.\"\n }\n />\n </DialogDescription>\n </DialogHeader>\n <form\n onSubmit={(event) => {\n event.preventDefault()\n event.stopPropagation()\n void form.handleSubmit()\n }}\n className=\"grid gap-4\"\n >\n <div className=\"grid gap-3\">\n {!product && (\n <form.Field\n name=\"key\"\n validators={{\n onBlur: ({ value }) =>\n value.trim() ? undefined : \"Enter a product key\",\n }}\n >\n {(field) => (\n <Field\n label={adminText(\"Key\")}\n id={\"p-key\"}\n hint=\"A short name you use in your own code. It cannot be changed later.\"\n >\n <Input\n id={adminId(\"p-key\")}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n placeholder={adminText(\"premium-monthly\")}\n aria-invalid={field.state.meta.errors.length > 0}\n />\n <FormFieldErrors errors={field.state.meta.errors} />\n </Field>\n )}\n </form.Field>\n )}\n <form.Field\n name=\"name\"\n validators={{\n onBlur: ({ value }) =>\n value.trim() ? undefined : \"Enter a display name\",\n }}\n >\n {(field) => (\n <Field\n label={adminText(\"Display name\")}\n id={\"p-name\"}\n hint=\"What customers see on purchase and invoices.\"\n >\n <Input\n id={adminId(\"p-name\")}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) => field.handleChange(event.target.value)}\n aria-invalid={field.state.meta.errors.length > 0}\n />\n <FormFieldErrors errors={field.state.meta.errors} />\n </Field>\n )}\n </form.Field>\n <form.Field name=\"description\">\n {(field) => (\n <Field label={adminText(\"Description\")} id={\"p-desc\"}>\n <Input\n id={adminId(\"p-desc\")}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) => field.handleChange(event.target.value)}\n />\n </Field>\n )}\n </form.Field>\n <div className=\"grid grid-cols-2 gap-3\">\n <form.Field name=\"tierGroup\">\n {(field) => (\n <Field\n label={adminText(\"Tier group\")}\n id={\"p-tg\"}\n hint=\"Products in one group are upgrades of each other. Leave empty if this stands alone.\"\n >\n <Input\n id={adminId(\"p-tg\")}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n />\n </Field>\n )}\n </form.Field>\n <form.Field name=\"tierRank\">\n {(field) => (\n <Field\n label={adminText(\"Tier rank\")}\n id={\"p-tr\"}\n hint=\"Higher rank means a higher tier in the group.\"\n >\n <Input\n id={adminId(\"p-tr\")}\n type=\"number\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n />\n </Field>\n )}\n </form.Field>\n </div>\n <form.Field name=\"entitlements\">\n {(field) => (\n <Field\n label={adminText(\"Entitlements\")}\n id={\"p-ents\"}\n hint=\"The access names your product checks. Separate several with commas.\"\n >\n <Input\n id={adminId(\"p-ents\")}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) => field.handleChange(event.target.value)}\n placeholder={adminText(\"premium, downloads\")}\n />\n </Field>\n )}\n </form.Field>\n </div>\n <DialogFooter>\n <form.Subscribe\n selector={(state) =>\n [\n state.values.key,\n state.values.name,\n state.isSubmitting,\n ] as const\n }\n >\n {([key, name, isSubmitting]) => (\n <>\n <Button\n type=\"button\"\n variant=\"outline\"\n disabled={isSubmitting}\n onClick={() => setOpen(false)}\n >\n <AdminMessage id={\"Cancel\"} />\n </Button>\n <Button\n type=\"submit\"\n disabled={\n isSubmitting || !name.trim() || (!product && !key.trim())\n }\n >\n {isSubmitting ? \"Saving…\" : \"Save product\"}\n </Button>\n </>\n )}\n </form.Subscribe>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction PricesTab() {\n const { adminQueries } = useAdminServices()\n\n const writesAllowed = React.useContext(CatalogWritesContext)\n const pages = useCursorPages(\"\", CATALOG_PAGE_SIZE)\n const { data: products } = useQuery(\n adminQueries.allProducts({ errorAction: \"Load products\" })\n )\n const {\n data,\n isPending: loading,\n isFetching,\n } = useQuery(\n adminQueries.prices({\n limit: pages.size,\n cursor: pages.cursor,\n errorAction: \"Load prices\",\n })\n )\n return (\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex justify-end\">\n {writesAllowed && <PriceDialog products={products?.data ?? []} />}\n </div>\n {loading ? (\n <div className=\"flex flex-col gap-3 py-2\">\n {Array.from({ length: 4 }).map((_, i) => (\n <Skeleton key={i} className=\"h-6 w-full\" />\n ))}\n </div>\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow className=\"hover:bg-transparent\">\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Price\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Product\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Amount\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Renews\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Providers\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"State\"} />\n </TableHead>\n <TableHead />\n </TableRow>\n </TableHeader>\n <TableBody>\n {(data?.data ?? []).map((price) => (\n <PriceRow\n key={price.id}\n price={price}\n product={products?.data.find(\n (p) => p.id === price.product_id\n )}\n />\n ))}\n {!data?.data?.length && (\n <TableRow>\n <TableCell\n colSpan={7}\n className=\"h-24 text-center text-muted-foreground\"\n >\n <AdminMessage id={\"No prices yet.\"} />\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n )}\n <CursorPager\n pages={pages}\n rows={data?.data?.length ?? 0}\n nextCursor={data?.next_cursor}\n busy={isFetching}\n sizes={[50, 100, 200]}\n />\n </div>\n )\n}\n\nfunction PriceRow({ price, product }: { price: Price; product?: Product }) {\n const { toast, toastApiError, adminMutations } = useAdminServices()\n\n const productName = product?.display_name ?? shortId(price.product_id, 13)\n const writesAllowed = React.useContext(CatalogWritesContext)\n const queryClient = useQueryClient()\n const setPriceActive = useMutation(adminMutations.setPriceActive(queryClient))\n const toggle = async () => {\n try {\n await setPriceActive.mutateAsync({\n id: price.id,\n active: price.archived,\n revision: price.revision,\n })\n toast.success(price.archived ? \"Price activated\" : \"Price deactivated\")\n } catch (err) {\n toastApiError(err, \"Toggle price\")\n }\n }\n return (\n <LinkedTableRow\n to={`/catalog/prices/${encodeURIComponent(price.id)}`}\n className={price.archived ? \"opacity-60\" : undefined}\n >\n <TableCell className=\"text-xs text-muted-foreground\">\n <Link\n className=\"underline-offset-2 hover:underline\"\n to={`/catalog/prices/${encodeURIComponent(price.id)}`}\n >\n {price.id}\n </Link>\n </TableCell>\n <TableCell className=\"font-medium\">{productName}</TableCell>\n <TableCell className=\"tabular-nums\">{priceAmountLabel(price)}</TableCell>\n <TableCell>{priceIntervalLabel(price)}</TableCell>\n <TableCell>\n <span className=\"flex flex-wrap gap-1\">\n {/* psp_links is keyed by PSP key (\"mobius\"), not by rail — the rail\n is recorded inside the entry (or#812). */}\n {Object.entries(price.psps ?? {}).map(([psp, state]) => (\n <Badge\n key={psp}\n variant=\"secondary\"\n className={\n state.status === \"linked\" ? \"\" : \"bg-held-surface text-held\"\n }\n title={state.message || undefined}\n >\n {psp}: {state.status}\n </Badge>\n ))}\n </span>\n </TableCell>\n <TableCell>\n {price.archived ? (\n <Badge variant=\"secondary\">\n <AdminMessage id={\"archived\"} />\n </Badge>\n ) : (\n <StatusBadge status=\"active\" />\n )}\n </TableCell>\n <TableCell className=\"text-right\">\n {writesAllowed && (\n <div className=\"flex justify-end gap-2\">\n {writesAllowed && (\n <PriceChangeWizard\n price={price}\n productName={productName}\n productKey={product?.key}\n />\n )}\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={!writesAllowed || setPriceActive.isPending}\n onClick={toggle}\n >\n {price.archived ? \"Activate\" : \"Deactivate\"}\n </Button>\n </div>\n )}\n </TableCell>\n </LinkedTableRow>\n )\n}\n\nconst durationError = ({ value }: { value: string }) =>\n !value || parseHours(value)\n ? undefined\n : \"Use hours, days or weeks, such as 30 days\"\n\nfunction PriceDialog({ products }: { products: Product[] }) {\n const { toast, toastApiError, adminMutations } = useAdminServices()\n\n const { text: adminText, id: adminId } = useAdminUI()\n\n const [open, setOpen] = React.useState(false)\n const queryClient = useQueryClient()\n const createPrice = useMutation(adminMutations.createPrice(queryClient))\n const form = useForm({\n defaultValues: {\n productId: \"\",\n amount: \"\",\n currency: \"USD\",\n accessDuration: \"\",\n billingInterval: \"\",\n },\n onSubmit: async ({ value }) => {\n const unitAmount = nativeAmountFromInput(value.amount, value.currency)\n if (unitAmount === null || BigInt(unitAmount) <= 0n) return\n const accessHours = parseHours(value.accessDuration)\n const billingHours = parseHours(value.billingInterval)\n if (\n (value.accessDuration && !accessHours) ||\n (value.billingInterval && !billingHours)\n )\n return\n try {\n await createPrice.mutateAsync({\n product_id: value.productId,\n unit_amount: unitAmount,\n currency: value.currency,\n ...(accessHours ? { access_duration_hours: accessHours } : {}),\n ...(billingHours ? { billing_interval_hours: billingHours } : {}),\n })\n form.reset()\n toast.success(\"Price created\")\n setOpen(false)\n } catch (err) {\n toastApiError(err, \"Create price\")\n }\n },\n })\n\n const handleOpenChange = (next: boolean) => {\n if (next) form.reset()\n setOpen(next)\n }\n\n return (\n <Dialog open={open} onOpenChange={handleOpenChange}>\n <DialogTrigger\n render={\n <Button size=\"sm\">\n <HugeiconsIcon icon={Add01Icon} className=\"size-4\" />\n <AdminMessage id={\" Price\"} />\n </Button>\n }\n />\n <DialogContent className={DIALOG_FORM}>\n <DialogHeader>\n <DialogTitle>\n <AdminMessage id={\"New price\"} />\n </DialogTitle>\n <DialogDescription>\n <AdminMessage\n id={\n \"These terms cannot be changed later. To charge a different amount, create another price and deactivate this one.\"\n }\n />\n </DialogDescription>\n </DialogHeader>\n <form\n onSubmit={(event) => {\n event.preventDefault()\n event.stopPropagation()\n void form.handleSubmit()\n }}\n className=\"grid gap-4\"\n >\n <div className=\"grid gap-3\">\n <form.Field name=\"productId\">\n {(field) => (\n <Field label={adminText(\"Product\")} id={\"pr-prod\"}>\n <Select\n items={products.map((product) => ({\n value: product.id,\n label: `${product.display_name} (${product.key})`,\n }))}\n value={field.state.value || null}\n onValueChange={(value) => field.handleChange(value ?? \"\")}\n >\n <SelectTrigger id={adminId(\"pr-prod\")} className=\"w-full\">\n <SelectValue placeholder={adminText(\"Pick a product…\")} />\n </SelectTrigger>\n <SelectContent>\n {products.map((product) => (\n <SelectItem key={product.id} value={product.id}>\n {product.display_name} ({product.key})\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n )}\n </form.Field>\n {/* Amount and currency are one money value, so they sit on one row\n under one label — two labelled columns pull apart whenever the\n hint wraps. */}\n <Field\n label={adminText(\"Amount\")}\n id={\"pr-amount\"}\n hint=\"Enter it the way you would write it, such as 19.90.\"\n >\n <div className=\"flex gap-2\">\n <form.Field\n name=\"amount\"\n validators={{\n onBlurListenTo: [\"currency\"],\n onBlur: ({ value, fieldApi }) =>\n BigInt(\n nativeAmountFromInput(\n value,\n fieldApi.form.getFieldValue(\"currency\")\n ) ?? \"0\"\n ) > 0n\n ? undefined\n : \"Enter an amount greater than zero\",\n }}\n >\n {(field) => (\n <div className=\"flex-1\">\n <Input\n id={adminId(\"pr-amount\")}\n type=\"number\"\n step=\"any\"\n min=\"0\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n aria-invalid={field.state.meta.errors.length > 0}\n />\n <FormFieldErrors errors={field.state.meta.errors} />\n </div>\n )}\n </form.Field>\n <form.Field\n name=\"currency\"\n validators={{\n onChange: ({ value }) =>\n currencyScale(value) === undefined\n ? `Use ${supportedCurrencies.join(\", \")}`\n : undefined,\n }}\n >\n {(field) => (\n <Input\n id={adminId(\"pr-cur\")}\n aria-label={adminText(\"Currency\")}\n className=\"w-24\"\n // Registered currency codes are normalized to uppercase.\n value={field.state.value}\n maxLength={Math.max(\n ...supportedCurrencies.map((code) => code.length)\n )}\n autoCapitalize=\"characters\"\n spellCheck={false}\n placeholder={adminText(\"USD\")}\n onBlur={field.handleBlur}\n onChange={(event) =>\n field.handleChange(event.target.value.toUpperCase())\n }\n />\n )}\n </form.Field>\n </div>\n </Field>\n <form.Field\n name=\"accessDuration\"\n validators={{ onBlur: durationError }}\n >\n {(field) => (\n <Field\n label={adminText(\"Access duration\")}\n id={\"pr-dur\"}\n hint=\"Such as 30 days, 1 week or 12 hours. Leave it empty for access that never expires.\"\n >\n <Input\n id={adminId(\"pr-dur\")}\n placeholder={adminText(\"Never expires\")}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) => field.handleChange(event.target.value)}\n aria-invalid={field.state.meta.errors.length > 0}\n />\n <FormFieldErrors errors={field.state.meta.errors} />\n </Field>\n )}\n </form.Field>\n <form.Field\n name=\"billingInterval\"\n validators={{ onBlur: durationError }}\n >\n {(field) => (\n <div className=\"grid gap-3 rounded-md border p-3\">\n <div className=\"flex items-center justify-between gap-4\">\n <Label htmlFor={adminId(\"pr-renew\")}>\n <AdminMessage id={\"Recurring billing\"} />\n </Label>\n <Switch\n id={adminId(\"pr-renew\")}\n checked={!!field.state.value}\n onCheckedChange={(checked) =>\n field.handleChange(checked ? \"30 days\" : \"\")\n }\n />\n </div>\n {field.state.value ? (\n <Field\n label={adminText(\"Billing interval\")}\n id={\"pr-billing\"}\n hint=\"Time between payments, such as 30 days, until the customer cancels.\"\n >\n <Input\n id={adminId(\"pr-billing\")}\n required\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n aria-invalid={field.state.meta.errors.length > 0}\n />\n <FormFieldErrors errors={field.state.meta.errors} />\n </Field>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage id={\"One-time payment.\"} />\n </p>\n )}\n </div>\n )}\n </form.Field>\n </div>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => handleOpenChange(false)}\n >\n <AdminMessage id={\"Cancel\"} />\n </Button>\n <form.Subscribe\n selector={(state) =>\n [\n state.values.productId,\n state.values.amount,\n state.values.currency,\n state.values.accessDuration,\n state.values.billingInterval,\n state.isSubmitting,\n ] as const\n }\n >\n {([\n productId,\n amount,\n currency,\n accessDuration,\n billingInterval,\n isSubmitting,\n ]) => (\n <Button\n type=\"submit\"\n disabled={\n isSubmitting ||\n !productId ||\n BigInt(nativeAmountFromInput(amount, currency) ?? \"0\") <=\n 0n ||\n durationError({ value: accessDuration }) !== undefined ||\n durationError({ value: billingInterval }) !== undefined\n }\n >\n {isSubmitting ? \"Creating…\" : \"Create price\"}\n </Button>\n )}\n </form.Subscribe>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction DriftTab() {\n const { toast, toastApiError, adminMutations, adminQueries } =\n useAdminServices()\n\n const queryClient = useQueryClient()\n const canRead = useMerchantConfig()\n const canRefresh = useMerchantConfigUpdates()\n const { data, isPending: loading } = useQuery(adminQueries.catalogDrift(canRead))\n const refreshDrift = useMutation(adminMutations.refreshPSPs(queryClient))\n\n return (\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex justify-end\">\n {canRefresh && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={refreshDrift.isPending}\n onClick={async () => {\n try {\n await refreshDrift.mutateAsync()\n toast.success(\n \"Re-reading every PSP: new drift appears here as it is found\"\n )\n } catch (err) {\n toastApiError(err, \"Refresh drift\")\n }\n }}\n >\n <HugeiconsIcon\n icon={Refresh01Icon}\n className={\n refreshDrift.isPending ? \"size-4 animate-spin\" : \"size-4\"\n }\n />\n <AdminMessage id={\"Refresh scan\"} />\n </Button>\n )}\n </div>\n {loading ? (\n <div className=\"flex flex-col gap-3 py-2\">\n {Array.from({ length: 4 }).map((_, i) => (\n <Skeleton key={i} className=\"h-6 w-full\" />\n ))}\n </div>\n ) : !data?.data?.length ? (\n <p className=\"text-sm text-muted-foreground\">\n <AdminMessage id={\"No open drift events. Catalog is in sync.\"} />\n </p>\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow className=\"hover:bg-transparent\">\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Provider\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Kind\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Resource\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Field\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"OpenRails\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Remote\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Detected\"} />\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {data.data.map((e) => (\n <TableRow key={e.id}>\n <TableCell>{e.provider ?? \"—\"}</TableCell>\n <TableCell>\n {e.finding_type.replace(/^catalog\\./, \"\")}\n </TableCell>\n <TableCell className=\"text-xs\">\n {e.resource_type}{\" \"}\n {shortId(e.resource_id || e.external_resource_id || \"\", 13)}\n </TableCell>\n <TableCell>{e.field || \"—\"}</TableCell>\n <TableCell className=\"max-w-40 truncate\">\n {e.openrails_value || \"—\"}\n </TableCell>\n <TableCell className=\"max-w-40 truncate\">\n {e.external_value || \"—\"}\n </TableCell>\n <TableCell>{formatDate(e.created_at)}</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </div>\n )\n}\n\n// hint carries the invisible constraint: what a value is for, or what happens if\n// it is left empty. Anything the control already says is left out.\nfunction Field({\n label,\n id,\n hint,\n children,\n}: {\n label: string\n id: string\n hint?: string\n children: React.ReactNode\n}) {\n const { id: adminId } = useAdminUI()\n\n return (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(id)}>{label}</Label>\n {hint ? (\n <p className=\"text-[13px] text-muted-foreground\">{hint}</p>\n ) : null}\n {children}\n </div>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"admin-catalog-Bsxo2gyS.js","names":[],"sources":["../src/admin/pages/catalog/application-dialog.tsx","../src/admin/pages/catalog/copilot-panel.tsx","../src/admin/pages/catalog/index.tsx"],"sourcesContent":["import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useAdminServices } from \"#orck/admin/context\"\nimport * as React from \"react\"\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\"\n\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"#orck/admin/components/ui/dialog\"\nimport { Label } from \"#orck/admin/components/ui/label\"\nimport { Textarea } from \"#orck/admin/components/ui/textarea\"\nimport { ApiError } from \"#orck/admin/lib/api/client\"\nimport { type CatalogApplicationReceipt } from \"#orck/admin/lib/api/endpoints\"\nimport type {\n CatalogConflict,\n CatalogFieldConflict,\n} from \"#orck/client/generated/wire\"\nimport { DIALOG_WIDE } from \"#orck/admin/lib/dialog-width\"\nimport { formatHours } from \"#orck/admin/lib/duration\"\nimport { formatDate, formatNativeAmount } from \"#orck/admin/lib/format\"\n\nexport function CatalogApplicationDialog() {\n const { toast, toastApiError, selectedMerchant, adminMutations } =\n useAdminServices()\n\n const { id: adminId, text: adminText } = useAdminUI()\n\n const [open, setOpen] = React.useState(false)\n const [document, setDocument] = React.useState(\"\")\n const [reviewed, setReviewed] = React.useState(false)\n const [submitted, setSubmitted] = React.useState<string>()\n const [receipt, setReceipt] = React.useState<CatalogApplicationReceipt>()\n const [message, setMessage] = React.useState(\"\")\n const [canEdit, setCanEdit] = React.useState(false)\n const [draftMerchant, setDraftMerchant] = React.useState<string>()\n const apply = useMutation(adminMutations.applyCatalog(useQueryClient()))\n\n const start = () => {\n setDraftMerchant(selectedMerchant())\n setDocument(\n JSON.stringify(\n {\n schema_version: 1,\n prune: false,\n products: {},\n },\n null,\n 2\n )\n )\n setSubmitted(undefined)\n setReceipt(undefined)\n setReviewed(false)\n setCanEdit(false)\n setMessage(\"\")\n }\n\n const run = async (force = false) => {\n if (selectedMerchant() !== draftMerchant) {\n setMessage(\n \"This draft belongs to another selected merchant. Return to that merchant before applying it.\"\n )\n return\n }\n const exactDocument = submitted ?? document\n setSubmitted(exactDocument)\n setCanEdit(false)\n setMessage(\"\")\n try {\n const result = await apply.mutateAsync({ document: exactDocument, force })\n setReceipt(result)\n const skipped = result.conflicts?.length ?? 0\n setMessage(\n result.replayed\n ? \"This batch was already applied. No changes were repeated, and later catalog edits were preserved.\"\n : skipped > 0\n ? `Applied everything no edit changed. ${skipped} ${skipped === 1 ? \"object was\" : \"objects were\"} skipped because an edit set ${skipped === 1 ? \"its\" : \"their\"} fields differently: change the batch to agree, remove those fields, or overwrite the edits.`\n : \"Batch applied. Review the current catalog before preparing another batch.\"\n )\n if (skipped > 0) {\n toast.warning(`Catalog batch applied; ${skipped} skipped`)\n } else {\n toast.success(\n result.replayed\n ? \"Original batch receipt returned\"\n : \"Catalog batch applied\"\n )\n }\n } catch (err) {\n const refused =\n err instanceof ApiError &&\n err.status >= 400 &&\n err.status < 500 &&\n err.status !== 408\n setCanEdit(refused)\n setMessage(\n refused\n ? \"Batch refused. Review the error and edit the document before trying again.\"\n : \"The outcome could not be confirmed. Retry this exact document to retrieve its receipt without repeating changes.\"\n )\n toastApiError(err, \"Apply catalog\")\n }\n }\n\n return (\n <Dialog\n open={open}\n onOpenChange={(next) => {\n if (apply.isPending) return\n setOpen(next)\n if (next && !document) start()\n }}\n >\n <DialogTrigger\n render={\n <Button variant=\"outline\" size=\"sm\">\n <AdminMessage id={\"Apply catalog\"} />\n </Button>\n }\n />\n <DialogContent className={DIALOG_WIDE}>\n <DialogHeader>\n <DialogTitle>\n <AdminMessage id={\"Apply catalog changes\"} />\n </DialogTitle>\n <DialogDescription>\n <AdminMessage\n id={\n \"Paste a JSON or YAML catalog batch; products, prices and meters are maps keyed by their key. Each product, price and meter applies whole, unless a field it names was set differently by an edit: it is skipped and listed, and the rest applies. A batch that applied whole is remembered; retries preserve later catalog edits. Omitted records stay unchanged unless prune is true, which archives the omitted ones only batches set.\"\n }\n />\n </DialogDescription>\n </DialogHeader>\n <div className=\"grid gap-3\">\n <Label htmlFor={adminId(\"catalog-application\")}>\n <AdminMessage id={\"Catalog document\"} />\n </Label>\n <Textarea\n id={adminId(\"catalog-application\")}\n className=\"max-h-80 min-h-48 font-mono text-xs\"\n spellCheck={false}\n value={document}\n disabled={submitted !== undefined}\n onChange={(event) => {\n setDocument(event.target.value)\n setReviewed(false)\n }}\n />\n {reviewed && !submitted && (\n <p className=\"text-sm\">\n <AdminMessage\n id={\n \"Review complete. Applying sends this exact document; this is not a database diff.\"\n }\n />\n </p>\n )}\n {message && (\n <p role=\"status\" className=\"text-sm\">\n {message}\n </p>\n )}\n {receipt && receipt.conflicts.length > 0 && (\n <CatalogConflicts conflicts={receipt.conflicts} />\n )}\n {receipt && (\n <pre\n aria-label={adminText(\"Batch receipt\")}\n className=\"max-h-48 overflow-auto rounded-md border p-3 text-xs\"\n >\n {JSON.stringify(receipt, null, 2)}\n </pre>\n )}\n </div>\n <DialogFooter>\n {canEdit && (\n <Button\n variant=\"outline\"\n onClick={() => {\n setSubmitted(undefined)\n setReviewed(false)\n setCanEdit(false)\n setMessage(\"\")\n }}\n >\n <AdminMessage id={\"Edit batch\"} />\n </Button>\n )}\n {receipt && receipt.conflicts.length > 0 && (\n <Button\n variant=\"destructive\"\n disabled={apply.isPending}\n onClick={() => void run(true)}\n >\n <AdminMessage id={\"Overwrite edits\"} />\n </Button>\n )}\n {receipt ? (\n <Button onClick={() => start()}>\n <AdminMessage id={\"New batch\"} />\n </Button>\n ) : submitted !== undefined ? (\n <Button\n disabled={apply.isPending || canEdit}\n onClick={() => void run()}\n >\n {apply.isPending ? \"Applying…\" : \"Retry exact batch\"}\n </Button>\n ) : reviewed ? (\n <Button disabled={!document.trim()} onClick={() => void run()}>\n <AdminMessage id={\"Apply reviewed batch\"} />\n </Button>\n ) : (\n <Button\n disabled={!document.trim()}\n onClick={() => setReviewed(true)}\n >\n <AdminMessage id={\"Review batch\"} />\n </Button>\n )}\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n\n// CatalogConflicts lists each object a batch skipped and the fields an edit\n// set differently, money and durations in readable units.\nfunction CatalogConflicts({ conflicts }: { conflicts: CatalogConflict[] }) {\n const { text: adminText } = useAdminUI()\n\n return (\n <ul\n aria-label={adminText(\"Skipped objects\")}\n className=\"grid gap-2 text-sm\"\n >\n {conflicts.map((conflict) => (\n <li\n key={`${conflict.object}:${conflict.product_key ?? \"\"}:${conflict.key}`}\n className=\"rounded-md border p-2\"\n >\n <p className=\"font-medium\">\n {conflict.product_key\n ? `Price ${conflict.key} of product ${conflict.product_key}`\n : `${conflict.object === \"meter\" ? \"Meter\" : \"Product\"} ${conflict.key}`}{\" \"}\n <AdminMessage id={\"skipped\"} />\n </p>\n <ul className=\"mt-1 grid gap-1 text-xs text-muted-foreground\">\n {conflict.fields.map((field) => (\n <li key={field.field}>\n {field.field}\n <AdminMessage id={\": the batch says\"} />{\" \"}\n {readableValue(field, field.file_value, conflict.currency)}\n <AdminMessage id={\", an edit set\"} />{\" \"}\n {readableValue(field, field.live_value, conflict.currency)} (\n {field.set_by}, {formatDate(field.set_at)})\n </li>\n ))}\n </ul>\n </li>\n ))}\n </ul>\n )\n}\n\nfunction readableValue(\n field: CatalogFieldConflict,\n value: unknown,\n currency: string | null\n): string {\n if (value === null || value === undefined) return \"none\"\n if (\n (field.field === \"unit_amount\" || field.field === \"trial_unit_amount\") &&\n typeof value === \"string\" &&\n currency\n ) {\n return formatNativeAmount(value, currency)\n }\n if (field.field.endsWith(\"_hours\") && typeof value === \"number\") {\n return formatHours(value)\n }\n return JSON.stringify(value)\n}\n","import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useAdminServices } from \"#orck/admin/context\"\n// Catalog copilot: one-shot Q&A over catalog, pricing and migration data, like\n// catalog tools, plus drafts when drafting is enabled. The model\n// never mutates anything: a draft opens, pre-filled, in the price-change\n// wizard or as a create-price call for a person to confirm.\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport {\n BubbleChatQuestionIcon,\n Cancel01Icon,\n Loading02Icon,\n SparklesIcon,\n} from \"@hugeicons/core-free-icons\"\nimport { useForm } from \"@tanstack/react-form\"\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\"\n\nimport { Badge } from \"#orck/admin/components/ui/badge\"\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport { Card, CardContent } from \"#orck/admin/components/ui/card\"\nimport { Input } from \"#orck/admin/components/ui/input\"\nimport type {\n CatalogDraft,\n NewPriceDraft,\n PriceChangeDraft,\n} from \"#orck/admin/lib/api/copilot\"\nimport { ApiError } from \"#orck/admin/lib/api/client\"\nimport { useCatalogWrites } from \"#orck/admin/lib/capabilities\"\nimport { formatNativeAmount } from \"#orck/admin/lib/format\"\n\nimport { PriceChangeWizard } from \"#orck/admin/pages/catalog/price-wizard\"\n\nexport function CatalogCopilotPanel({\n enabled,\n draftingEnabled,\n}: {\n enabled: boolean\n draftingEnabled: boolean\n}) {\n const { text: adminText } = useAdminUI()\n\n const { adminMutations } = useAdminServices()\n\n const askCatalog = useMutation(adminMutations.askCatalogCopilot())\n const form = useForm({\n defaultValues: { question: \"\" },\n onSubmit: async ({ value }) => {\n const question = value.question.trim()\n if (!question) return\n\n askCatalog.reset()\n try {\n await askCatalog.mutateAsync(question)\n } catch {\n // The request error renders inline below the form.\n }\n },\n })\n const result = askCatalog.data\n const error = askCatalog.error\n ? askCatalog.error instanceof ApiError\n ? askCatalog.error.message\n : \"ask failed\"\n : null\n\n // Enabling the copilot is an operator setup step (see docs/billing-admin.md);\n // an unconfigured feature is not page furniture, so render nothing.\n if (!enabled) {\n return null\n }\n\n return (\n <Card>\n <CardContent className=\"flex flex-col gap-3\">\n <form\n className=\"flex items-center gap-2\"\n onSubmit={(event) => {\n event.preventDefault()\n event.stopPropagation()\n void form.handleSubmit()\n }}\n >\n <HugeiconsIcon\n icon={BubbleChatQuestionIcon}\n className=\"size-4 shrink-0 text-muted-foreground\"\n />\n <form.Field name=\"question\">\n {(field) => (\n <Input\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) => field.handleChange(event.target.value)}\n placeholder={\n draftingEnabled\n ? 'Ask about your catalog, or ask for a change — e.g. \"who is still on the old premium price?\" or \"raise premium to $12\"'\n : 'Ask about your catalog — e.g. \"what do we sell?\" or \"who is still on the old premium price?\"'\n }\n className=\"flex-1\"\n />\n )}\n </form.Field>\n <form.Subscribe\n selector={(state) =>\n [state.values.question, state.isSubmitting] as const\n }\n >\n {([question, isSubmitting]) => (\n <Button\n type=\"submit\"\n size=\"sm\"\n disabled={isSubmitting || !question.trim()}\n >\n {isSubmitting ? (\n <HugeiconsIcon\n icon={Loading02Icon}\n className=\"size-3.5 animate-spin\"\n />\n ) : null}\n <AdminMessage id={\"Ask\"} />\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n {askCatalog.isPending ? (\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage id={\"Checking your catalog…\"} />\n </p>\n ) : null}\n {error ? (\n <p\n className=\"text-xs whitespace-pre-wrap text-destructive\"\n role=\"alert\"\n >\n {error}\n </p>\n ) : null}\n\n {result ? (\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex items-start justify-between gap-2\">\n <p className=\"text-sm whitespace-pre-wrap\">{result.answer}</p>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-6 shrink-0\"\n aria-label={adminText(\"Dismiss answer\")}\n onClick={() => {\n askCatalog.reset()\n }}\n >\n <HugeiconsIcon icon={Cancel01Icon} className=\"size-3.5\" />\n </Button>\n </div>\n\n {result.evidence.length > 0 && (\n <div className=\"flex flex-col gap-2\">\n {result.evidence.map((ev, i) => (\n <div key={i} className=\"rounded-lg border bg-muted/30 p-2\">\n <span className=\"mb-1 block text-xs font-medium text-muted-foreground uppercase\">\n {ev.tool}\n </span>\n <pre className=\"max-h-48 overflow-auto text-xs whitespace-pre-wrap\">\n {ev.summary}\n </pre>\n </div>\n ))}\n </div>\n )}\n\n {result.drafts?.map((draft, i) => (\n <DraftCard\n key={i}\n draft={draft}\n draftingEnabled={draftingEnabled}\n />\n ))}\n </div>\n ) : null}\n </CardContent>\n </Card>\n )\n}\n\nfunction DraftCard({\n draft,\n draftingEnabled,\n}: {\n draft: CatalogDraft\n draftingEnabled: boolean\n}) {\n const canApply = useCatalogWrites() && draftingEnabled\n if (draft.kind === \"refused\" && draft.refusal) {\n return (\n <div className=\"rounded-lg border border-dashed p-3 text-xs\">\n <p className=\"mb-1 flex items-center gap-2 font-medium\">\n <Badge variant=\"secondary\">\n <AdminMessage id={\"refused: \"} />\n {draft.refusal.code}\n </Badge>\n </p>\n <p className=\"text-muted-foreground\">{draft.refusal.reason}</p>\n <p className=\"mt-1\">{draft.refusal.workaround}</p>\n </div>\n )\n }\n if (draft.kind === \"price_change\" && draft.price_change) {\n return (\n <PriceChangeDraftCard draft={draft.price_change} canApply={canApply} />\n )\n }\n if (draft.kind === \"new_price\" && draft.new_price) {\n return <NewPriceDraftCard draft={draft.new_price} canApply={canApply} />\n }\n return null\n}\n\n// PriceChangeDraftCard loads the live price, then opens the price-change\n// wizard pre-filled at step 3; a person confirms as for a typed change.\nfunction PriceChangeDraftCard({\n draft,\n canApply,\n}: {\n draft: PriceChangeDraft\n canApply: boolean\n}) {\n const { toastApiError, adminMutations } = useAdminServices()\n\n const loadDraft = useMutation(adminMutations.loadCatalogPriceDraft())\n\n const openWizard = async () => {\n if (!canApply) return\n try {\n await loadDraft.mutateAsync({\n productKey: draft.product_key,\n priceKey: draft.price_key,\n })\n } catch (err) {\n toastApiError(err, \"Load draft for review\")\n }\n }\n\n return (\n <div className=\"rounded-lg border bg-muted/30 p-3 text-sm\">\n <div className=\"mb-1 flex items-center gap-2\">\n <HugeiconsIcon\n icon={SparklesIcon}\n className=\"size-3.5 text-muted-foreground\"\n />\n <span className=\"text-xs font-medium text-muted-foreground uppercase\">\n <AdminMessage id={\"Draft: price change\"} />\n </span>\n <Badge variant=\"secondary\">\n {BigInt(draft.new_amount) > BigInt(draft.current_amount)\n ? \"increase\"\n : \"decrease\"}\n </Badge>\n </div>\n <p>{draft.review_text}</p>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {formatNativeAmount(draft.current_amount, draft.currency)} →{\" \"}\n {formatNativeAmount(draft.new_amount, draft.currency)} ·{\" \"}\n {draft.affected_count.toLocaleString()}\n <AdminMessage id={\" affected · requires human confirm\"} />\n </p>\n {canApply &&\n (loadDraft.data ? (\n <PriceChangeWizard\n price={loadDraft.data.price}\n productName={loadDraft.data.productName}\n productKey={loadDraft.data.productKey}\n draft={draft}\n onDone={() => loadDraft.reset()}\n />\n ) : (\n <Button\n size=\"sm\"\n className=\"mt-2\"\n disabled={loadDraft.isPending}\n onClick={openWizard}\n >\n {loadDraft.isPending ? \"Loading…\" : \"Review in wizard\"}\n </Button>\n ))}\n </div>\n )\n}\n\n// NewPriceDraftCard creates the price only on a person's click, with the same\n// createPrice the New Price form uses.\nfunction NewPriceDraftCard({\n draft,\n canApply,\n}: {\n draft: NewPriceDraft\n canApply: boolean\n}) {\n const { toastApiError, adminMutations } = useAdminServices()\n\n const queryClient = useQueryClient()\n const createDraftPrice = useMutation(\n adminMutations.createCatalogDraftPrice(queryClient)\n )\n\n const confirm = async () => {\n if (!canApply) return\n try {\n await createDraftPrice.mutateAsync(draft.create_price)\n } catch (err) {\n toastApiError(err, \"Create drafted price\")\n }\n }\n\n return (\n <div className=\"rounded-lg border bg-muted/30 p-3 text-sm\">\n <div className=\"mb-1 flex items-center gap-2\">\n <HugeiconsIcon\n icon={SparklesIcon}\n className=\"size-3.5 text-muted-foreground\"\n />\n <span className=\"text-xs font-medium text-muted-foreground uppercase\">\n <AdminMessage id={\"Draft: new price\"} />\n </span>\n </div>\n <p>{draft.review_text}</p>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n <AdminMessage id={\"key: \"} />\n {draft.create_price.key} ·{\" \"}\n {formatNativeAmount(\n draft.create_price.unit_amount,\n draft.create_price.currency\n )}\n </p>\n {canApply && (\n <Button\n size=\"sm\"\n className=\"mt-2\"\n disabled={createDraftPrice.isPending || createDraftPrice.isSuccess}\n onClick={confirm}\n >\n {createDraftPrice.isSuccess\n ? \"Created\"\n : createDraftPrice.isPending\n ? \"Creating…\"\n : \"Create this price\"}\n </Button>\n )}\n </div>\n )\n}\n","import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useAdminServices } from \"#orck/admin/context\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { Add01Icon, Refresh01Icon } from \"@hugeicons/core-free-icons\"\nimport * as React from \"react\"\nimport { Link } from \"#orck/admin/router\"\n\nimport { useForm } from \"@tanstack/react-form\"\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\"\n\nimport { FormFieldErrors } from \"#orck/admin/components/form-field-errors\"\nimport { CursorPager } from \"#orck/admin/components/cursor-pager\"\nimport { useCursorPages } from \"#orck/admin/lib/cursor-pages\"\nimport { LinkedTableRow } from \"#orck/admin/components/linked-table-row\"\nimport { StatusBadge } from \"#orck/admin/components/status-badge\"\nimport { Badge } from \"#orck/admin/components/ui/badge\"\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"#orck/admin/components/ui/dialog\"\nimport { Input } from \"#orck/admin/components/ui/input\"\nimport { Label } from \"#orck/admin/components/ui/label\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"#orck/admin/components/ui/select\"\nimport { Skeleton } from \"#orck/admin/components/ui/skeleton\"\nimport { Switch } from \"#orck/admin/components/ui/switch\"\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"#orck/admin/components/ui/table\"\nimport { DIALOG_FORM } from \"#orck/admin/lib/dialog-width\"\nimport type { Price, Product } from \"#orck/client/generated/wire\"\nimport {\n currencyScale,\n formatDate,\n nativeAmountFromInput,\n shortId,\n supportedCurrencies,\n} from \"#orck/admin/lib/format\"\nimport { parseHours } from \"#orck/admin/lib/duration\"\n\nimport { CatalogApplicationDialog } from \"#orck/admin/pages/catalog/application-dialog\"\nimport { CatalogCopilotPanel } from \"#orck/admin/pages/catalog/copilot-panel\"\nimport {\n priceAmountLabel,\n priceIntervalLabel,\n} from \"#orck/admin/pages/catalog/price-format\"\nimport { PriceChangeWizard } from \"#orck/admin/pages/catalog/price-wizard\"\nimport {\n useAccess,\n useCatalogWrites,\n useMerchantConfig,\n useMerchantConfigUpdates,\n} from \"#orck/admin/lib/capabilities\"\n\n// Each part of the catalog is its own page, reached from the sub-items the\n// sidebar reveals under Catalog. The shell around them is identical, so it\n// lives here rather than being repeated three times.\nconst CatalogWritesContext = React.createContext(false)\n\nfunction CatalogSection({\n title,\n children,\n}: {\n title: string\n children: React.ReactNode\n}) {\n const assistants = useAccess()?.assistants\n const writesAllowed = useCatalogWrites()\n return (\n <CatalogWritesContext.Provider value={writesAllowed}>\n <div className=\"flex flex-col gap-4\">\n <h1 className=\"text-2xl font-semibold tracking-tight\">{title}</h1>\n <CatalogCopilotPanel\n enabled={assistants?.catalog_copilot ?? false}\n draftingEnabled={\n writesAllowed && (assistants?.catalog_drafting ?? false)\n }\n />\n {!writesAllowed && (\n <p className=\"text-sm text-muted-foreground\">\n <AdminMessage\n id={\n \"Catalog updates are unavailable. You can still browse products and prices.\"\n }\n />\n </p>\n )}\n {children}\n </div>\n </CatalogWritesContext.Provider>\n )\n}\n\nexport function CatalogProductsPage() {\n const { text: adminText } = useAdminUI()\n\n return (\n <CatalogSection title={adminText(\"Products\")}>\n <ProductsTab />\n </CatalogSection>\n )\n}\n\nexport function CatalogPricesPage() {\n const { text: adminText } = useAdminUI()\n\n return (\n <CatalogSection title={adminText(\"Prices\")}>\n <PricesTab />\n </CatalogSection>\n )\n}\n\nexport function CatalogDriftPage() {\n const { text: adminText } = useAdminUI()\n const merchantConfig = useMerchantConfig()\n if (!merchantConfig) return null\n return (\n <div className=\"flex flex-col gap-4\">\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n {adminText(\"Drift\")}\n </h1>\n <DriftTab />\n </div>\n )\n}\n\nconst CATALOG_PAGE_SIZE = 100\n\nfunction ProductsTab() {\n const { adminQueries } = useAdminServices()\n\n const writesAllowed = React.useContext(CatalogWritesContext)\n const pages = useCursorPages(\"\", CATALOG_PAGE_SIZE)\n const {\n data,\n isPending: loading,\n isFetching,\n } = useQuery(\n adminQueries.products({\n limit: pages.size,\n cursor: pages.cursor,\n errorAction: \"Load products\",\n })\n )\n\n return (\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex justify-end gap-2\">\n {writesAllowed && (\n <>\n <CatalogApplicationDialog />\n <ProductDialog />\n </>\n )}\n </div>\n {loading ? (\n <div className=\"flex flex-col gap-3 py-2\">\n {Array.from({ length: 4 }).map((_, i) => (\n <Skeleton key={i} className=\"h-6 w-full\" />\n ))}\n </div>\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow className=\"hover:bg-transparent\">\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Product\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Key\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Tier\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Entitlements\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"State\"} />\n </TableHead>\n <TableHead />\n </TableRow>\n </TableHeader>\n <TableBody>\n {(data?.data ?? []).map((p) => (\n <ProductRow key={p.id} product={p} />\n ))}\n {!data?.data?.length && (\n <TableRow>\n <TableCell\n colSpan={6}\n className=\"h-24 text-center text-muted-foreground\"\n >\n <AdminMessage id={\"No products yet.\"} />\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n )}\n <CursorPager\n pages={pages}\n rows={data?.data?.length ?? 0}\n nextCursor={data?.next_cursor}\n busy={isFetching}\n sizes={[50, 100, 200]}\n />\n </div>\n )\n}\n\nfunction ProductRow({ product }: { product: Product }) {\n const { toast, toastApiError, adminMutations } = useAdminServices()\n\n const writesAllowed = React.useContext(CatalogWritesContext)\n const queryClient = useQueryClient()\n const setProductActive = useMutation(\n adminMutations.setProductActive(queryClient)\n )\n const toggle = async () => {\n try {\n await setProductActive.mutateAsync({\n id: product.id,\n active: product.archived,\n revision: product.revision,\n })\n toast.success(\n product.archived ? \"Product activated\" : \"Product deactivated\"\n )\n } catch (err) {\n toastApiError(err, \"Toggle product\")\n }\n }\n return (\n <TableRow className={product.archived ? \"opacity-60\" : undefined}>\n <TableCell className=\"font-medium\">{product.display_name}</TableCell>\n <TableCell className=\"text-xs text-muted-foreground\">\n {product.key}\n </TableCell>\n <TableCell>\n {product.tier_group\n ? `${product.tier_group} #${product.tier_rank}`\n : \"—\"}\n </TableCell>\n <TableCell>\n <span className=\"flex flex-wrap gap-1\">\n {product.entitlements.map((e) => (\n <Badge key={e} variant=\"secondary\" className=\"text-[10px]\">\n {e}\n </Badge>\n ))}\n </span>\n </TableCell>\n <TableCell>\n {product.archived ? (\n <Badge variant=\"secondary\">\n <AdminMessage id={\"archived\"} />\n </Badge>\n ) : (\n <StatusBadge status=\"active\" />\n )}\n </TableCell>\n <TableCell className=\"text-right\">\n {writesAllowed && (\n <div className=\"flex justify-end gap-2\">\n {writesAllowed && <ProductDialog product={product} />}\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={!writesAllowed || setProductActive.isPending}\n onClick={toggle}\n >\n {product.archived ? \"Activate\" : \"Deactivate\"}\n </Button>\n </div>\n )}\n </TableCell>\n </TableRow>\n )\n}\n\nfunction productFormValues(product?: Product) {\n return {\n key: product?.key ?? \"\",\n name: product?.display_name ?? \"\",\n description: product?.description ?? \"\",\n tierGroup: product?.tier_group ?? \"\",\n tierRank: String(product?.tier_rank ?? 0),\n entitlements: (product?.entitlements ?? []).join(\",\"),\n }\n}\n\nfunction ProductDialog({ product }: { product?: Product }) {\n const { toast, toastApiError, adminMutations } = useAdminServices()\n\n const { text: adminText, id: adminId } = useAdminUI()\n\n const [open, setOpen] = React.useState(false)\n const queryClient = useQueryClient()\n const createProduct = useMutation(adminMutations.createProduct(queryClient))\n const updateProduct = useMutation(adminMutations.updateProduct(queryClient))\n const form = useForm({\n defaultValues: productFormValues(product),\n onSubmit: async ({ value }) => {\n const entitlements = value.entitlements\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean)\n\n try {\n if (product) {\n await updateProduct.mutateAsync({\n id: product.id,\n product: {\n display_name: value.name,\n description: value.description,\n tier_group: value.tierGroup || null,\n tier_rank: Number(value.tierRank) || 0,\n entitlements,\n expected_revision: product.revision,\n },\n })\n toast.success(\"Product updated\")\n } else {\n await createProduct.mutateAsync({\n key: value.key,\n display_name: value.name,\n description: value.description,\n tier_group: value.tierGroup || undefined,\n tier_rank: Number(value.tierRank) || 0,\n entitlements,\n })\n toast.success(\"Product created\")\n }\n form.reset(value)\n setOpen(false)\n } catch (err) {\n toastApiError(err, product ? \"Update product\" : \"Create product\")\n }\n },\n })\n\n const handleOpenChange = (next: boolean) => {\n if (next) form.reset(productFormValues(product))\n setOpen(next)\n }\n\n return (\n <Dialog open={open} onOpenChange={handleOpenChange}>\n <DialogTrigger\n render={\n product ? (\n <Button variant=\"outline\" size=\"sm\">\n <AdminMessage id={\"Edit\"} />\n </Button>\n ) : (\n <Button size=\"sm\">\n <HugeiconsIcon icon={Add01Icon} className=\"size-4\" />\n <AdminMessage id={\" Product\"} />\n </Button>\n )\n }\n />\n <DialogContent className={DIALOG_FORM}>\n <DialogHeader>\n <DialogTitle>{product ? \"Edit product\" : \"New product\"}</DialogTitle>\n <DialogDescription>\n <AdminMessage\n id={\n \"A product is the thing a customer gets. You set what it costs afterwards, by adding a price to it.\"\n }\n />\n </DialogDescription>\n </DialogHeader>\n <form\n onSubmit={(event) => {\n event.preventDefault()\n event.stopPropagation()\n void form.handleSubmit()\n }}\n className=\"grid gap-4\"\n >\n <div className=\"grid gap-3\">\n {!product && (\n <form.Field\n name=\"key\"\n validators={{\n onBlur: ({ value }) =>\n value.trim() ? undefined : \"Enter a product key\",\n }}\n >\n {(field) => (\n <Field\n label={adminText(\"Key\")}\n id={\"p-key\"}\n hint=\"A short name you use in your own code. It cannot be changed later.\"\n >\n <Input\n id={adminId(\"p-key\")}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n placeholder={adminText(\"premium-monthly\")}\n aria-invalid={field.state.meta.errors.length > 0}\n />\n <FormFieldErrors errors={field.state.meta.errors} />\n </Field>\n )}\n </form.Field>\n )}\n <form.Field\n name=\"name\"\n validators={{\n onBlur: ({ value }) =>\n value.trim() ? undefined : \"Enter a display name\",\n }}\n >\n {(field) => (\n <Field\n label={adminText(\"Display name\")}\n id={\"p-name\"}\n hint=\"What customers see on purchase and invoices.\"\n >\n <Input\n id={adminId(\"p-name\")}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) => field.handleChange(event.target.value)}\n aria-invalid={field.state.meta.errors.length > 0}\n />\n <FormFieldErrors errors={field.state.meta.errors} />\n </Field>\n )}\n </form.Field>\n <form.Field name=\"description\">\n {(field) => (\n <Field label={adminText(\"Description\")} id={\"p-desc\"}>\n <Input\n id={adminId(\"p-desc\")}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) => field.handleChange(event.target.value)}\n />\n </Field>\n )}\n </form.Field>\n <div className=\"grid grid-cols-2 gap-3\">\n <form.Field name=\"tierGroup\">\n {(field) => (\n <Field\n label={adminText(\"Tier group\")}\n id={\"p-tg\"}\n hint=\"Products in one group are upgrades of each other. Leave empty if this stands alone.\"\n >\n <Input\n id={adminId(\"p-tg\")}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n />\n </Field>\n )}\n </form.Field>\n <form.Field name=\"tierRank\">\n {(field) => (\n <Field\n label={adminText(\"Tier rank\")}\n id={\"p-tr\"}\n hint=\"Higher rank means a higher tier in the group.\"\n >\n <Input\n id={adminId(\"p-tr\")}\n type=\"number\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n />\n </Field>\n )}\n </form.Field>\n </div>\n <form.Field name=\"entitlements\">\n {(field) => (\n <Field\n label={adminText(\"Entitlements\")}\n id={\"p-ents\"}\n hint=\"The access names your product checks. Separate several with commas.\"\n >\n <Input\n id={adminId(\"p-ents\")}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) => field.handleChange(event.target.value)}\n placeholder={adminText(\"premium, downloads\")}\n />\n </Field>\n )}\n </form.Field>\n </div>\n <DialogFooter>\n <form.Subscribe\n selector={(state) =>\n [\n state.values.key,\n state.values.name,\n state.isSubmitting,\n ] as const\n }\n >\n {([key, name, isSubmitting]) => (\n <>\n <Button\n type=\"button\"\n variant=\"outline\"\n disabled={isSubmitting}\n onClick={() => setOpen(false)}\n >\n <AdminMessage id={\"Cancel\"} />\n </Button>\n <Button\n type=\"submit\"\n disabled={\n isSubmitting || !name.trim() || (!product && !key.trim())\n }\n >\n {isSubmitting ? \"Saving…\" : \"Save product\"}\n </Button>\n </>\n )}\n </form.Subscribe>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction PricesTab() {\n const { adminQueries } = useAdminServices()\n\n const writesAllowed = React.useContext(CatalogWritesContext)\n const pages = useCursorPages(\"\", CATALOG_PAGE_SIZE)\n const { data: products } = useQuery(\n adminQueries.allProducts({ errorAction: \"Load products\" })\n )\n const {\n data,\n isPending: loading,\n isFetching,\n } = useQuery(\n adminQueries.prices({\n limit: pages.size,\n cursor: pages.cursor,\n errorAction: \"Load prices\",\n })\n )\n return (\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex justify-end\">\n {writesAllowed && <PriceDialog products={products?.data ?? []} />}\n </div>\n {loading ? (\n <div className=\"flex flex-col gap-3 py-2\">\n {Array.from({ length: 4 }).map((_, i) => (\n <Skeleton key={i} className=\"h-6 w-full\" />\n ))}\n </div>\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow className=\"hover:bg-transparent\">\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Price\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Product\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Amount\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Renews\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Providers\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"State\"} />\n </TableHead>\n <TableHead />\n </TableRow>\n </TableHeader>\n <TableBody>\n {(data?.data ?? []).map((price) => (\n <PriceRow\n key={price.id}\n price={price}\n product={products?.data.find(\n (p) => p.id === price.product_id\n )}\n />\n ))}\n {!data?.data?.length && (\n <TableRow>\n <TableCell\n colSpan={7}\n className=\"h-24 text-center text-muted-foreground\"\n >\n <AdminMessage id={\"No prices yet.\"} />\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n )}\n <CursorPager\n pages={pages}\n rows={data?.data?.length ?? 0}\n nextCursor={data?.next_cursor}\n busy={isFetching}\n sizes={[50, 100, 200]}\n />\n </div>\n )\n}\n\nfunction PriceRow({ price, product }: { price: Price; product?: Product }) {\n const { toast, toastApiError, adminMutations } = useAdminServices()\n\n const productName = product?.display_name ?? shortId(price.product_id, 13)\n const writesAllowed = React.useContext(CatalogWritesContext)\n const queryClient = useQueryClient()\n const setPriceActive = useMutation(adminMutations.setPriceActive(queryClient))\n const toggle = async () => {\n try {\n await setPriceActive.mutateAsync({\n id: price.id,\n active: price.archived,\n revision: price.revision,\n })\n toast.success(price.archived ? \"Price activated\" : \"Price deactivated\")\n } catch (err) {\n toastApiError(err, \"Toggle price\")\n }\n }\n return (\n <LinkedTableRow\n to={`/catalog/prices/${encodeURIComponent(price.id)}`}\n className={price.archived ? \"opacity-60\" : undefined}\n >\n <TableCell className=\"text-xs text-muted-foreground\">\n <Link\n className=\"underline-offset-2 hover:underline\"\n to={`/catalog/prices/${encodeURIComponent(price.id)}`}\n >\n {price.id}\n </Link>\n </TableCell>\n <TableCell className=\"font-medium\">{productName}</TableCell>\n <TableCell className=\"tabular-nums\">{priceAmountLabel(price)}</TableCell>\n <TableCell>{priceIntervalLabel(price)}</TableCell>\n <TableCell>\n <span className=\"flex flex-wrap gap-1\">\n {/* psps is keyed by PSP key (\"mobius\"), not by rail — the rail\n is recorded inside the entry (or#812). */}\n {Object.entries(price.psps ?? {}).map(([psp, state]) => (\n <Badge\n key={psp}\n variant=\"secondary\"\n className={\n state.status === \"linked\" ? \"\" : \"bg-held-surface text-held\"\n }\n title={state.message || undefined}\n >\n {psp}: {state.status}\n </Badge>\n ))}\n </span>\n </TableCell>\n <TableCell>\n {price.archived ? (\n <Badge variant=\"secondary\">\n <AdminMessage id={\"archived\"} />\n </Badge>\n ) : (\n <StatusBadge status=\"active\" />\n )}\n </TableCell>\n <TableCell className=\"text-right\">\n {writesAllowed && (\n <div className=\"flex justify-end gap-2\">\n {writesAllowed && (\n <PriceChangeWizard\n price={price}\n productName={productName}\n productKey={product?.key}\n />\n )}\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={!writesAllowed || setPriceActive.isPending}\n onClick={toggle}\n >\n {price.archived ? \"Activate\" : \"Deactivate\"}\n </Button>\n </div>\n )}\n </TableCell>\n </LinkedTableRow>\n )\n}\n\nconst durationError = ({ value }: { value: string }) =>\n !value || parseHours(value)\n ? undefined\n : \"Use hours, days or weeks, such as 30 days\"\n\nfunction PriceDialog({ products }: { products: Product[] }) {\n const { toast, toastApiError, adminMutations } = useAdminServices()\n\n const { text: adminText, id: adminId } = useAdminUI()\n\n const [open, setOpen] = React.useState(false)\n const queryClient = useQueryClient()\n const createPrice = useMutation(adminMutations.createPrice(queryClient))\n const form = useForm({\n defaultValues: {\n productId: \"\",\n amount: \"\",\n currency: \"USD\",\n accessDuration: \"\",\n billingInterval: \"\",\n },\n onSubmit: async ({ value }) => {\n const unitAmount = nativeAmountFromInput(value.amount, value.currency)\n if (unitAmount === null || BigInt(unitAmount) <= 0n) return\n const accessHours = parseHours(value.accessDuration)\n const billingHours = parseHours(value.billingInterval)\n if (\n (value.accessDuration && !accessHours) ||\n (value.billingInterval && !billingHours)\n )\n return\n try {\n await createPrice.mutateAsync({\n product_id: value.productId,\n unit_amount: unitAmount,\n currency: value.currency,\n ...(accessHours ? { access_duration_hours: accessHours } : {}),\n ...(billingHours ? { billing_interval_hours: billingHours } : {}),\n })\n form.reset()\n toast.success(\"Price created\")\n setOpen(false)\n } catch (err) {\n toastApiError(err, \"Create price\")\n }\n },\n })\n\n const handleOpenChange = (next: boolean) => {\n if (next) form.reset()\n setOpen(next)\n }\n\n return (\n <Dialog open={open} onOpenChange={handleOpenChange}>\n <DialogTrigger\n render={\n <Button size=\"sm\">\n <HugeiconsIcon icon={Add01Icon} className=\"size-4\" />\n <AdminMessage id={\" Price\"} />\n </Button>\n }\n />\n <DialogContent className={DIALOG_FORM}>\n <DialogHeader>\n <DialogTitle>\n <AdminMessage id={\"New price\"} />\n </DialogTitle>\n <DialogDescription>\n <AdminMessage\n id={\n \"These terms cannot be changed later. To charge a different amount, create another price and deactivate this one.\"\n }\n />\n </DialogDescription>\n </DialogHeader>\n <form\n onSubmit={(event) => {\n event.preventDefault()\n event.stopPropagation()\n void form.handleSubmit()\n }}\n className=\"grid gap-4\"\n >\n <div className=\"grid gap-3\">\n <form.Field name=\"productId\">\n {(field) => (\n <Field label={adminText(\"Product\")} id={\"pr-prod\"}>\n <Select\n items={products.map((product) => ({\n value: product.id,\n label: `${product.display_name} (${product.key})`,\n }))}\n value={field.state.value || null}\n onValueChange={(value) => field.handleChange(value ?? \"\")}\n >\n <SelectTrigger id={adminId(\"pr-prod\")} className=\"w-full\">\n <SelectValue placeholder={adminText(\"Pick a product…\")} />\n </SelectTrigger>\n <SelectContent>\n {products.map((product) => (\n <SelectItem key={product.id} value={product.id}>\n {product.display_name} ({product.key})\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n )}\n </form.Field>\n {/* Amount and currency are one money value, so they sit on one row\n under one label — two labelled columns pull apart whenever the\n hint wraps. */}\n <Field\n label={adminText(\"Amount\")}\n id={\"pr-amount\"}\n hint=\"Enter it the way you would write it, such as 19.90.\"\n >\n <div className=\"flex gap-2\">\n <form.Field\n name=\"amount\"\n validators={{\n onBlurListenTo: [\"currency\"],\n onBlur: ({ value, fieldApi }) =>\n BigInt(\n nativeAmountFromInput(\n value,\n fieldApi.form.getFieldValue(\"currency\")\n ) ?? \"0\"\n ) > 0n\n ? undefined\n : \"Enter an amount greater than zero\",\n }}\n >\n {(field) => (\n <div className=\"flex-1\">\n <Input\n id={adminId(\"pr-amount\")}\n type=\"number\"\n step=\"any\"\n min=\"0\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n aria-invalid={field.state.meta.errors.length > 0}\n />\n <FormFieldErrors errors={field.state.meta.errors} />\n </div>\n )}\n </form.Field>\n <form.Field\n name=\"currency\"\n validators={{\n onChange: ({ value }) =>\n currencyScale(value) === undefined\n ? `Use ${supportedCurrencies.join(\", \")}`\n : undefined,\n }}\n >\n {(field) => (\n <Input\n id={adminId(\"pr-cur\")}\n aria-label={adminText(\"Currency\")}\n className=\"w-24\"\n // Registered currency codes are normalized to uppercase.\n value={field.state.value}\n maxLength={Math.max(\n ...supportedCurrencies.map((code) => code.length)\n )}\n autoCapitalize=\"characters\"\n spellCheck={false}\n placeholder={adminText(\"USD\")}\n onBlur={field.handleBlur}\n onChange={(event) =>\n field.handleChange(event.target.value.toUpperCase())\n }\n />\n )}\n </form.Field>\n </div>\n </Field>\n <form.Field\n name=\"accessDuration\"\n validators={{ onBlur: durationError }}\n >\n {(field) => (\n <Field\n label={adminText(\"Access duration\")}\n id={\"pr-dur\"}\n hint=\"Such as 30 days, 1 week or 12 hours. Leave it empty for access that never expires.\"\n >\n <Input\n id={adminId(\"pr-dur\")}\n placeholder={adminText(\"Never expires\")}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) => field.handleChange(event.target.value)}\n aria-invalid={field.state.meta.errors.length > 0}\n />\n <FormFieldErrors errors={field.state.meta.errors} />\n </Field>\n )}\n </form.Field>\n <form.Field\n name=\"billingInterval\"\n validators={{ onBlur: durationError }}\n >\n {(field) => (\n <div className=\"grid gap-3 rounded-md border p-3\">\n <div className=\"flex items-center justify-between gap-4\">\n <Label htmlFor={adminId(\"pr-renew\")}>\n <AdminMessage id={\"Recurring billing\"} />\n </Label>\n <Switch\n id={adminId(\"pr-renew\")}\n checked={!!field.state.value}\n onCheckedChange={(checked) =>\n field.handleChange(checked ? \"30 days\" : \"\")\n }\n />\n </div>\n {field.state.value ? (\n <Field\n label={adminText(\"Billing interval\")}\n id={\"pr-billing\"}\n hint=\"Time between payments, such as 30 days, until the customer cancels.\"\n >\n <Input\n id={adminId(\"pr-billing\")}\n required\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n aria-invalid={field.state.meta.errors.length > 0}\n />\n <FormFieldErrors errors={field.state.meta.errors} />\n </Field>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage id={\"One-time payment.\"} />\n </p>\n )}\n </div>\n )}\n </form.Field>\n </div>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => handleOpenChange(false)}\n >\n <AdminMessage id={\"Cancel\"} />\n </Button>\n <form.Subscribe\n selector={(state) =>\n [\n state.values.productId,\n state.values.amount,\n state.values.currency,\n state.values.accessDuration,\n state.values.billingInterval,\n state.isSubmitting,\n ] as const\n }\n >\n {([\n productId,\n amount,\n currency,\n accessDuration,\n billingInterval,\n isSubmitting,\n ]) => (\n <Button\n type=\"submit\"\n disabled={\n isSubmitting ||\n !productId ||\n BigInt(nativeAmountFromInput(amount, currency) ?? \"0\") <=\n 0n ||\n durationError({ value: accessDuration }) !== undefined ||\n durationError({ value: billingInterval }) !== undefined\n }\n >\n {isSubmitting ? \"Creating…\" : \"Create price\"}\n </Button>\n )}\n </form.Subscribe>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction DriftTab() {\n const { toast, toastApiError, adminMutations, adminQueries } =\n useAdminServices()\n\n const queryClient = useQueryClient()\n const canRead = useMerchantConfig()\n const canRefresh = useMerchantConfigUpdates()\n const { data, isPending: loading } = useQuery(adminQueries.catalogDrift(canRead))\n const refreshDrift = useMutation(adminMutations.refreshPSPs(queryClient))\n\n return (\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex justify-end\">\n {canRefresh && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={refreshDrift.isPending}\n onClick={async () => {\n try {\n await refreshDrift.mutateAsync()\n toast.success(\n \"Re-reading every PSP: new drift appears here as it is found\"\n )\n } catch (err) {\n toastApiError(err, \"Refresh drift\")\n }\n }}\n >\n <HugeiconsIcon\n icon={Refresh01Icon}\n className={\n refreshDrift.isPending ? \"size-4 animate-spin\" : \"size-4\"\n }\n />\n <AdminMessage id={\"Refresh scan\"} />\n </Button>\n )}\n </div>\n {loading ? (\n <div className=\"flex flex-col gap-3 py-2\">\n {Array.from({ length: 4 }).map((_, i) => (\n <Skeleton key={i} className=\"h-6 w-full\" />\n ))}\n </div>\n ) : !data?.data?.length ? (\n <p className=\"text-sm text-muted-foreground\">\n <AdminMessage id={\"No open drift events. Catalog is in sync.\"} />\n </p>\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow className=\"hover:bg-transparent\">\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Provider\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Kind\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Resource\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Field\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"OpenRails\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Remote\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Detected\"} />\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {data.data.map((e) => (\n <TableRow key={e.id}>\n <TableCell>{e.provider ?? \"—\"}</TableCell>\n <TableCell>\n {e.finding_type.replace(/^catalog\\./, \"\")}\n </TableCell>\n <TableCell className=\"text-xs\">\n {e.resource_type}{\" \"}\n {shortId(e.resource_id || e.external_resource_id || \"\", 13)}\n </TableCell>\n <TableCell>{e.field || \"—\"}</TableCell>\n <TableCell className=\"max-w-40 truncate\">\n {e.openrails_value || \"—\"}\n </TableCell>\n <TableCell className=\"max-w-40 truncate\">\n {e.external_value || \"—\"}\n </TableCell>\n <TableCell>{formatDate(e.created_at)}</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </div>\n )\n}\n\n// hint carries the invisible constraint: what a value is for, or what happens if\n// it is left empty. Anything the control already says is left out.\nfunction Field({\n label,\n id,\n hint,\n children,\n}: {\n label: string\n id: string\n hint?: string\n children: React.ReactNode\n}) {\n const { id: adminId } = useAdminUI()\n\n return (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(id)}>{label}</Label>\n {hint ? (\n <p className=\"text-[13px] text-muted-foreground\">{hint}</p>\n ) : null}\n {children}\n </div>\n )\n}\n"],"mappings":"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"}