@burdenoff/microfe-billing 2026.623.2 → 2026.624.1

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 (53) hide show
  1. package/dist/billing/BillingUserRoutes.js +3 -3
  2. package/dist/billing/BillingUserRoutes.js.map +1 -1
  3. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js +34 -34
  4. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js.map +1 -1
  5. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js +94 -94
  6. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js.map +1 -1
  7. package/dist/billing/modules/addons/pages/AddonsListPage.js +1 -1
  8. package/dist/billing/modules/addons/pages/AddonsListPage.js.map +1 -1
  9. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js +40 -40
  10. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js.map +1 -1
  11. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js +10 -10
  12. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js.map +1 -1
  13. package/dist/billing/modules/billing/pages/TransactionsPage.js +62 -62
  14. package/dist/billing/modules/billing/pages/TransactionsPage.js.map +1 -1
  15. package/dist/billing/modules/coupons/pages/CreateCouponPage.js +7 -7
  16. package/dist/billing/modules/coupons/pages/CreateCouponPage.js.map +1 -1
  17. package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js +1 -1
  18. package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js.map +1 -1
  19. package/dist/billing/modules/earnings/pages/EarningsPage.js +21 -21
  20. package/dist/billing/modules/earnings/pages/EarningsPage.js.map +1 -1
  21. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +4 -4
  22. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
  23. package/dist/billing/modules/earnings/pages/PayoutsPage.js +33 -33
  24. package/dist/billing/modules/earnings/pages/PayoutsPage.js.map +1 -1
  25. package/dist/billing/modules/plans/pages/PlanAssignFreePage.js +4 -4
  26. package/dist/billing/modules/plans/pages/PlanAssignFreePage.js.map +1 -1
  27. package/dist/billing/modules/plans/pages/PlansBrowsePage.js +146 -142
  28. package/dist/billing/modules/plans/pages/PlansBrowsePage.js.map +1 -1
  29. package/dist/billing/modules/plans/pages/PlansListPage.js +1 -1
  30. package/dist/billing/modules/plans/pages/PlansListPage.js.map +1 -1
  31. package/dist/billing/modules/promotions/pages/CreatePromotionPage.js +4 -4
  32. package/dist/billing/modules/promotions/pages/CreatePromotionPage.js.map +1 -1
  33. package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js +1 -1
  34. package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js.map +1 -1
  35. package/dist/billing/modules/settings/pages/SettingsPage.js +57 -57
  36. package/dist/billing/modules/settings/pages/SettingsPage.js.map +1 -1
  37. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js +33 -33
  38. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js.map +1 -1
  39. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js +1 -1
  40. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
  41. package/dist/billing/modules/usage/pages/UsagePage.js +1 -1
  42. package/dist/billing/modules/usage/pages/UsagePage.js.map +1 -1
  43. package/dist/billing/shared/components/AccessDenied.js +4 -4
  44. package/dist/billing/shared/components/AccessDenied.js.map +1 -1
  45. package/dist/billing/shared/components/ActorIdentity.js +8 -8
  46. package/dist/billing/shared/components/ActorIdentity.js.map +1 -1
  47. package/dist/billing/shared/components/CurrencyPriceOverridesEditor.js +11 -11
  48. package/dist/billing/shared/components/CurrencyPriceOverridesEditor.js.map +1 -1
  49. package/dist/billing/shared/ui/Card.js +1 -1
  50. package/dist/billing/shared/ui/Card.js.map +1 -1
  51. package/dist/billing/shared/ui/MetricCard.js +1 -1
  52. package/dist/billing/shared/ui/MetricCard.js.map +1 -1
  53. package/package.json +1 -1
@@ -130,16 +130,16 @@ var D = () => {
130
130
  description: "Register payout accounts, request withdrawals, and track disbursement status."
131
131
  }),
132
132
  B && !c(B) ? /* @__PURE__ */ T("div", {
133
- className: "rounded-lg border border-border bg-card p-4 text-sm text-destructive",
133
+ className: "rounded-lg border border-border-subtle bg-bg-surface p-4 text-sm text-status-error-text",
134
134
  children: B.message
135
135
  }) : null,
136
136
  /* @__PURE__ */ E("div", {
137
137
  className: "grid gap-6 xl:grid-cols-[1.05fr,1.95fr]",
138
138
  children: [/* @__PURE__ */ E("section", {
139
- className: "rounded-lg border border-border bg-card p-4",
139
+ className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
140
140
  children: [
141
141
  /* @__PURE__ */ T("h2", {
142
- className: "mb-4 text-lg font-semibold text-foreground",
142
+ className: "mb-4 text-lg font-semibold text-text-primary",
143
143
  children: J ? "Edit payout account" : "Add payout account"
144
144
  }),
145
145
  /* @__PURE__ */ E("div", {
@@ -152,7 +152,7 @@ var D = () => {
152
152
  label: e.target.value
153
153
  })),
154
154
  placeholder: "Label",
155
- className: "w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground"
155
+ className: "w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
156
156
  }),
157
157
  /* @__PURE__ */ E("div", {
158
158
  className: "grid gap-3 md:grid-cols-2",
@@ -162,7 +162,7 @@ var D = () => {
162
162
  ...t,
163
163
  type: e.target.value
164
164
  })),
165
- className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground",
165
+ className: "rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary",
166
166
  children: [
167
167
  /* @__PURE__ */ T("option", {
168
168
  value: "BANK_ACCOUNT",
@@ -183,7 +183,7 @@ var D = () => {
183
183
  ...t,
184
184
  providerPreference: e.target.value
185
185
  })),
186
- className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground",
186
+ className: "rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary",
187
187
  children: [
188
188
  /* @__PURE__ */ T("option", {
189
189
  value: "AUTO",
@@ -213,7 +213,7 @@ var D = () => {
213
213
  country: e.target.value.toUpperCase()
214
214
  })),
215
215
  placeholder: "Country",
216
- className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground"
216
+ className: "rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
217
217
  }), /* @__PURE__ */ T("input", {
218
218
  value: H.currency,
219
219
  onChange: (e) => U((t) => ({
@@ -221,7 +221,7 @@ var D = () => {
221
221
  currency: e.target.value.toUpperCase()
222
222
  })),
223
223
  placeholder: "Currency",
224
- className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground"
224
+ className: "rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
225
225
  })]
226
226
  }),
227
227
  /* @__PURE__ */ T("input", {
@@ -231,7 +231,7 @@ var D = () => {
231
231
  accountHolderName: e.target.value
232
232
  })),
233
233
  placeholder: "Account holder name",
234
- className: "w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground"
234
+ className: "w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
235
235
  }),
236
236
  H.type === "BANK_ACCOUNT" ? /* @__PURE__ */ E(w, { children: [
237
237
  /* @__PURE__ */ T("input", {
@@ -241,7 +241,7 @@ var D = () => {
241
241
  bankName: e.target.value
242
242
  })),
243
243
  placeholder: "Bank name",
244
- className: "w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground"
244
+ className: "w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
245
245
  }),
246
246
  /* @__PURE__ */ T("input", {
247
247
  value: H.accountNumber,
@@ -250,7 +250,7 @@ var D = () => {
250
250
  accountNumber: e.target.value
251
251
  })),
252
252
  placeholder: "Account number",
253
- className: "w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground"
253
+ className: "w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
254
254
  }),
255
255
  /* @__PURE__ */ T("input", {
256
256
  value: H.country === "IN" ? H.ifsc : H.routingNumber,
@@ -262,7 +262,7 @@ var D = () => {
262
262
  routingNumber: e.target.value
263
263
  }),
264
264
  placeholder: H.country === "IN" ? "IFSC" : "Routing number",
265
- className: "w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground"
265
+ className: "w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
266
266
  })
267
267
  ] }) : H.type === "UPI" ? /* @__PURE__ */ T("input", {
268
268
  value: H.upiId,
@@ -271,14 +271,14 @@ var D = () => {
271
271
  upiId: e.target.value
272
272
  })),
273
273
  placeholder: "UPI ID",
274
- className: "w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground"
274
+ className: "w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
275
275
  }) : null
276
276
  ]
277
277
  }),
278
278
  /* @__PURE__ */ E("button", {
279
279
  type: "button",
280
280
  onClick: () => void Q(),
281
- className: "mt-4 inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground",
281
+ className: "mt-4 inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text",
282
282
  children: [/* @__PURE__ */ T(x, { className: "size-4" }), J ? "Update payout account" : "Save payout account"]
283
283
  }),
284
284
  J ? /* @__PURE__ */ T("button", {
@@ -298,24 +298,24 @@ var D = () => {
298
298
  upiId: ""
299
299
  });
300
300
  },
301
- className: "mt-4 ml-3 inline-flex items-center gap-2 rounded-md border border-border px-4 py-2 text-sm font-medium text-foreground",
301
+ className: "mt-4 ml-3 inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary",
302
302
  children: "Cancel edit"
303
303
  }) : null
304
304
  ]
305
305
  }), /* @__PURE__ */ E("section", {
306
306
  className: "space-y-4",
307
307
  children: [/* @__PURE__ */ E("div", {
308
- className: "rounded-lg border border-border bg-card p-4",
308
+ className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
309
309
  children: [
310
310
  /* @__PURE__ */ E("div", {
311
311
  className: "mb-4 flex items-center justify-between",
312
312
  children: [/* @__PURE__ */ T("h2", {
313
- className: "text-lg font-semibold text-foreground",
313
+ className: "text-lg font-semibold text-text-primary",
314
314
  children: "Request payout"
315
315
  }), /* @__PURE__ */ E("button", {
316
316
  type: "button",
317
317
  onClick: () => void Z(),
318
- className: "inline-flex items-center gap-2 rounded-md border border-border px-3 py-2 text-sm font-medium text-foreground",
318
+ className: "inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary",
319
319
  children: [/* @__PURE__ */ T(S, { className: "size-4" }), "Refresh"]
320
320
  })]
321
321
  }),
@@ -329,7 +329,7 @@ var D = () => {
329
329
  /* @__PURE__ */ T("select", {
330
330
  value: K,
331
331
  onChange: (e) => q(e.target.value),
332
- className: "w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground",
332
+ className: "w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary",
333
333
  children: P.map((e) => /* @__PURE__ */ E("option", {
334
334
  value: e.id,
335
335
  children: [
@@ -345,32 +345,32 @@ var D = () => {
345
345
  value: W,
346
346
  onChange: (e) => G(e.target.value),
347
347
  placeholder: "Amount",
348
- className: "w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground"
348
+ className: "w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
349
349
  }),
350
350
  /* @__PURE__ */ E("button", {
351
351
  type: "button",
352
352
  onClick: () => void ne(),
353
- className: "inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground",
353
+ className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text",
354
354
  children: [/* @__PURE__ */ T(C, { className: "size-4" }), "Request payout"]
355
355
  })
356
356
  ]
357
357
  }),
358
358
  P.length > 0 ? /* @__PURE__ */ E("div", {
359
- className: "mt-4 space-y-3 rounded-md border border-border bg-background/60 p-3",
359
+ className: "mt-4 space-y-3 rounded-md border border-border-subtle bg-bg-surface/60 p-3",
360
360
  children: [/* @__PURE__ */ T("h3", {
361
- className: "text-sm font-semibold text-foreground",
361
+ className: "text-sm font-semibold text-text-primary",
362
362
  children: "Saved payout accounts"
363
363
  }), P.map((e) => /* @__PURE__ */ E("div", {
364
- className: "flex flex-wrap items-center justify-between gap-3 rounded-md border border-border/70 bg-card px-3 py-2 text-sm",
364
+ className: "flex flex-wrap items-center justify-between gap-3 rounded-md border border-border-subtle/70 bg-bg-surface px-3 py-2 text-sm",
365
365
  children: [/* @__PURE__ */ E("div", { children: [/* @__PURE__ */ E("p", {
366
- className: "font-medium text-foreground",
366
+ className: "font-medium text-text-primary",
367
367
  children: [
368
368
  e.label,
369
369
  " ",
370
370
  e.isDefault ? "• Default" : ""
371
371
  ]
372
372
  }), /* @__PURE__ */ E("p", {
373
- className: "text-muted-foreground",
373
+ className: "text-text-secondary",
374
374
  children: [
375
375
  e.providerPreference,
376
376
  " · ",
@@ -384,19 +384,19 @@ var D = () => {
384
384
  /* @__PURE__ */ T("button", {
385
385
  type: "button",
386
386
  onClick: () => te(e),
387
- className: "rounded-md border border-border px-3 py-1.5 text-xs font-medium text-foreground",
387
+ className: "rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary",
388
388
  children: "Edit"
389
389
  }),
390
390
  e.isDefault ? null : /* @__PURE__ */ T("button", {
391
391
  type: "button",
392
392
  onClick: () => void $(e.id),
393
- className: "rounded-md border border-border px-3 py-1.5 text-xs font-medium text-foreground",
393
+ className: "rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary",
394
394
  children: "Make default"
395
395
  }),
396
396
  /* @__PURE__ */ T("button", {
397
397
  type: "button",
398
398
  onClick: () => void ee(e.id),
399
- className: "rounded-md border border-border px-3 py-1.5 text-xs font-medium text-destructive",
399
+ className: "rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-status-error-text",
400
400
  children: "Archive"
401
401
  })
402
402
  ]
@@ -405,9 +405,9 @@ var D = () => {
405
405
  }) : null
406
406
  ]
407
407
  }), /* @__PURE__ */ E("div", {
408
- className: "rounded-lg border border-border bg-card p-4",
408
+ className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
409
409
  children: [/* @__PURE__ */ T("h2", {
410
- className: "mb-4 text-lg font-semibold text-foreground",
410
+ className: "mb-4 text-lg font-semibold text-text-primary",
411
411
  children: "Payout requests"
412
412
  }), I.length === 0 && !R ? /* @__PURE__ */ T(r, {
413
413
  icon: /* @__PURE__ */ T(C, { className: "size-8" }),
@@ -418,7 +418,7 @@ var D = () => {
418
418
  children: /* @__PURE__ */ E("table", {
419
419
  className: "min-w-full text-sm",
420
420
  children: [/* @__PURE__ */ T("thead", { children: /* @__PURE__ */ E("tr", {
421
- className: "border-b border-border text-left text-muted-foreground",
421
+ className: "border-b border-border-subtle text-left text-text-secondary",
422
422
  children: [
423
423
  /* @__PURE__ */ T("th", {
424
424
  className: "px-3 py-2",
@@ -442,7 +442,7 @@ var D = () => {
442
442
  })
443
443
  ]
444
444
  }) }), /* @__PURE__ */ T("tbody", { children: I.map((e) => /* @__PURE__ */ E("tr", {
445
- className: "border-b border-border/70 text-foreground",
445
+ className: "border-b border-border-subtle/70 text-text-primary",
446
446
  children: [
447
447
  /* @__PURE__ */ T("td", {
448
448
  className: "px-3 py-2 font-medium",
@@ -1 +1 @@
1
- {"version":3,"file":"PayoutsPage.js","names":[],"sources":["../../../../../src/billing/modules/earnings/pages/PayoutsPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState, type FC } from 'react';\nimport { Landmark, RefreshCw, Send } from 'lucide-react';\n\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { useBillingEventEmitter } from '../../../hooks/useBillingEventEmitter';\nimport { useBilling } from '../../../providers/BillingProvider';\nimport { AccessDenied, EmptyState, PageHeader, ServerError } from '../../../shared/components';\nimport { formatCurrency, formatDateTime, isServerError } from '../../../shared/utils';\nimport { useGetDefaultBillingAccountSettingsQuery } from '../../../../generated/global-operations';\nimport {\n addPayoutAccount,\n archivePayoutAccount,\n fetchPayoutAccounts,\n fetchPayoutRequests,\n requestPayout,\n setDefaultPayoutAccount,\n updatePayoutAccount,\n type PayoutAccount,\n type PayoutRequest,\n} from '../api';\n\nexport const PayoutsPage: FC = () => {\n const permissions = useBillingPermissions();\n const { emit } = useBillingEventEmitter();\n const { apiGatewayUrl, authToken, orgId } = useBilling();\n const { data: billingAccountData } = useGetDefaultBillingAccountSettingsQuery({});\n const billingAccountId = billingAccountData?.getDefaultBillingAccount?.id;\n\n const [accounts, setAccounts] = useState<PayoutAccount[]>([]);\n const [requests, setRequests] = useState<PayoutRequest[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const [accountForm, setAccountForm] = useState({\n label: '',\n type: 'BANK_ACCOUNT',\n providerPreference: 'AUTO',\n country: 'US',\n currency: 'USD',\n accountHolderName: '',\n bankName: '',\n accountNumber: '',\n routingNumber: '',\n ifsc: '',\n upiId: '',\n });\n const [requestAmount, setRequestAmount] = useState('');\n const [selectedAccountId, setSelectedAccountId] = useState<string>('');\n const [editingAccountId, setEditingAccountId] = useState<string | null>(null);\n\n const requestContext = useMemo(\n () => ({\n apiGatewayUrl,\n authToken,\n orgId,\n }),\n [apiGatewayUrl, authToken, orgId]\n );\n\n const loadData = async () => {\n if (!billingAccountId) return;\n setLoading(true);\n setError(null);\n try {\n const [loadedAccounts, loadedRequests] = await Promise.all([\n fetchPayoutAccounts(billingAccountId, requestContext),\n fetchPayoutRequests(billingAccountId, requestContext),\n ]);\n setAccounts(loadedAccounts);\n setRequests(loadedRequests);\n if (!selectedAccountId && loadedAccounts[0]?.id) {\n setSelectedAccountId(loadedAccounts[0].id);\n }\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError : new Error('Failed to load payout data'));\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n void loadData();\n }, [billingAccountId, requestContext]);\n\n if (!permissions.canManagePaymentMethods) {\n return <AccessDenied message=\"You don't have permission to manage payout accounts.\" />;\n }\n\n if (error && isServerError(error)) {\n return (\n <ServerError\n title=\"Payout data unavailable\"\n message={error.message}\n onRetry={() => void loadData()}\n showRetry\n />\n );\n }\n\n const handleAddAccount = async () => {\n if (!billingAccountId) return;\n const payload = {\n billingAccountId,\n ...accountForm,\n };\n\n if (editingAccountId) {\n await updatePayoutAccount(editingAccountId, payload, requestContext);\n emit('billing.payout_account.updated', {\n route: '/billing/payouts',\n entityId: editingAccountId,\n source: 'payouts',\n });\n } else {\n await addPayoutAccount(payload, requestContext);\n emit('billing.payout_account.added', {\n route: '/billing/payouts',\n entityId: billingAccountId,\n source: 'payouts',\n });\n }\n\n setAccountForm({\n label: '',\n type: 'BANK_ACCOUNT',\n providerPreference: 'AUTO',\n country: 'US',\n currency: 'USD',\n accountHolderName: '',\n bankName: '',\n accountNumber: '',\n routingNumber: '',\n ifsc: '',\n upiId: '',\n });\n setEditingAccountId(null);\n await loadData();\n };\n\n const handleSetDefault = async (accountId: string) => {\n await setDefaultPayoutAccount(accountId, requestContext);\n await loadData();\n };\n\n const handleArchive = async (accountId: string) => {\n if (!window.confirm('Archive this payout account?')) return;\n await archivePayoutAccount(accountId, requestContext);\n emit('billing.payout_account.archived', {\n route: '/billing/payouts',\n entityId: accountId,\n source: 'payouts',\n });\n await loadData();\n };\n\n const handleEditAccount = (account: PayoutAccount) => {\n setEditingAccountId(account.id);\n setAccountForm((current) => ({\n ...current,\n label: account.label,\n type: account.type,\n providerPreference: account.providerPreference,\n country: account.country || current.country,\n currency: account.currency,\n accountHolderName: account.displayName || current.accountHolderName,\n bankName: '',\n accountNumber: '',\n routingNumber: '',\n ifsc: '',\n upiId: '',\n }));\n };\n\n const handleRequestPayout = async () => {\n if (!billingAccountId || !selectedAccountId || !requestAmount) return;\n await requestPayout(\n {\n billingAccountId,\n payoutAccountId: selectedAccountId,\n amount: Number(requestAmount),\n currency: accounts.find((account) => account.id === selectedAccountId)?.currency || 'USD',\n },\n requestContext\n );\n emit('billing.payout.requested', {\n route: '/billing/payouts',\n entityId: selectedAccountId,\n source: 'payouts',\n amount: Number(requestAmount),\n currency: accounts.find((account) => account.id === selectedAccountId)?.currency || 'USD',\n });\n setRequestAmount('');\n await loadData();\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title=\"Payouts\"\n description=\"Register payout accounts, request withdrawals, and track disbursement status.\"\n />\n\n {error && !isServerError(error) ? (\n <div className=\"rounded-lg border border-border bg-card p-4 text-sm text-destructive\">\n {error.message}\n </div>\n ) : null}\n\n <div className=\"grid gap-6 xl:grid-cols-[1.05fr,1.95fr]\">\n <section className=\"rounded-lg border border-border bg-card p-4\">\n <h2 className=\"mb-4 text-lg font-semibold text-foreground\">\n {editingAccountId ? 'Edit payout account' : 'Add payout account'}\n </h2>\n <div className=\"space-y-3\">\n <input\n value={accountForm.label}\n onChange={(event) =>\n setAccountForm((current) => ({ ...current, label: event.target.value }))\n }\n placeholder=\"Label\"\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground\"\n />\n <div className=\"grid gap-3 md:grid-cols-2\">\n <select\n value={accountForm.type}\n onChange={(event) =>\n setAccountForm((current) => ({ ...current, type: event.target.value }))\n }\n className=\"rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground\"\n >\n <option value=\"BANK_ACCOUNT\">Bank account</option>\n <option value=\"UPI\">UPI</option>\n <option value=\"WALLET\">Wallet</option>\n </select>\n <select\n value={accountForm.providerPreference}\n onChange={(event) =>\n setAccountForm((current) => ({\n ...current,\n providerPreference: event.target.value,\n }))\n }\n className=\"rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground\"\n >\n <option value=\"AUTO\">Auto</option>\n <option value=\"STRIPE\">Stripe</option>\n <option value=\"RAZORPAY\">Razorpay</option>\n <option value=\"MANUAL\">Manual</option>\n </select>\n </div>\n <div className=\"grid gap-3 md:grid-cols-2\">\n <input\n value={accountForm.country}\n onChange={(event) =>\n setAccountForm((current) => ({\n ...current,\n country: event.target.value.toUpperCase(),\n }))\n }\n placeholder=\"Country\"\n className=\"rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground\"\n />\n <input\n value={accountForm.currency}\n onChange={(event) =>\n setAccountForm((current) => ({\n ...current,\n currency: event.target.value.toUpperCase(),\n }))\n }\n placeholder=\"Currency\"\n className=\"rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground\"\n />\n </div>\n <input\n value={accountForm.accountHolderName}\n onChange={(event) =>\n setAccountForm((current) => ({ ...current, accountHolderName: event.target.value }))\n }\n placeholder=\"Account holder name\"\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground\"\n />\n {accountForm.type === 'BANK_ACCOUNT' ? (\n <>\n <input\n value={accountForm.bankName}\n onChange={(event) =>\n setAccountForm((current) => ({ ...current, bankName: event.target.value }))\n }\n placeholder=\"Bank name\"\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground\"\n />\n <input\n value={accountForm.accountNumber}\n onChange={(event) =>\n setAccountForm((current) => ({ ...current, accountNumber: event.target.value }))\n }\n placeholder=\"Account number\"\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground\"\n />\n <input\n value={\n accountForm.country === 'IN' ? accountForm.ifsc : accountForm.routingNumber\n }\n onChange={(event) =>\n setAccountForm((current) =>\n current.country === 'IN'\n ? { ...current, ifsc: event.target.value }\n : { ...current, routingNumber: event.target.value }\n )\n }\n placeholder={accountForm.country === 'IN' ? 'IFSC' : 'Routing number'}\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground\"\n />\n </>\n ) : accountForm.type === 'UPI' ? (\n <input\n value={accountForm.upiId}\n onChange={(event) =>\n setAccountForm((current) => ({ ...current, upiId: event.target.value }))\n }\n placeholder=\"UPI ID\"\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground\"\n />\n ) : null}\n </div>\n <button\n type=\"button\"\n onClick={() => void handleAddAccount()}\n className=\"mt-4 inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground\"\n >\n <Landmark className=\"size-4\" />\n {editingAccountId ? 'Update payout account' : 'Save payout account'}\n </button>\n {editingAccountId ? (\n <button\n type=\"button\"\n onClick={() => {\n setEditingAccountId(null);\n setAccountForm({\n label: '',\n type: 'BANK_ACCOUNT',\n providerPreference: 'AUTO',\n country: 'US',\n currency: 'USD',\n accountHolderName: '',\n bankName: '',\n accountNumber: '',\n routingNumber: '',\n ifsc: '',\n upiId: '',\n });\n }}\n className=\"mt-4 ml-3 inline-flex items-center gap-2 rounded-md border border-border px-4 py-2 text-sm font-medium text-foreground\"\n >\n Cancel edit\n </button>\n ) : null}\n </section>\n\n <section className=\"space-y-4\">\n <div className=\"rounded-lg border border-border bg-card p-4\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-foreground\">Request payout</h2>\n <button\n type=\"button\"\n onClick={() => void loadData()}\n className=\"inline-flex items-center gap-2 rounded-md border border-border px-3 py-2 text-sm font-medium text-foreground\"\n >\n <RefreshCw className=\"size-4\" />\n Refresh\n </button>\n </div>\n {accounts.length === 0 && !loading ? (\n <EmptyState\n icon={<Landmark className=\"size-8\" />}\n title=\"No payout accounts yet\"\n description=\"Add a payout account before requesting a withdrawal.\"\n />\n ) : (\n <div className=\"space-y-3\">\n <select\n value={selectedAccountId}\n onChange={(event) => setSelectedAccountId(event.target.value)}\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground\"\n >\n {accounts.map((account) => (\n <option key={account.id} value={account.id}>\n {account.label} · {account.currency} · {account.status}\n </option>\n ))}\n </select>\n <input\n value={requestAmount}\n onChange={(event) => setRequestAmount(event.target.value)}\n placeholder=\"Amount\"\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground\"\n />\n <button\n type=\"button\"\n onClick={() => void handleRequestPayout()}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground\"\n >\n <Send className=\"size-4\" />\n Request payout\n </button>\n </div>\n )}\n\n {accounts.length > 0 ? (\n <div className=\"mt-4 space-y-3 rounded-md border border-border bg-background/60 p-3\">\n <h3 className=\"text-sm font-semibold text-foreground\">Saved payout accounts</h3>\n {accounts.map((account) => (\n <div\n key={account.id}\n className=\"flex flex-wrap items-center justify-between gap-3 rounded-md border border-border/70 bg-card px-3 py-2 text-sm\"\n >\n <div>\n <p className=\"font-medium text-foreground\">\n {account.label} {account.isDefault ? '• Default' : ''}\n </p>\n <p className=\"text-muted-foreground\">\n {account.providerPreference} · {account.currency} · {account.status}\n </p>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={() => handleEditAccount(account)}\n className=\"rounded-md border border-border px-3 py-1.5 text-xs font-medium text-foreground\"\n >\n Edit\n </button>\n {!account.isDefault ? (\n <button\n type=\"button\"\n onClick={() => void handleSetDefault(account.id)}\n className=\"rounded-md border border-border px-3 py-1.5 text-xs font-medium text-foreground\"\n >\n Make default\n </button>\n ) : null}\n <button\n type=\"button\"\n onClick={() => void handleArchive(account.id)}\n className=\"rounded-md border border-border px-3 py-1.5 text-xs font-medium text-destructive\"\n >\n Archive\n </button>\n </div>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n\n <div className=\"rounded-lg border border-border bg-card p-4\">\n <h2 className=\"mb-4 text-lg font-semibold text-foreground\">Payout requests</h2>\n {requests.length === 0 && !loading ? (\n <EmptyState\n icon={<Send className=\"size-8\" />}\n title=\"No payout requests yet\"\n description=\"Your payout requests and processing updates will appear here.\"\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border text-left text-muted-foreground\">\n <th className=\"px-3 py-2\">Amount</th>\n <th className=\"px-3 py-2\">Provider</th>\n <th className=\"px-3 py-2\">Status</th>\n <th className=\"px-3 py-2\">Account</th>\n <th className=\"px-3 py-2\">Created</th>\n </tr>\n </thead>\n <tbody>\n {requests.map((request) => (\n <tr key={request.id} className=\"border-b border-border/70 text-foreground\">\n <td className=\"px-3 py-2 font-medium\">\n {formatCurrency(request.requestedAmount, request.currency)}\n </td>\n <td className=\"px-3 py-2\">{request.provider}</td>\n <td className=\"px-3 py-2\">{request.status}</td>\n <td className=\"px-3 py-2\">{request.payoutAccount?.label || '-'}</td>\n <td className=\"px-3 py-2\">{formatDateTime(request.createdAt)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n </section>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"PayoutsPage.js","names":[],"sources":["../../../../../src/billing/modules/earnings/pages/PayoutsPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState, type FC } from 'react';\nimport { Landmark, RefreshCw, Send } from 'lucide-react';\n\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { useBillingEventEmitter } from '../../../hooks/useBillingEventEmitter';\nimport { useBilling } from '../../../providers/BillingProvider';\nimport { AccessDenied, EmptyState, PageHeader, ServerError } from '../../../shared/components';\nimport { formatCurrency, formatDateTime, isServerError } from '../../../shared/utils';\nimport { useGetDefaultBillingAccountSettingsQuery } from '../../../../generated/global-operations';\nimport {\n addPayoutAccount,\n archivePayoutAccount,\n fetchPayoutAccounts,\n fetchPayoutRequests,\n requestPayout,\n setDefaultPayoutAccount,\n updatePayoutAccount,\n type PayoutAccount,\n type PayoutRequest,\n} from '../api';\n\nexport const PayoutsPage: FC = () => {\n const permissions = useBillingPermissions();\n const { emit } = useBillingEventEmitter();\n const { apiGatewayUrl, authToken, orgId } = useBilling();\n const { data: billingAccountData } = useGetDefaultBillingAccountSettingsQuery({});\n const billingAccountId = billingAccountData?.getDefaultBillingAccount?.id;\n\n const [accounts, setAccounts] = useState<PayoutAccount[]>([]);\n const [requests, setRequests] = useState<PayoutRequest[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const [accountForm, setAccountForm] = useState({\n label: '',\n type: 'BANK_ACCOUNT',\n providerPreference: 'AUTO',\n country: 'US',\n currency: 'USD',\n accountHolderName: '',\n bankName: '',\n accountNumber: '',\n routingNumber: '',\n ifsc: '',\n upiId: '',\n });\n const [requestAmount, setRequestAmount] = useState('');\n const [selectedAccountId, setSelectedAccountId] = useState<string>('');\n const [editingAccountId, setEditingAccountId] = useState<string | null>(null);\n\n const requestContext = useMemo(\n () => ({\n apiGatewayUrl,\n authToken,\n orgId,\n }),\n [apiGatewayUrl, authToken, orgId]\n );\n\n const loadData = async () => {\n if (!billingAccountId) return;\n setLoading(true);\n setError(null);\n try {\n const [loadedAccounts, loadedRequests] = await Promise.all([\n fetchPayoutAccounts(billingAccountId, requestContext),\n fetchPayoutRequests(billingAccountId, requestContext),\n ]);\n setAccounts(loadedAccounts);\n setRequests(loadedRequests);\n if (!selectedAccountId && loadedAccounts[0]?.id) {\n setSelectedAccountId(loadedAccounts[0].id);\n }\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError : new Error('Failed to load payout data'));\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n void loadData();\n }, [billingAccountId, requestContext]);\n\n if (!permissions.canManagePaymentMethods) {\n return <AccessDenied message=\"You don't have permission to manage payout accounts.\" />;\n }\n\n if (error && isServerError(error)) {\n return (\n <ServerError\n title=\"Payout data unavailable\"\n message={error.message}\n onRetry={() => void loadData()}\n showRetry\n />\n );\n }\n\n const handleAddAccount = async () => {\n if (!billingAccountId) return;\n const payload = {\n billingAccountId,\n ...accountForm,\n };\n\n if (editingAccountId) {\n await updatePayoutAccount(editingAccountId, payload, requestContext);\n emit('billing.payout_account.updated', {\n route: '/billing/payouts',\n entityId: editingAccountId,\n source: 'payouts',\n });\n } else {\n await addPayoutAccount(payload, requestContext);\n emit('billing.payout_account.added', {\n route: '/billing/payouts',\n entityId: billingAccountId,\n source: 'payouts',\n });\n }\n\n setAccountForm({\n label: '',\n type: 'BANK_ACCOUNT',\n providerPreference: 'AUTO',\n country: 'US',\n currency: 'USD',\n accountHolderName: '',\n bankName: '',\n accountNumber: '',\n routingNumber: '',\n ifsc: '',\n upiId: '',\n });\n setEditingAccountId(null);\n await loadData();\n };\n\n const handleSetDefault = async (accountId: string) => {\n await setDefaultPayoutAccount(accountId, requestContext);\n await loadData();\n };\n\n const handleArchive = async (accountId: string) => {\n if (!window.confirm('Archive this payout account?')) return;\n await archivePayoutAccount(accountId, requestContext);\n emit('billing.payout_account.archived', {\n route: '/billing/payouts',\n entityId: accountId,\n source: 'payouts',\n });\n await loadData();\n };\n\n const handleEditAccount = (account: PayoutAccount) => {\n setEditingAccountId(account.id);\n setAccountForm((current) => ({\n ...current,\n label: account.label,\n type: account.type,\n providerPreference: account.providerPreference,\n country: account.country || current.country,\n currency: account.currency,\n accountHolderName: account.displayName || current.accountHolderName,\n bankName: '',\n accountNumber: '',\n routingNumber: '',\n ifsc: '',\n upiId: '',\n }));\n };\n\n const handleRequestPayout = async () => {\n if (!billingAccountId || !selectedAccountId || !requestAmount) return;\n await requestPayout(\n {\n billingAccountId,\n payoutAccountId: selectedAccountId,\n amount: Number(requestAmount),\n currency: accounts.find((account) => account.id === selectedAccountId)?.currency || 'USD',\n },\n requestContext\n );\n emit('billing.payout.requested', {\n route: '/billing/payouts',\n entityId: selectedAccountId,\n source: 'payouts',\n amount: Number(requestAmount),\n currency: accounts.find((account) => account.id === selectedAccountId)?.currency || 'USD',\n });\n setRequestAmount('');\n await loadData();\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title=\"Payouts\"\n description=\"Register payout accounts, request withdrawals, and track disbursement status.\"\n />\n\n {error && !isServerError(error) ? (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 text-sm text-status-error-text\">\n {error.message}\n </div>\n ) : null}\n\n <div className=\"grid gap-6 xl:grid-cols-[1.05fr,1.95fr]\">\n <section className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">\n {editingAccountId ? 'Edit payout account' : 'Add payout account'}\n </h2>\n <div className=\"space-y-3\">\n <input\n value={accountForm.label}\n onChange={(event) =>\n setAccountForm((current) => ({ ...current, label: event.target.value }))\n }\n placeholder=\"Label\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n <div className=\"grid gap-3 md:grid-cols-2\">\n <select\n value={accountForm.type}\n onChange={(event) =>\n setAccountForm((current) => ({ ...current, type: event.target.value }))\n }\n className=\"rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n <option value=\"BANK_ACCOUNT\">Bank account</option>\n <option value=\"UPI\">UPI</option>\n <option value=\"WALLET\">Wallet</option>\n </select>\n <select\n value={accountForm.providerPreference}\n onChange={(event) =>\n setAccountForm((current) => ({\n ...current,\n providerPreference: event.target.value,\n }))\n }\n className=\"rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n <option value=\"AUTO\">Auto</option>\n <option value=\"STRIPE\">Stripe</option>\n <option value=\"RAZORPAY\">Razorpay</option>\n <option value=\"MANUAL\">Manual</option>\n </select>\n </div>\n <div className=\"grid gap-3 md:grid-cols-2\">\n <input\n value={accountForm.country}\n onChange={(event) =>\n setAccountForm((current) => ({\n ...current,\n country: event.target.value.toUpperCase(),\n }))\n }\n placeholder=\"Country\"\n className=\"rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n <input\n value={accountForm.currency}\n onChange={(event) =>\n setAccountForm((current) => ({\n ...current,\n currency: event.target.value.toUpperCase(),\n }))\n }\n placeholder=\"Currency\"\n className=\"rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </div>\n <input\n value={accountForm.accountHolderName}\n onChange={(event) =>\n setAccountForm((current) => ({ ...current, accountHolderName: event.target.value }))\n }\n placeholder=\"Account holder name\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n {accountForm.type === 'BANK_ACCOUNT' ? (\n <>\n <input\n value={accountForm.bankName}\n onChange={(event) =>\n setAccountForm((current) => ({ ...current, bankName: event.target.value }))\n }\n placeholder=\"Bank name\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n <input\n value={accountForm.accountNumber}\n onChange={(event) =>\n setAccountForm((current) => ({ ...current, accountNumber: event.target.value }))\n }\n placeholder=\"Account number\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n <input\n value={\n accountForm.country === 'IN' ? accountForm.ifsc : accountForm.routingNumber\n }\n onChange={(event) =>\n setAccountForm((current) =>\n current.country === 'IN'\n ? { ...current, ifsc: event.target.value }\n : { ...current, routingNumber: event.target.value }\n )\n }\n placeholder={accountForm.country === 'IN' ? 'IFSC' : 'Routing number'}\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </>\n ) : accountForm.type === 'UPI' ? (\n <input\n value={accountForm.upiId}\n onChange={(event) =>\n setAccountForm((current) => ({ ...current, upiId: event.target.value }))\n }\n placeholder=\"UPI ID\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n ) : null}\n </div>\n <button\n type=\"button\"\n onClick={() => void handleAddAccount()}\n className=\"mt-4 inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text\"\n >\n <Landmark className=\"size-4\" />\n {editingAccountId ? 'Update payout account' : 'Save payout account'}\n </button>\n {editingAccountId ? (\n <button\n type=\"button\"\n onClick={() => {\n setEditingAccountId(null);\n setAccountForm({\n label: '',\n type: 'BANK_ACCOUNT',\n providerPreference: 'AUTO',\n country: 'US',\n currency: 'USD',\n accountHolderName: '',\n bankName: '',\n accountNumber: '',\n routingNumber: '',\n ifsc: '',\n upiId: '',\n });\n }}\n className=\"mt-4 ml-3 inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary\"\n >\n Cancel edit\n </button>\n ) : null}\n </section>\n\n <section className=\"space-y-4\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Request payout</h2>\n <button\n type=\"button\"\n onClick={() => void loadData()}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary\"\n >\n <RefreshCw className=\"size-4\" />\n Refresh\n </button>\n </div>\n {accounts.length === 0 && !loading ? (\n <EmptyState\n icon={<Landmark className=\"size-8\" />}\n title=\"No payout accounts yet\"\n description=\"Add a payout account before requesting a withdrawal.\"\n />\n ) : (\n <div className=\"space-y-3\">\n <select\n value={selectedAccountId}\n onChange={(event) => setSelectedAccountId(event.target.value)}\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n {accounts.map((account) => (\n <option key={account.id} value={account.id}>\n {account.label} · {account.currency} · {account.status}\n </option>\n ))}\n </select>\n <input\n value={requestAmount}\n onChange={(event) => setRequestAmount(event.target.value)}\n placeholder=\"Amount\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n <button\n type=\"button\"\n onClick={() => void handleRequestPayout()}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text\"\n >\n <Send className=\"size-4\" />\n Request payout\n </button>\n </div>\n )}\n\n {accounts.length > 0 ? (\n <div className=\"mt-4 space-y-3 rounded-md border border-border-subtle bg-bg-surface/60 p-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Saved payout accounts</h3>\n {accounts.map((account) => (\n <div\n key={account.id}\n className=\"flex flex-wrap items-center justify-between gap-3 rounded-md border border-border-subtle/70 bg-bg-surface px-3 py-2 text-sm\"\n >\n <div>\n <p className=\"font-medium text-text-primary\">\n {account.label} {account.isDefault ? '• Default' : ''}\n </p>\n <p className=\"text-text-secondary\">\n {account.providerPreference} · {account.currency} · {account.status}\n </p>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={() => handleEditAccount(account)}\n className=\"rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary\"\n >\n Edit\n </button>\n {!account.isDefault ? (\n <button\n type=\"button\"\n onClick={() => void handleSetDefault(account.id)}\n className=\"rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary\"\n >\n Make default\n </button>\n ) : null}\n <button\n type=\"button\"\n onClick={() => void handleArchive(account.id)}\n className=\"rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-status-error-text\"\n >\n Archive\n </button>\n </div>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Payout requests</h2>\n {requests.length === 0 && !loading ? (\n <EmptyState\n icon={<Send className=\"size-8\" />}\n title=\"No payout requests yet\"\n description=\"Your payout requests and processing updates will appear here.\"\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-subtle text-left text-text-secondary\">\n <th className=\"px-3 py-2\">Amount</th>\n <th className=\"px-3 py-2\">Provider</th>\n <th className=\"px-3 py-2\">Status</th>\n <th className=\"px-3 py-2\">Account</th>\n <th className=\"px-3 py-2\">Created</th>\n </tr>\n </thead>\n <tbody>\n {requests.map((request) => (\n <tr key={request.id} className=\"border-b border-border-subtle/70 text-text-primary\">\n <td className=\"px-3 py-2 font-medium\">\n {formatCurrency(request.requestedAmount, request.currency)}\n </td>\n <td className=\"px-3 py-2\">{request.provider}</td>\n <td className=\"px-3 py-2\">{request.status}</td>\n <td className=\"px-3 py-2\">{request.payoutAccount?.label || '-'}</td>\n <td className=\"px-3 py-2\">{formatDateTime(request.createdAt)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n </section>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -143,9 +143,9 @@ var u = () => {
143
143
  /* @__PURE__ */ c("div", { children: [
144
144
  /* @__PURE__ */ c("label", {
145
145
  htmlFor: "workspaceId",
146
- className: "block text-sm font-medium text-foreground mb-1",
146
+ className: "block text-sm font-medium text-text-primary mb-1",
147
147
  children: ["Workspace ID ", /* @__PURE__ */ s("span", {
148
- className: "text-muted-foreground font-normal",
148
+ className: "text-text-secondary font-normal",
149
149
  children: "(optional)"
150
150
  })]
151
151
  }),
@@ -154,11 +154,11 @@ var u = () => {
154
154
  type: "text",
155
155
  value: b,
156
156
  onChange: (e) => x(e.target.value),
157
- className: "w-full px-3 py-2 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary font-mono text-sm",
157
+ className: "w-full px-3 py-2 border border-border-subtle rounded-md bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-primary font-mono text-sm",
158
158
  placeholder: "e.g. ws_01jk3n2… (leave blank to auto-resolve)"
159
159
  }),
160
160
  /* @__PURE__ */ s("p", {
161
- className: "text-xs text-muted-foreground mt-1",
161
+ className: "text-xs text-text-secondary mt-1",
162
162
  children: "If blank, the first active workspace for this org is used automatically. Set explicitly when the org has multiple workspaces."
163
163
  })
164
164
  ] }),
@@ -1 +1 @@
1
- {"version":3,"file":"PlanAssignFreePage.js","names":[],"sources":["../../../../../src/billing/modules/plans/pages/PlanAssignFreePage.tsx"],"sourcesContent":["/**\n * Plans Module - Assign Plan Free (Admin only)\n *\n * Internal tool for assigning any plan to a billing account at no charge.\n * Protected by PLAN_ASSIGN_SECRET — only team members who know the secret\n * can use this page. Never expose to end users.\n *\n * Route: /billing/plans/assign-free\n */\n\nimport { useState, type FC, type FormEvent } from 'react';\nimport { useBillingNavigate } from '../../../hooks/useBillingNavigate';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { AccessDenied, PageHeader } from '../../../shared/components';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useAssignPlanFreeMutation } from '../../../../generated/global-operations';\nimport { usePlans } from '../hooks';\n\nexport const PlanAssignFreePage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n\n const navigateTo = useBillingNavigate();\n const permissions = useBillingPermissions();\n\n const [secret, setSecret] = useState('');\n const [billingAccountId, setBillingAccountId] = useState('');\n const [planId, setPlanId] = useState('');\n const [workspaceId, setWorkspaceId] = useState('');\n const [result, setResult] = useState<{ success: boolean; message: string } | null>(null);\n\n // Fetch all plans (including non-purchasable internal ones) for the dropdown\n const { plans, isLoading: isPlansLoading } = usePlans({ includeFree: true });\n\n const [assignPlanFree, { loading: isAssigning }] = useAssignPlanFreeMutation();\n\n if (!permissions.canManagePlans) {\n return (\n <AccessDenied\n message={tr(\n 'billing.assignFree.noPermission',\n \"You don't have permission to access this page.\"\n )}\n />\n );\n }\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n setResult(null);\n\n if (!secret.trim() || !billingAccountId.trim() || !planId) {\n setResult({ success: false, message: 'All fields are required.' });\n return;\n }\n\n try {\n const { data } = await assignPlanFree({\n variables: {\n secret: secret.trim(),\n billingAccountId: billingAccountId.trim(),\n planId,\n ...(workspaceId.trim() ? { workspaceId: workspaceId.trim() } : {}),\n },\n });\n\n if (data?.assignPlanFree) {\n const sub = data.assignPlanFree;\n setResult({\n success: true,\n message: `Plan assigned. Subscription ID: ${sub.id} · Status: ${sub.status} · Valid: ${new Date(sub.startDate).toLocaleDateString()} → ${new Date(sub.endDate).toLocaleDateString()}`,\n });\n // Clear sensitive fields\n setSecret('');\n setBillingAccountId('');\n setPlanId('');\n setWorkspaceId('');\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to assign plan.';\n setResult({ success: false, message: msg });\n }\n };\n\n const selectedPlan = plans.find((p) => p.id === planId);\n\n return (\n <div className=\"space-y-6 p-6 max-w-2xl\">\n <PageHeader\n title={tr('billing.assignFree.title', 'Assign Plan for Free')}\n description={tr(\n 'billing.assignFree.description',\n 'Internally assign any plan to a billing account at no charge. Requires the team secret.'\n )}\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/plans')}\n className=\"px-3 py-2 text-sm border border-border-subtle rounded-md text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n ← Back to Plans\n </button>\n }\n />\n\n {/* Warning banner */}\n <div className=\"flex items-start gap-3 p-4 rounded-lg border border-status-warning-border bg-status-warning-bg/10\">\n <svg\n className=\"size-5 text-status-warning-text shrink-0 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.962-.833-2.732 0L3.072 16.5c-.77.833.192 2.5 1.732 2.5z\"\n />\n </svg>\n <div>\n <p className=\"text-sm font-medium text-status-warning-text\">Internal admin tool</p>\n <p className=\"text-xs text-status-warning-text/80 mt-0.5\">\n This bypasses all payment flows. The plan is assigned immediately with no charge. Use\n only for enterprise deals or internal accounts.\n </p>\n </div>\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"border border-border-subtle rounded-card bg-bg-surface overflow-hidden shadow-[var(--shadow-elevation-1)]\"\n >\n <div className=\"p-4 border-b border-border-subtle bg-bg-sunken/30\">\n <h2 className=\"font-semibold text-text-primary\">Assignment Details</h2>\n </div>\n\n <div className=\"p-4 space-y-4\">\n {/* Secret */}\n <div>\n <label htmlFor=\"secret\" className=\"block text-sm font-medium text-text-primary mb-1\">\n Team Secret <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n id=\"secret\"\n type=\"password\"\n value={secret}\n onChange={(e) => setSecret(e.target.value)}\n autoComplete=\"off\"\n className=\"w-full px-3 py-2 border border-border-subtle rounded-input bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] font-mono\"\n placeholder=\"Enter PLAN_ASSIGN_SECRET\"\n required\n />\n <p className=\"text-xs text-text-muted mt-1\">\n The secret key shared within the team. Never expose this to users.\n </p>\n </div>\n\n {/* Billing Account ID */}\n <div>\n <label\n htmlFor=\"billingAccountId\"\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n Billing Account ID <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n id=\"billingAccountId\"\n type=\"text\"\n value={billingAccountId}\n onChange={(e) => setBillingAccountId(e.target.value)}\n className=\"w-full px-3 py-2 border border-border-subtle rounded-input bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] font-mono text-sm\"\n placeholder=\"e.g. ba_01jk3n2...\"\n required\n />\n <p className=\"text-xs text-text-muted mt-1\">\n Find this in the user's billing account settings or via the billing accounts list.\n </p>\n </div>\n\n {/* Workspace ID (optional — auto-resolved from org if omitted) */}\n <div>\n <label htmlFor=\"workspaceId\" className=\"block text-sm font-medium text-foreground mb-1\">\n Workspace ID <span className=\"text-muted-foreground font-normal\">(optional)</span>\n </label>\n <input\n id=\"workspaceId\"\n type=\"text\"\n value={workspaceId}\n onChange={(e) => setWorkspaceId(e.target.value)}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary font-mono text-sm\"\n placeholder=\"e.g. ws_01jk3n2… (leave blank to auto-resolve)\"\n />\n <p className=\"text-xs text-muted-foreground mt-1\">\n If blank, the first active workspace for this org is used automatically. Set\n explicitly when the org has multiple workspaces.\n </p>\n </div>\n\n {/* Plan selector */}\n <div>\n <label htmlFor=\"planId\" className=\"block text-sm font-medium text-text-primary mb-1\">\n Plan <span className=\"text-status-error-text\">*</span>\n </label>\n {isPlansLoading ? (\n <div className=\"h-10 bg-bg-sunken animate-pulse rounded-md\" />\n ) : (\n <select\n id=\"planId\"\n value={planId}\n onChange={(e) => setPlanId(e.target.value)}\n className=\"w-full px-3 py-2 border border-border-subtle rounded-input bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n required\n >\n <option value=\"\" disabled>\n Select a plan…\n </option>\n {plans.map((plan) => (\n <option key={plan.id} value={plan.id}>\n {plan.name}\n {!plan.isPurchasable ? ' (internal)' : ''}\n {plan.price != null && plan.price > 0\n ? ` — ${plan.currency ?? 'USD'} ${plan.price}`\n : ''}\n </option>\n ))}\n </select>\n )}\n {selectedPlan && (\n <p className=\"text-xs text-text-muted mt-1\">\n {selectedPlan.isPurchasable ? 'Public plan' : 'Internal / non-purchasable plan'}\n {selectedPlan.productID ? ` · Product: ${selectedPlan.productID}` : ''}\n </p>\n )}\n </div>\n </div>\n\n {/* Result banner */}\n {result && (\n <div\n className={`mx-4 mb-4 p-3 rounded-lg border text-sm ${\n result.success\n ? 'border-status-success-border bg-status-success-bg/10 text-status-success-text'\n : 'border-status-error-border bg-status-error-bg/10 text-status-error-text'\n }`}\n >\n {result.message}\n </div>\n )}\n\n <div className=\"px-4 pb-4 flex items-center gap-3\">\n <button\n type=\"submit\"\n disabled={isAssigning || !secret || !billingAccountId || !planId}\n className=\"px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {isAssigning ? 'Assigning…' : 'Assign Plan for Free'}\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setSecret('');\n setBillingAccountId('');\n setPlanId('');\n setWorkspaceId('');\n setResult(null);\n }}\n className=\"px-4 py-2 text-sm border border-border-subtle rounded-md text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n Clear\n </button>\n </div>\n </form>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"PlanAssignFreePage.js","names":[],"sources":["../../../../../src/billing/modules/plans/pages/PlanAssignFreePage.tsx"],"sourcesContent":["/**\n * Plans Module - Assign Plan Free (Admin only)\n *\n * Internal tool for assigning any plan to a billing account at no charge.\n * Protected by PLAN_ASSIGN_SECRET — only team members who know the secret\n * can use this page. Never expose to end users.\n *\n * Route: /billing/plans/assign-free\n */\n\nimport { useState, type FC, type FormEvent } from 'react';\nimport { useBillingNavigate } from '../../../hooks/useBillingNavigate';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { AccessDenied, PageHeader } from '../../../shared/components';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useAssignPlanFreeMutation } from '../../../../generated/global-operations';\nimport { usePlans } from '../hooks';\n\nexport const PlanAssignFreePage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n\n const navigateTo = useBillingNavigate();\n const permissions = useBillingPermissions();\n\n const [secret, setSecret] = useState('');\n const [billingAccountId, setBillingAccountId] = useState('');\n const [planId, setPlanId] = useState('');\n const [workspaceId, setWorkspaceId] = useState('');\n const [result, setResult] = useState<{ success: boolean; message: string } | null>(null);\n\n // Fetch all plans (including non-purchasable internal ones) for the dropdown\n const { plans, isLoading: isPlansLoading } = usePlans({ includeFree: true });\n\n const [assignPlanFree, { loading: isAssigning }] = useAssignPlanFreeMutation();\n\n if (!permissions.canManagePlans) {\n return (\n <AccessDenied\n message={tr(\n 'billing.assignFree.noPermission',\n \"You don't have permission to access this page.\"\n )}\n />\n );\n }\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n setResult(null);\n\n if (!secret.trim() || !billingAccountId.trim() || !planId) {\n setResult({ success: false, message: 'All fields are required.' });\n return;\n }\n\n try {\n const { data } = await assignPlanFree({\n variables: {\n secret: secret.trim(),\n billingAccountId: billingAccountId.trim(),\n planId,\n ...(workspaceId.trim() ? { workspaceId: workspaceId.trim() } : {}),\n },\n });\n\n if (data?.assignPlanFree) {\n const sub = data.assignPlanFree;\n setResult({\n success: true,\n message: `Plan assigned. Subscription ID: ${sub.id} · Status: ${sub.status} · Valid: ${new Date(sub.startDate).toLocaleDateString()} → ${new Date(sub.endDate).toLocaleDateString()}`,\n });\n // Clear sensitive fields\n setSecret('');\n setBillingAccountId('');\n setPlanId('');\n setWorkspaceId('');\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to assign plan.';\n setResult({ success: false, message: msg });\n }\n };\n\n const selectedPlan = plans.find((p) => p.id === planId);\n\n return (\n <div className=\"space-y-6 p-6 max-w-2xl\">\n <PageHeader\n title={tr('billing.assignFree.title', 'Assign Plan for Free')}\n description={tr(\n 'billing.assignFree.description',\n 'Internally assign any plan to a billing account at no charge. Requires the team secret.'\n )}\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/plans')}\n className=\"px-3 py-2 text-sm border border-border-subtle rounded-md text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n ← Back to Plans\n </button>\n }\n />\n\n {/* Warning banner */}\n <div className=\"flex items-start gap-3 p-4 rounded-lg border border-status-warning-border bg-status-warning-bg/10\">\n <svg\n className=\"size-5 text-status-warning-text shrink-0 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.962-.833-2.732 0L3.072 16.5c-.77.833.192 2.5 1.732 2.5z\"\n />\n </svg>\n <div>\n <p className=\"text-sm font-medium text-status-warning-text\">Internal admin tool</p>\n <p className=\"text-xs text-status-warning-text/80 mt-0.5\">\n This bypasses all payment flows. The plan is assigned immediately with no charge. Use\n only for enterprise deals or internal accounts.\n </p>\n </div>\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"border border-border-subtle rounded-card bg-bg-surface overflow-hidden shadow-[var(--shadow-elevation-1)]\"\n >\n <div className=\"p-4 border-b border-border-subtle bg-bg-sunken/30\">\n <h2 className=\"font-semibold text-text-primary\">Assignment Details</h2>\n </div>\n\n <div className=\"p-4 space-y-4\">\n {/* Secret */}\n <div>\n <label htmlFor=\"secret\" className=\"block text-sm font-medium text-text-primary mb-1\">\n Team Secret <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n id=\"secret\"\n type=\"password\"\n value={secret}\n onChange={(e) => setSecret(e.target.value)}\n autoComplete=\"off\"\n className=\"w-full px-3 py-2 border border-border-subtle rounded-input bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] font-mono\"\n placeholder=\"Enter PLAN_ASSIGN_SECRET\"\n required\n />\n <p className=\"text-xs text-text-muted mt-1\">\n The secret key shared within the team. Never expose this to users.\n </p>\n </div>\n\n {/* Billing Account ID */}\n <div>\n <label\n htmlFor=\"billingAccountId\"\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n Billing Account ID <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n id=\"billingAccountId\"\n type=\"text\"\n value={billingAccountId}\n onChange={(e) => setBillingAccountId(e.target.value)}\n className=\"w-full px-3 py-2 border border-border-subtle rounded-input bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] font-mono text-sm\"\n placeholder=\"e.g. ba_01jk3n2...\"\n required\n />\n <p className=\"text-xs text-text-muted mt-1\">\n Find this in the user's billing account settings or via the billing accounts list.\n </p>\n </div>\n\n {/* Workspace ID (optional — auto-resolved from org if omitted) */}\n <div>\n <label htmlFor=\"workspaceId\" className=\"block text-sm font-medium text-text-primary mb-1\">\n Workspace ID <span className=\"text-text-secondary font-normal\">(optional)</span>\n </label>\n <input\n id=\"workspaceId\"\n type=\"text\"\n value={workspaceId}\n onChange={(e) => setWorkspaceId(e.target.value)}\n className=\"w-full px-3 py-2 border border-border-subtle rounded-md bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-primary font-mono text-sm\"\n placeholder=\"e.g. ws_01jk3n2… (leave blank to auto-resolve)\"\n />\n <p className=\"text-xs text-text-secondary mt-1\">\n If blank, the first active workspace for this org is used automatically. Set\n explicitly when the org has multiple workspaces.\n </p>\n </div>\n\n {/* Plan selector */}\n <div>\n <label htmlFor=\"planId\" className=\"block text-sm font-medium text-text-primary mb-1\">\n Plan <span className=\"text-status-error-text\">*</span>\n </label>\n {isPlansLoading ? (\n <div className=\"h-10 bg-bg-sunken animate-pulse rounded-md\" />\n ) : (\n <select\n id=\"planId\"\n value={planId}\n onChange={(e) => setPlanId(e.target.value)}\n className=\"w-full px-3 py-2 border border-border-subtle rounded-input bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n required\n >\n <option value=\"\" disabled>\n Select a plan…\n </option>\n {plans.map((plan) => (\n <option key={plan.id} value={plan.id}>\n {plan.name}\n {!plan.isPurchasable ? ' (internal)' : ''}\n {plan.price != null && plan.price > 0\n ? ` — ${plan.currency ?? 'USD'} ${plan.price}`\n : ''}\n </option>\n ))}\n </select>\n )}\n {selectedPlan && (\n <p className=\"text-xs text-text-muted mt-1\">\n {selectedPlan.isPurchasable ? 'Public plan' : 'Internal / non-purchasable plan'}\n {selectedPlan.productID ? ` · Product: ${selectedPlan.productID}` : ''}\n </p>\n )}\n </div>\n </div>\n\n {/* Result banner */}\n {result && (\n <div\n className={`mx-4 mb-4 p-3 rounded-lg border text-sm ${\n result.success\n ? 'border-status-success-border bg-status-success-bg/10 text-status-success-text'\n : 'border-status-error-border bg-status-error-bg/10 text-status-error-text'\n }`}\n >\n {result.message}\n </div>\n )}\n\n <div className=\"px-4 pb-4 flex items-center gap-3\">\n <button\n type=\"submit\"\n disabled={isAssigning || !secret || !billingAccountId || !planId}\n className=\"px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {isAssigning ? 'Assigning…' : 'Assign Plan for Free'}\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setSecret('');\n setBillingAccountId('');\n setPlanId('');\n setWorkspaceId('');\n setResult(null);\n }}\n className=\"px-4 py-2 text-sm border border-border-subtle rounded-md text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n Clear\n </button>\n </div>\n </form>\n </div>\n );\n};\n"],"mappings":"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"}