@burdenoff/microfe-billing 2026.614.1 → 2026.623.2

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 (135) hide show
  1. package/dist/billing/BillingAdminRoutes.js +7 -6
  2. package/dist/billing/BillingAdminRoutes.js.map +1 -1
  3. package/dist/billing/BillingRoot.js +1 -1
  4. package/dist/billing/BillingRoot.js.map +1 -1
  5. package/dist/billing/modules/addons/components/FloatingCartDrawer.js +22 -22
  6. package/dist/billing/modules/addons/components/FloatingCartDrawer.js.map +1 -1
  7. package/dist/billing/modules/addons/pages/AddonCreatePage.js +31 -31
  8. package/dist/billing/modules/addons/pages/AddonCreatePage.js.map +1 -1
  9. package/dist/billing/modules/addons/pages/AddonDetailPage.js +39 -39
  10. package/dist/billing/modules/addons/pages/AddonDetailPage.js.map +1 -1
  11. package/dist/billing/modules/addons/pages/AddonEditPage.js +29 -29
  12. package/dist/billing/modules/addons/pages/AddonEditPage.js.map +1 -1
  13. package/dist/billing/modules/addons/pages/AddonsListPage.js +91 -91
  14. package/dist/billing/modules/addons/pages/AddonsListPage.js.map +1 -1
  15. package/dist/billing/modules/analytics/pages/AnalyticsPage.js +40 -40
  16. package/dist/billing/modules/analytics/pages/AnalyticsPage.js.map +1 -1
  17. package/dist/billing/modules/billing/pages/InvoiceDetailPage.js +115 -115
  18. package/dist/billing/modules/billing/pages/InvoiceDetailPage.js.map +1 -1
  19. package/dist/billing/modules/billing/pages/InvoicesListPage.js +75 -72
  20. package/dist/billing/modules/billing/pages/InvoicesListPage.js.map +1 -1
  21. package/dist/billing/modules/billing/pages/RefundsPage.js +126 -126
  22. package/dist/billing/modules/billing/pages/RefundsPage.js.map +1 -1
  23. package/dist/billing/modules/billing/pages/UserRefundsPage.js +45 -45
  24. package/dist/billing/modules/billing/pages/UserRefundsPage.js.map +1 -1
  25. package/dist/billing/modules/checkout/components/BillingAccountSelector.js +25 -25
  26. package/dist/billing/modules/checkout/components/BillingAccountSelector.js.map +1 -1
  27. package/dist/billing/modules/checkout/components/CompleteBillingAccountModal.js +31 -35
  28. package/dist/billing/modules/checkout/components/CompleteBillingAccountModal.js.map +1 -1
  29. package/dist/billing/modules/checkout/components/CreditsAmountInput.js +9 -9
  30. package/dist/billing/modules/checkout/components/CreditsAmountInput.js.map +1 -1
  31. package/dist/billing/modules/checkout/components/OrderSummary.js +31 -31
  32. package/dist/billing/modules/checkout/components/OrderSummary.js.map +1 -1
  33. package/dist/billing/modules/checkout/components/PromoCodeInput.js +8 -8
  34. package/dist/billing/modules/checkout/components/PromoCodeInput.js.map +1 -1
  35. package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js +5 -5
  36. package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js.map +1 -1
  37. package/dist/billing/modules/checkout/components/SimpleAutoPayToggle.js +9 -9
  38. package/dist/billing/modules/checkout/components/SimpleAutoPayToggle.js.map +1 -1
  39. package/dist/billing/modules/checkout/components/StripePaymentForm.js +21 -21
  40. package/dist/billing/modules/checkout/components/StripePaymentForm.js.map +1 -1
  41. package/dist/billing/modules/checkout/components/SubscriptionSelector.js +11 -11
  42. package/dist/billing/modules/checkout/components/SubscriptionSelector.js.map +1 -1
  43. package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js +31 -31
  44. package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js.map +1 -1
  45. package/dist/billing/modules/checkout/components/WorkspaceQuotaAssignmentModal.js +23 -23
  46. package/dist/billing/modules/checkout/components/WorkspaceQuotaAssignmentModal.js.map +1 -1
  47. package/dist/billing/modules/checkout/pages/CheckoutPage.js +91 -91
  48. package/dist/billing/modules/checkout/pages/CheckoutPage.js.map +1 -1
  49. package/dist/billing/modules/coupons/pages/CouponDetailPage.js +62 -62
  50. package/dist/billing/modules/coupons/pages/CouponDetailPage.js.map +1 -1
  51. package/dist/billing/modules/coupons/pages/CouponsListPage.js +72 -60
  52. package/dist/billing/modules/coupons/pages/CouponsListPage.js.map +1 -1
  53. package/dist/billing/modules/coupons/pages/CreateCouponPage.js +66 -66
  54. package/dist/billing/modules/coupons/pages/CreateCouponPage.js.map +1 -1
  55. package/dist/billing/modules/coupons/pages/EditCouponPage.js +46 -46
  56. package/dist/billing/modules/coupons/pages/EditCouponPage.js.map +1 -1
  57. package/dist/billing/modules/credits/pages/AdminCreditsPage.js +19 -19
  58. package/dist/billing/modules/credits/pages/AdminCreditsPage.js.map +1 -1
  59. package/dist/billing/modules/credits/pages/CreditTransactionsPage.js +37 -37
  60. package/dist/billing/modules/credits/pages/CreditTransactionsPage.js.map +1 -1
  61. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js +90 -90
  62. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js.map +1 -1
  63. package/dist/billing/modules/credits/pages/CreditsPage.js +41 -41
  64. package/dist/billing/modules/credits/pages/CreditsPage.js.map +1 -1
  65. package/dist/billing/modules/dashboard/components/ActiveSubscriptionCard.js +31 -31
  66. package/dist/billing/modules/dashboard/components/ActiveSubscriptionCard.js.map +1 -1
  67. package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js +35 -35
  68. package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js.map +1 -1
  69. package/dist/billing/modules/dashboard/components/BillingAccountCard.js +24 -24
  70. package/dist/billing/modules/dashboard/components/BillingAccountCard.js.map +1 -1
  71. package/dist/billing/modules/dashboard/components/CreateBillingAccountModal.js +99 -99
  72. package/dist/billing/modules/dashboard/components/CreateBillingAccountModal.js.map +1 -1
  73. package/dist/billing/modules/dashboard/components/PaymentMethodsSection.js +23 -23
  74. package/dist/billing/modules/dashboard/components/PaymentMethodsSection.js.map +1 -1
  75. package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js +22 -22
  76. package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js.map +1 -1
  77. package/dist/billing/modules/dashboard/pages/OverviewPage.js +58 -58
  78. package/dist/billing/modules/dashboard/pages/OverviewPage.js.map +1 -1
  79. package/dist/billing/modules/discounts/pages/DiscountsListPage.js +126 -126
  80. package/dist/billing/modules/discounts/pages/DiscountsListPage.js.map +1 -1
  81. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +83 -79
  82. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
  83. package/dist/billing/modules/plans/pages/PlanAssignFreePage.js +16 -16
  84. package/dist/billing/modules/plans/pages/PlanAssignFreePage.js.map +1 -1
  85. package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js +40 -40
  86. package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js.map +1 -1
  87. package/dist/billing/modules/plans/pages/PlanCreatePage.js +35 -35
  88. package/dist/billing/modules/plans/pages/PlanCreatePage.js.map +1 -1
  89. package/dist/billing/modules/plans/pages/PlanDetailPage.js +57 -57
  90. package/dist/billing/modules/plans/pages/PlanDetailPage.js.map +1 -1
  91. package/dist/billing/modules/plans/pages/PlanEditPage.js +35 -35
  92. package/dist/billing/modules/plans/pages/PlanEditPage.js.map +1 -1
  93. package/dist/billing/modules/plans/pages/PlansBrowsePage.js +57 -57
  94. package/dist/billing/modules/plans/pages/PlansBrowsePage.js.map +1 -1
  95. package/dist/billing/modules/plans/pages/PlansListPage.js +52 -52
  96. package/dist/billing/modules/plans/pages/PlansListPage.js.map +1 -1
  97. package/dist/billing/modules/promotions/pages/CreatePromotionPage.js +40 -39
  98. package/dist/billing/modules/promotions/pages/CreatePromotionPage.js.map +1 -1
  99. package/dist/billing/modules/promotions/pages/PromotionsListPage.js +22 -19
  100. package/dist/billing/modules/promotions/pages/PromotionsListPage.js.map +1 -1
  101. package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js +34 -34
  102. package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js.map +1 -1
  103. package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js +47 -47
  104. package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js.map +1 -1
  105. package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js +39 -39
  106. package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js.map +1 -1
  107. package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js +52 -52
  108. package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js.map +1 -1
  109. package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js +23 -23
  110. package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js.map +1 -1
  111. package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js +259 -246
  112. package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js.map +1 -1
  113. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js +88 -85
  114. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
  115. package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js +51 -51
  116. package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js.map +1 -1
  117. package/dist/billing/modules/usage/pages/UsagePage.js +206 -196
  118. package/dist/billing/modules/usage/pages/UsagePage.js.map +1 -1
  119. package/dist/billing/shared/components/ServerError.js +4 -4
  120. package/dist/billing/shared/components/ServerError.js.map +1 -1
  121. package/dist/billing/shared/components/StatCard.js +11 -33
  122. package/dist/billing/shared/components/StatCard.js.map +1 -1
  123. package/dist/billing/shared/ui/Card.js +15 -0
  124. package/dist/billing/shared/ui/Card.js.map +1 -0
  125. package/dist/billing/shared/ui/MetricCard.js +44 -0
  126. package/dist/billing/shared/ui/MetricCard.js.map +1 -0
  127. package/dist/billing/shared/ui/ProgressBar.js +30 -0
  128. package/dist/billing/shared/ui/ProgressBar.js.map +1 -0
  129. package/dist/billing/shared/ui/SectionHeader.js +2 -0
  130. package/dist/billing/shared/ui/StatusPill.js +28 -0
  131. package/dist/billing/shared/ui/StatusPill.js.map +1 -0
  132. package/dist/billing/shared/ui/index.js +5 -0
  133. package/dist/billing/shared/utils/tokens.js +13 -30
  134. package/dist/billing/shared/utils/tokens.js.map +1 -1
  135. package/package.json +1 -1
@@ -47,7 +47,7 @@ var y = () => {
47
47
  }, [w]), !C.canManagePlans) return /* @__PURE__ */ g(e, { message: b("billing.plans.noEditPermission", "You don't have permission to edit plans.") });
48
48
  if (T || k) return /* @__PURE__ */ _("div", {
49
49
  className: "space-y-6 p-6",
50
- children: [/* @__PURE__ */ g("div", { className: "h-8 w-48 bg-muted animate-pulse rounded" }), /* @__PURE__ */ g("div", {
50
+ children: [/* @__PURE__ */ g("div", { className: "h-8 w-48 bg-bg-sunken animate-pulse rounded" }), /* @__PURE__ */ g("div", {
51
51
  className: "max-w-2xl space-y-4",
52
52
  children: [
53
53
  1,
@@ -55,7 +55,7 @@ var y = () => {
55
55
  3,
56
56
  4,
57
57
  5
58
- ].map((e) => /* @__PURE__ */ g("div", { className: "h-16 bg-muted animate-pulse rounded" }, e))
58
+ ].map((e) => /* @__PURE__ */ g("div", { className: "h-16 bg-bg-sunken animate-pulse rounded" }, e))
59
59
  })]
60
60
  });
61
61
  if (E && a(E)) return /* @__PURE__ */ g("div", {
@@ -72,12 +72,12 @@ var y = () => {
72
72
  children: /* @__PURE__ */ _("div", {
73
73
  className: "text-center space-y-4",
74
74
  children: [/* @__PURE__ */ g("h2", {
75
- className: "text-lg font-semibold text-foreground",
75
+ className: "text-lg font-semibold text-text-primary",
76
76
  children: b("billing.plans.planNotFound", "Plan not found")
77
77
  }), /* @__PURE__ */ g("button", {
78
78
  type: "button",
79
79
  onClick: () => S("/plans"),
80
- className: "px-4 py-2 text-sm font-medium bg-primary text-primary-foreground rounded-md hover:bg-primary/90",
80
+ className: "px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover",
81
81
  children: "Back to Plans"
82
82
  })]
83
83
  })
@@ -155,11 +155,11 @@ var y = () => {
155
155
  /* @__PURE__ */ _("div", {
156
156
  className: "grid grid-cols-1 lg:grid-cols-2 gap-6",
157
157
  children: [/* @__PURE__ */ _("div", {
158
- className: "border border-border rounded-lg bg-card overflow-hidden h-fit",
158
+ className: "border border-border-subtle rounded-card bg-bg-surface overflow-hidden shadow-[var(--shadow-elevation-1)] h-fit",
159
159
  children: [/* @__PURE__ */ g("div", {
160
- className: "p-4 border-b border-border bg-muted/30",
160
+ className: "p-4 border-b border-border-subtle bg-bg-sunken/30",
161
161
  children: /* @__PURE__ */ g("h2", {
162
- className: "font-semibold text-foreground",
162
+ className: "font-semibold text-text-primary",
163
163
  children: b("billing.plans.basicInfo", "Basic Information")
164
164
  })
165
165
  }), /* @__PURE__ */ _("div", {
@@ -167,14 +167,14 @@ var y = () => {
167
167
  children: [
168
168
  /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ _("label", {
169
169
  htmlFor: "name",
170
- className: "block text-sm font-medium text-foreground mb-1",
170
+ className: "block text-sm font-medium text-text-primary mb-1",
171
171
  children: [b("billing.plans.planNameLabel", "Plan Name"), " *"]
172
172
  }), /* @__PURE__ */ g("input", {
173
173
  id: "name",
174
174
  type: "text",
175
175
  value: j,
176
176
  onChange: (e) => M(e.target.value),
177
- 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",
177
+ 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)]",
178
178
  placeholder: b("billing.plans.planNamePlaceholder", "e.g., Pro Plan"),
179
179
  required: !0
180
180
  })] }),
@@ -182,7 +182,7 @@ var y = () => {
182
182
  className: "grid grid-cols-2 gap-4",
183
183
  children: [/* @__PURE__ */ _("div", { children: [/* @__PURE__ */ _("label", {
184
184
  htmlFor: "price",
185
- className: "block text-sm font-medium text-foreground mb-1",
185
+ className: "block text-sm font-medium text-text-primary mb-1",
186
186
  children: [b("billing.plans.priceLabel", "Price"), " *"]
187
187
  }), /* @__PURE__ */ g("input", {
188
188
  id: "price",
@@ -191,18 +191,18 @@ var y = () => {
191
191
  min: "0",
192
192
  value: N,
193
193
  onChange: (e) => P(e.target.value),
194
- 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",
194
+ 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)]",
195
195
  placeholder: "49.99",
196
196
  required: !0
197
197
  })] }), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ _("label", {
198
198
  htmlFor: "currency",
199
- className: "block text-sm font-medium text-foreground mb-1",
199
+ className: "block text-sm font-medium text-text-primary mb-1",
200
200
  children: [b("billing.plans.currencyLabel", "Currency"), " *"]
201
201
  }), /* @__PURE__ */ _("select", {
202
202
  id: "currency",
203
203
  value: F,
204
204
  onChange: (e) => I(e.target.value),
205
- 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",
205
+ 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)]",
206
206
  children: [
207
207
  /* @__PURE__ */ g("option", {
208
208
  value: "USD",
@@ -241,13 +241,13 @@ var y = () => {
241
241
  }),
242
242
  /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ _("label", {
243
243
  htmlFor: "duration",
244
- className: "block text-sm font-medium text-foreground mb-1",
244
+ className: "block text-sm font-medium text-text-primary mb-1",
245
245
  children: [b("billing.plans.billingPeriodLabel", "Billing Period"), " *"]
246
246
  }), /* @__PURE__ */ _("select", {
247
247
  id: "duration",
248
248
  value: L,
249
249
  onChange: (e) => R(e.target.value),
250
- 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",
250
+ 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)]",
251
251
  children: [/* @__PURE__ */ g("option", {
252
252
  value: i.MONTHLY,
253
253
  children: "Monthly"
@@ -263,60 +263,60 @@ var y = () => {
263
263
  type: "checkbox",
264
264
  checked: z,
265
265
  onChange: (e) => B(e.target.checked),
266
- className: "size-4 rounded border-border text-primary focus:ring-primary"
266
+ className: "size-4 rounded border-border-subtle text-text-link focus:ring-[var(--color-focus-ring)]"
267
267
  }), /* @__PURE__ */ g("label", {
268
268
  htmlFor: "isActive",
269
- className: "text-sm font-medium text-foreground",
269
+ className: "text-sm font-medium text-text-primary",
270
270
  children: b("billing.plans.planIsActive", "Plan is active")
271
271
  })]
272
272
  }),
273
273
  /* @__PURE__ */ _("div", {
274
274
  className: "flex items-start justify-between gap-4 pt-1",
275
275
  children: [/* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("p", {
276
- className: "text-sm font-medium text-foreground",
276
+ className: "text-sm font-medium text-text-primary",
277
277
  children: b("billing.plans.isPurchasableLabel", "Publicly purchasable")
278
278
  }), /* @__PURE__ */ g("p", {
279
- className: "text-xs text-muted-foreground mt-0.5",
279
+ className: "text-xs text-text-muted mt-0.5",
280
280
  children: V ? b("billing.plans.isPurchasableOn", "Visible on pricing page — users can subscribe directly.") : b("billing.plans.isPurchasableOff", "Internal / custom plan — hidden from pricing page, assign via API only.")
281
281
  })] }), /* @__PURE__ */ g("button", {
282
282
  type: "button",
283
283
  role: "switch",
284
284
  "aria-checked": V,
285
285
  onClick: () => H((e) => !e),
286
- className: `relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 ${V ? "bg-primary" : "bg-muted-foreground/30"}`,
287
- children: /* @__PURE__ */ g("span", { className: `inline-block h-5 w-5 transform rounded-full bg-white shadow transition-transform ${V ? "translate-x-5" : "translate-x-0"}` })
286
+ className: `relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:ring-offset-2 ${V ? "bg-action-primary-bg" : "bg-text-muted/30"}`,
287
+ children: /* @__PURE__ */ g("span", { className: `inline-block h-5 w-5 transform rounded-full bg-bg-surface shadow transition-transform ${V ? "translate-x-5" : "translate-x-0"}` })
288
288
  })]
289
289
  })
290
290
  ]
291
291
  })]
292
292
  }), /* @__PURE__ */ _("div", {
293
- className: "border border-border rounded-lg bg-card overflow-hidden h-fit",
293
+ className: "border border-border-subtle rounded-card bg-bg-surface overflow-hidden shadow-[var(--shadow-elevation-1)] h-fit",
294
294
  children: [/* @__PURE__ */ _("div", {
295
- className: "p-4 border-b border-border bg-muted/30 flex items-center justify-between",
295
+ className: "p-4 border-b border-border-subtle bg-bg-sunken/30 flex items-center justify-between",
296
296
  children: [/* @__PURE__ */ g("h2", {
297
- className: "font-semibold text-foreground",
297
+ className: "font-semibold text-text-primary",
298
298
  children: b("billing.plans.quotaAllocations", "Quota Allocations")
299
299
  }), /* @__PURE__ */ g("button", {
300
300
  type: "button",
301
301
  onClick: Z,
302
- className: "px-3 py-1 text-sm font-medium text-primary hover:bg-primary/10 rounded-md transition-colors",
302
+ className: "px-3 py-1 text-sm font-medium text-text-link hover:bg-[var(--color-accent-soft)] rounded-md transition-colors",
303
303
  children: "+ Add Quota"
304
304
  })]
305
305
  }), /* @__PURE__ */ g("div", {
306
306
  className: "p-4 space-y-3",
307
307
  children: U.length === 0 ? /* @__PURE__ */ g("p", {
308
- className: "text-sm text-muted-foreground",
308
+ className: "text-sm text-text-muted",
309
309
  children: b("billing.plans.noQuotasAllocated", "No quotas allocated. Click \"Add Quota\" to add one.")
310
310
  }) : U.map((e, t) => {
311
311
  let n = O.find((t) => t.id === e.quotaId), r = n?.limits, i = r?.value ?? 0, a = r?.type ?? "unknown", o = i * e.quantity;
312
312
  return /* @__PURE__ */ _("div", {
313
- className: "p-3 border border-border rounded-lg bg-muted/20 space-y-3",
313
+ className: "p-3 border border-border-subtle rounded-lg bg-bg-sunken/20 space-y-3",
314
314
  children: [/* @__PURE__ */ _("div", {
315
315
  className: "flex items-center gap-3",
316
316
  children: [/* @__PURE__ */ _("select", {
317
317
  value: e.quotaId,
318
318
  onChange: (e) => $(t, "quotaId", e.target.value),
319
- className: `flex-1 px-3 py-2 border border-border rounded-md bg-background focus:outline-none focus:ring-2 focus:ring-primary ${e.quotaId === "" ? "text-muted-foreground" : "text-foreground"}`,
319
+ className: `flex-1 px-3 py-2 border border-border-subtle rounded-input bg-bg-surface focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] ${e.quotaId === "" ? "text-text-muted" : "text-text-primary"}`,
320
320
  children: [/* @__PURE__ */ g("option", {
321
321
  value: "",
322
322
  disabled: !0,
@@ -346,7 +346,7 @@ var y = () => {
346
346
  }), n && /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g("div", {
347
347
  className: "flex items-center justify-between text-sm",
348
348
  children: /* @__PURE__ */ _("div", {
349
- className: "text-muted-foreground",
349
+ className: "text-text-muted",
350
350
  children: [
351
351
  /* @__PURE__ */ _("span", {
352
352
  className: "capitalize",
@@ -360,7 +360,7 @@ var y = () => {
360
360
  "Value per unit:",
361
361
  " ",
362
362
  /* @__PURE__ */ g("span", {
363
- className: "font-medium text-foreground",
363
+ className: "font-medium text-text-primary",
364
364
  children: i.toLocaleString()
365
365
  })
366
366
  ] })
@@ -371,19 +371,19 @@ var y = () => {
371
371
  children: [/* @__PURE__ */ _("div", {
372
372
  className: "flex items-center gap-2",
373
373
  children: [/* @__PURE__ */ _("label", {
374
- className: "text-sm text-muted-foreground",
374
+ className: "text-sm text-text-muted",
375
375
  children: [b("billing.plans.quantity", "Quantity"), ":"]
376
376
  }), /* @__PURE__ */ g("input", {
377
377
  type: "number",
378
378
  min: "1",
379
379
  value: e.quantity,
380
380
  onChange: (e) => $(t, "quantity", e.target.value),
381
- className: "w-24 px-3 py-1.5 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary text-center"
381
+ className: "w-24 px-3 py-1.5 border border-border-subtle rounded-input bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] text-center"
382
382
  })]
383
383
  }), /* @__PURE__ */ _("div", {
384
384
  className: "flex items-center gap-2 text-sm",
385
385
  children: [/* @__PURE__ */ g("span", {
386
- className: "text-muted-foreground",
386
+ className: "text-text-muted",
387
387
  children: "="
388
388
  }), /* @__PURE__ */ _("span", {
389
389
  className: "font-semibold text-status-success-text",
@@ -405,12 +405,12 @@ var y = () => {
405
405
  children: [/* @__PURE__ */ g("button", {
406
406
  type: "submit",
407
407
  disabled: A,
408
- className: "px-6 py-2 text-sm font-medium bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors disabled:opacity-50",
408
+ className: "px-6 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",
409
409
  children: A ? b("billing.plans.saving", "Saving...") : b("billing.plans.saveChanges", "Save Changes")
410
410
  }), /* @__PURE__ */ g("button", {
411
411
  type: "button",
412
412
  onClick: () => S(`/plans/${x}`),
413
- className: "px-6 py-2 text-sm font-medium border border-border text-foreground rounded-md hover:bg-muted transition-colors",
413
+ className: "px-6 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors",
414
414
  children: "Cancel"
415
415
  })]
416
416
  })
@@ -1 +1 @@
1
- {"version":3,"file":"PlanEditPage.js","names":[],"sources":["../../../../../src/billing/modules/plans/pages/PlanEditPage.tsx"],"sourcesContent":["/**\n * Plans Module - Plan Edit Page\n * Form to edit an existing plan\n */\n\nimport { useState, useEffect, type FC, type FormEvent } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useBillingNavigate } from '../../../hooks/useBillingNavigate';\nimport { usePlan, usePlanMutations, useQuotas } from '../hooks';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport {\n AccessDenied,\n CurrencyPriceOverridesEditor,\n PageHeader,\n ServerError,\n} from '../../../shared/components';\nimport { getPlanFeatureQuantity, isServerError } from '../../../shared/utils';\nimport {\n PlanDuration,\n type CurrencyPriceOverrideInput,\n type UpdatePlanInput,\n} from '../../../shared/types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface QuotaAllocation {\n quotaId: string;\n quantity: number;\n}\n\nexport const PlanEditPage: 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 const { planId } = useParams<{ planId: string }>();\n const navigateTo = useBillingNavigate();\n const permissions = useBillingPermissions();\n const { plan, isLoading: isPlanLoading, error: planError, refetch } = usePlan(planId);\n const { quotas, isLoading: isQuotasLoading } = useQuotas({ onlyActive: true });\n const { updatePlan, isUpdating } = usePlanMutations();\n\n // Form state\n const [name, setName] = useState('');\n const [price, setPrice] = useState('');\n const [currency, setCurrency] = useState('USD');\n const [duration, setDuration] = useState<PlanDuration>(PlanDuration.MONTHLY);\n const [isActive, setIsActive] = useState(true);\n const [isPurchasable, setIsPurchasable] = useState(true);\n const [quotaAllocations, setQuotaAllocations] = useState<QuotaAllocation[]>([]);\n const [currencyPriceOverrides, setCurrencyPriceOverrides] = useState<\n CurrencyPriceOverrideInput[]\n >([]);\n const [error, setError] = useState<string | null>(null);\n const [success, setSuccess] = useState(false);\n\n // Populate form when plan data loads\n useEffect(() => {\n if (plan) {\n setName(plan.name ?? '');\n setPrice(String(plan.price ?? ''));\n setCurrency(plan.currency ?? 'USD');\n setDuration(plan.duration ?? PlanDuration.MONTHLY);\n setIsActive(plan.isActive ?? true);\n setIsPurchasable(plan.isPurchasable ?? true);\n // Pre-populate currency price overrides so existing prices are preserved on save\n if (plan.currencyPrices && typeof plan.currencyPrices === 'object') {\n const existing = plan.currencyPrices as Record<string, number>;\n setCurrencyPriceOverrides(\n Object.entries(existing)\n .filter(([, v]) => typeof v === 'number')\n .map(([currency, amount]) => ({ currency, amount }))\n );\n }\n // Extract quota allocations from features\n if (plan.features && plan.features.length > 0) {\n const allocations: QuotaAllocation[] = [];\n const quotaMap = new Map<string, number>();\n\n for (const feature of plan.features) {\n if (feature.quota?.id) {\n const quotaId = feature.quota.id;\n // SubscriptionFeature now stores per-plan override in context.quantity.\n // Fall back to quota.limits.value for legacy autoseeded plans.\n const value = getPlanFeatureQuantity(feature) || 1;\n quotaMap.set(quotaId, value);\n }\n }\n\n for (const [quotaId, quantity] of quotaMap) {\n allocations.push({ quotaId, quantity });\n }\n\n setQuotaAllocations(allocations);\n }\n }\n }, [plan]);\n\n // Permission check\n if (!permissions.canManagePlans) {\n return (\n <AccessDenied\n message={tr('billing.plans.noEditPermission', \"You don't have permission to edit plans.\")}\n />\n );\n }\n\n // Loading state\n if (isPlanLoading || isQuotasLoading) {\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"h-8 w-48 bg-muted animate-pulse rounded\" />\n <div className=\"max-w-2xl space-y-4\">\n {[1, 2, 3, 4, 5].map((i) => (\n <div key={i} className=\"h-16 bg-muted animate-pulse rounded\" />\n ))}\n </div>\n </div>\n );\n }\n\n // Error state\n if (planError && isServerError(planError)) {\n return (\n <div className=\"p-6\">\n <ServerError\n title={tr('billing.plans.serverUnavailable', 'Server Unavailable')}\n message={tr(\n 'billing.plans.serverUnavailableLoadPlan',\n 'Unable to load plan. The server might be down or experiencing issues.'\n )}\n onRetry={() => refetch()}\n showRetry\n />\n </div>\n );\n }\n\n if (!plan) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-4\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n {tr('billing.plans.planNotFound', 'Plan not found')}\n </h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/plans')}\n className=\"px-4 py-2 text-sm font-medium bg-primary text-primary-foreground rounded-md hover:bg-primary/90\"\n >\n Back to Plans\n </button>\n </div>\n </div>\n );\n }\n\n const handleAddQuota = () => {\n // Add new quota at the top with empty quotaId (placeholder)\n setQuotaAllocations([{ quotaId: '', quantity: 1 }, ...quotaAllocations]);\n };\n\n const handleRemoveQuota = (index: number) => {\n setQuotaAllocations(quotaAllocations.filter((_, i) => i !== index));\n };\n\n const handleQuotaChange = (\n index: number,\n field: 'quotaId' | 'quantity',\n value: string | number\n ) => {\n const updated = [...quotaAllocations];\n if (field === 'quotaId') {\n updated[index].quotaId = value as string;\n } else {\n updated[index].quantity = Number(value);\n }\n setQuotaAllocations(updated);\n };\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n setError(null);\n setSuccess(false);\n\n // Validation\n if (!name.trim()) {\n setError('Plan name is required');\n return;\n }\n if (!price || isNaN(Number(price)) || Number(price) < 0) {\n setError('Valid price is required');\n return;\n }\n if (quotaAllocations.length === 0) {\n setError('At least one quota is required');\n return;\n }\n // Check for unselected quotas\n const unselectedQuotas = quotaAllocations.filter((a) => a.quotaId === '');\n if (unselectedQuotas.length > 0) {\n setError('Please select a quota for all allocations');\n return;\n }\n\n const input: UpdatePlanInput = {\n id: planId!,\n name: name.trim(),\n price: Number(price),\n currency,\n duration,\n isActive,\n isPurchasable,\n quotas: quotaAllocations.map((a) => ({\n quotaId: a.quotaId,\n quantity: a.quantity,\n })),\n ...(currencyPriceOverrides.length > 0 ? { currencyPriceOverrides } : {}),\n };\n\n try {\n await updatePlan(input);\n setSuccess(true);\n // Navigate back after short delay\n setTimeout(() => navigateTo(`/plans/${planId}`), 1500);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to update plan');\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title={`Edit Plan: ${plan.name}`}\n description={tr(\n 'billing.plans.editPlanDesc',\n 'Update the plan details and quota allocations'\n )}\n />\n\n <form onSubmit={handleSubmit} className=\"space-y-6\">\n {/* Error/Success Messages */}\n {error && (\n <div className=\"p-4 bg-status-error-bg-subtle border border-border-subtle rounded-lg\">\n <p className=\"text-sm text-status-error-text\">{error}</p>\n </div>\n )}\n {success && (\n <div className=\"p-4 bg-status-success-bg-subtle border border-border-subtle rounded-lg\">\n <p className=\"text-sm text-status-success-text\">\n {tr('billing.plans.updateSuccess', 'Plan updated successfully! Redirecting...')}\n </p>\n </div>\n )}\n\n {/* Two-column layout on desktop */}\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n {/* Basic Info */}\n <div className=\"border border-border rounded-lg bg-card overflow-hidden h-fit\">\n <div className=\"p-4 border-b border-border bg-muted/30\">\n <h2 className=\"font-semibold text-foreground\">\n {tr('billing.plans.basicInfo', 'Basic Information')}\n </h2>\n </div>\n <div className=\"p-4 space-y-4\">\n {/* Name */}\n <div>\n <label htmlFor=\"name\" className=\"block text-sm font-medium text-foreground mb-1\">\n {tr('billing.plans.planNameLabel', 'Plan Name')} *\n </label>\n <input\n id=\"name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(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\"\n placeholder={tr('billing.plans.planNamePlaceholder', 'e.g., Pro Plan')}\n required\n />\n </div>\n\n {/* Price & Currency */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label htmlFor=\"price\" className=\"block text-sm font-medium text-foreground mb-1\">\n {tr('billing.plans.priceLabel', 'Price')} *\n </label>\n <input\n id=\"price\"\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n value={price}\n onChange={(e) => setPrice(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\"\n placeholder=\"49.99\"\n required\n />\n </div>\n <div>\n <label\n htmlFor=\"currency\"\n className=\"block text-sm font-medium text-foreground mb-1\"\n >\n {tr('billing.plans.currencyLabel', 'Currency')} *\n </label>\n <select\n id=\"currency\"\n value={currency}\n onChange={(e) => setCurrency(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\"\n >\n <option value=\"USD\">USD ($)</option>\n <option value=\"EUR\">EUR</option>\n <option value=\"GBP\">GBP</option>\n <option value=\"INR\">INR</option>\n <option value=\"AUD\">AUD</option>\n <option value=\"CAD\">CAD</option>\n <option value=\"JPY\">JPY</option>\n <option value=\"SGD\">SGD</option>\n </select>\n </div>\n </div>\n\n {/* Duration */}\n <div>\n <label\n htmlFor=\"duration\"\n className=\"block text-sm font-medium text-foreground mb-1\"\n >\n {tr('billing.plans.billingPeriodLabel', 'Billing Period')} *\n </label>\n <select\n id=\"duration\"\n value={duration}\n onChange={(e) => setDuration(e.target.value as PlanDuration)}\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\"\n >\n <option value={PlanDuration.MONTHLY}>Monthly</option>\n <option value={PlanDuration.YEARLY}>Yearly</option>\n </select>\n </div>\n\n {/* Status */}\n <div className=\"flex items-center gap-3\">\n <input\n id=\"isActive\"\n type=\"checkbox\"\n checked={isActive}\n onChange={(e) => setIsActive(e.target.checked)}\n className=\"size-4 rounded border-border text-primary focus:ring-primary\"\n />\n <label htmlFor=\"isActive\" className=\"text-sm font-medium text-foreground\">\n {tr('billing.plans.planIsActive', 'Plan is active')}\n </label>\n </div>\n\n {/* Purchasable toggle */}\n <div className=\"flex items-start justify-between gap-4 pt-1\">\n <div>\n <p className=\"text-sm font-medium text-foreground\">\n {tr('billing.plans.isPurchasableLabel', 'Publicly purchasable')}\n </p>\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n {isPurchasable\n ? tr(\n 'billing.plans.isPurchasableOn',\n 'Visible on pricing page — users can subscribe directly.'\n )\n : tr(\n 'billing.plans.isPurchasableOff',\n 'Internal / custom plan — hidden from pricing page, assign via API only.'\n )}\n </p>\n </div>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={isPurchasable}\n onClick={() => setIsPurchasable((v) => !v)}\n className={`relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 ${\n isPurchasable ? 'bg-primary' : 'bg-muted-foreground/30'\n }`}\n >\n <span\n className={`inline-block h-5 w-5 transform rounded-full bg-white shadow transition-transform ${\n isPurchasable ? 'translate-x-5' : 'translate-x-0'\n }`}\n />\n </button>\n </div>\n </div>\n </div>\n\n {/* Quota Allocations */}\n <div className=\"border border-border rounded-lg bg-card overflow-hidden h-fit\">\n <div className=\"p-4 border-b border-border bg-muted/30 flex items-center justify-between\">\n <h2 className=\"font-semibold text-foreground\">\n {tr('billing.plans.quotaAllocations', 'Quota Allocations')}\n </h2>\n <button\n type=\"button\"\n onClick={handleAddQuota}\n className=\"px-3 py-1 text-sm font-medium text-primary hover:bg-primary/10 rounded-md transition-colors\"\n >\n + Add Quota\n </button>\n </div>\n <div className=\"p-4 space-y-3\">\n {quotaAllocations.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">\n {tr(\n 'billing.plans.noQuotasAllocated',\n 'No quotas allocated. Click \"Add Quota\" to add one.'\n )}\n </p>\n ) : (\n quotaAllocations.map((allocation, index) => {\n const selectedQuota = quotas.find((q) => q.id === allocation.quotaId);\n const limits = selectedQuota?.limits as { type?: string; value?: number } | null;\n const limitValue = limits?.value ?? 0;\n const limitType = limits?.type ?? 'unknown';\n const totalValue = limitValue * allocation.quantity;\n\n return (\n <div\n key={index}\n className=\"p-3 border border-border rounded-lg bg-muted/20 space-y-3\"\n >\n <div className=\"flex items-center gap-3\">\n <select\n value={allocation.quotaId}\n onChange={(e) => handleQuotaChange(index, 'quotaId', e.target.value)}\n className={`flex-1 px-3 py-2 border border-border rounded-md bg-background focus:outline-none focus:ring-2 focus:ring-primary ${\n allocation.quotaId === '' ? 'text-muted-foreground' : 'text-foreground'\n }`}\n >\n <option value=\"\" disabled>\n {tr('billing.plans.selectQuota', 'Select a quota...')}\n </option>\n {quotas.map((quota) => (\n <option key={quota.id} value={quota.id}>\n {quota.name}\n </option>\n ))}\n </select>\n <button\n type=\"button\"\n onClick={() => handleRemoveQuota(index)}\n className=\"p-2 text-status-error-text hover:bg-status-error-bg-subtle rounded-md transition-colors\"\n title=\"Remove quota\"\n >\n <svg\n className=\"size-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=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n />\n </svg>\n </button>\n </div>\n\n {/* Quota Info - only show when quota is selected */}\n {selectedQuota && (\n <>\n <div className=\"flex items-center justify-between text-sm\">\n <div className=\"text-muted-foreground\">\n <span className=\"capitalize\">Type: {limitType}</span>\n <span className=\"mx-2\">•</span>\n <span>\n Value per unit:{' '}\n <span className=\"font-medium text-foreground\">\n {limitValue.toLocaleString()}\n </span>\n </span>\n </div>\n </div>\n\n {/* Quantity & Total */}\n <div className=\"flex items-center gap-4\">\n <div className=\"flex items-center gap-2\">\n <label className=\"text-sm text-muted-foreground\">\n {tr('billing.plans.quantity', 'Quantity')}:\n </label>\n <input\n type=\"number\"\n min=\"1\"\n value={allocation.quantity}\n onChange={(e) =>\n handleQuotaChange(index, 'quantity', e.target.value)\n }\n className=\"w-24 px-3 py-1.5 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary text-center\"\n />\n </div>\n <div className=\"flex items-center gap-2 text-sm\">\n <span className=\"text-muted-foreground\">=</span>\n <span className=\"font-semibold text-status-success-text\">\n {totalValue.toLocaleString()} total\n </span>\n </div>\n </div>\n </>\n )}\n </div>\n );\n })\n )}\n </div>\n </div>\n </div>\n\n <CurrencyPriceOverridesEditor\n overrides={currencyPriceOverrides}\n onChange={setCurrencyPriceOverrides}\n />\n\n {/* Actions */}\n <div className=\"flex items-center gap-3 pt-4\">\n <button\n type=\"submit\"\n disabled={isUpdating}\n className=\"px-6 py-2 text-sm font-medium bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors disabled:opacity-50\"\n >\n {isUpdating\n ? tr('billing.plans.saving', 'Saving...')\n : tr('billing.plans.saveChanges', 'Save Changes')}\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/plans/${planId}`)}\n className=\"px-6 py-2 text-sm font-medium border border-border text-foreground rounded-md hover:bg-muted transition-colors\"\n >\n Cancel\n </button>\n </div>\n </form>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"PlanEditPage.js","names":[],"sources":["../../../../../src/billing/modules/plans/pages/PlanEditPage.tsx"],"sourcesContent":["/**\n * Plans Module - Plan Edit Page\n * Form to edit an existing plan\n */\n\nimport { useState, useEffect, type FC, type FormEvent } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useBillingNavigate } from '../../../hooks/useBillingNavigate';\nimport { usePlan, usePlanMutations, useQuotas } from '../hooks';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport {\n AccessDenied,\n CurrencyPriceOverridesEditor,\n PageHeader,\n ServerError,\n} from '../../../shared/components';\nimport { getPlanFeatureQuantity, isServerError } from '../../../shared/utils';\nimport {\n PlanDuration,\n type CurrencyPriceOverrideInput,\n type UpdatePlanInput,\n} from '../../../shared/types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface QuotaAllocation {\n quotaId: string;\n quantity: number;\n}\n\nexport const PlanEditPage: 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 const { planId } = useParams<{ planId: string }>();\n const navigateTo = useBillingNavigate();\n const permissions = useBillingPermissions();\n const { plan, isLoading: isPlanLoading, error: planError, refetch } = usePlan(planId);\n const { quotas, isLoading: isQuotasLoading } = useQuotas({ onlyActive: true });\n const { updatePlan, isUpdating } = usePlanMutations();\n\n // Form state\n const [name, setName] = useState('');\n const [price, setPrice] = useState('');\n const [currency, setCurrency] = useState('USD');\n const [duration, setDuration] = useState<PlanDuration>(PlanDuration.MONTHLY);\n const [isActive, setIsActive] = useState(true);\n const [isPurchasable, setIsPurchasable] = useState(true);\n const [quotaAllocations, setQuotaAllocations] = useState<QuotaAllocation[]>([]);\n const [currencyPriceOverrides, setCurrencyPriceOverrides] = useState<\n CurrencyPriceOverrideInput[]\n >([]);\n const [error, setError] = useState<string | null>(null);\n const [success, setSuccess] = useState(false);\n\n // Populate form when plan data loads\n useEffect(() => {\n if (plan) {\n setName(plan.name ?? '');\n setPrice(String(plan.price ?? ''));\n setCurrency(plan.currency ?? 'USD');\n setDuration(plan.duration ?? PlanDuration.MONTHLY);\n setIsActive(plan.isActive ?? true);\n setIsPurchasable(plan.isPurchasable ?? true);\n // Pre-populate currency price overrides so existing prices are preserved on save\n if (plan.currencyPrices && typeof plan.currencyPrices === 'object') {\n const existing = plan.currencyPrices as Record<string, number>;\n setCurrencyPriceOverrides(\n Object.entries(existing)\n .filter(([, v]) => typeof v === 'number')\n .map(([currency, amount]) => ({ currency, amount }))\n );\n }\n // Extract quota allocations from features\n if (plan.features && plan.features.length > 0) {\n const allocations: QuotaAllocation[] = [];\n const quotaMap = new Map<string, number>();\n\n for (const feature of plan.features) {\n if (feature.quota?.id) {\n const quotaId = feature.quota.id;\n // SubscriptionFeature now stores per-plan override in context.quantity.\n // Fall back to quota.limits.value for legacy autoseeded plans.\n const value = getPlanFeatureQuantity(feature) || 1;\n quotaMap.set(quotaId, value);\n }\n }\n\n for (const [quotaId, quantity] of quotaMap) {\n allocations.push({ quotaId, quantity });\n }\n\n setQuotaAllocations(allocations);\n }\n }\n }, [plan]);\n\n // Permission check\n if (!permissions.canManagePlans) {\n return (\n <AccessDenied\n message={tr('billing.plans.noEditPermission', \"You don't have permission to edit plans.\")}\n />\n );\n }\n\n // Loading state\n if (isPlanLoading || isQuotasLoading) {\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"h-8 w-48 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"max-w-2xl space-y-4\">\n {[1, 2, 3, 4, 5].map((i) => (\n <div key={i} className=\"h-16 bg-bg-sunken animate-pulse rounded\" />\n ))}\n </div>\n </div>\n );\n }\n\n // Error state\n if (planError && isServerError(planError)) {\n return (\n <div className=\"p-6\">\n <ServerError\n title={tr('billing.plans.serverUnavailable', 'Server Unavailable')}\n message={tr(\n 'billing.plans.serverUnavailableLoadPlan',\n 'Unable to load plan. The server might be down or experiencing issues.'\n )}\n onRetry={() => refetch()}\n showRetry\n />\n </div>\n );\n }\n\n if (!plan) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-4\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('billing.plans.planNotFound', 'Plan not found')}\n </h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/plans')}\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\"\n >\n Back to Plans\n </button>\n </div>\n </div>\n );\n }\n\n const handleAddQuota = () => {\n // Add new quota at the top with empty quotaId (placeholder)\n setQuotaAllocations([{ quotaId: '', quantity: 1 }, ...quotaAllocations]);\n };\n\n const handleRemoveQuota = (index: number) => {\n setQuotaAllocations(quotaAllocations.filter((_, i) => i !== index));\n };\n\n const handleQuotaChange = (\n index: number,\n field: 'quotaId' | 'quantity',\n value: string | number\n ) => {\n const updated = [...quotaAllocations];\n if (field === 'quotaId') {\n updated[index].quotaId = value as string;\n } else {\n updated[index].quantity = Number(value);\n }\n setQuotaAllocations(updated);\n };\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n setError(null);\n setSuccess(false);\n\n // Validation\n if (!name.trim()) {\n setError('Plan name is required');\n return;\n }\n if (!price || isNaN(Number(price)) || Number(price) < 0) {\n setError('Valid price is required');\n return;\n }\n if (quotaAllocations.length === 0) {\n setError('At least one quota is required');\n return;\n }\n // Check for unselected quotas\n const unselectedQuotas = quotaAllocations.filter((a) => a.quotaId === '');\n if (unselectedQuotas.length > 0) {\n setError('Please select a quota for all allocations');\n return;\n }\n\n const input: UpdatePlanInput = {\n id: planId!,\n name: name.trim(),\n price: Number(price),\n currency,\n duration,\n isActive,\n isPurchasable,\n quotas: quotaAllocations.map((a) => ({\n quotaId: a.quotaId,\n quantity: a.quantity,\n })),\n ...(currencyPriceOverrides.length > 0 ? { currencyPriceOverrides } : {}),\n };\n\n try {\n await updatePlan(input);\n setSuccess(true);\n // Navigate back after short delay\n setTimeout(() => navigateTo(`/plans/${planId}`), 1500);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to update plan');\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title={`Edit Plan: ${plan.name}`}\n description={tr(\n 'billing.plans.editPlanDesc',\n 'Update the plan details and quota allocations'\n )}\n />\n\n <form onSubmit={handleSubmit} className=\"space-y-6\">\n {/* Error/Success Messages */}\n {error && (\n <div className=\"p-4 bg-status-error-bg-subtle border border-border-subtle rounded-lg\">\n <p className=\"text-sm text-status-error-text\">{error}</p>\n </div>\n )}\n {success && (\n <div className=\"p-4 bg-status-success-bg-subtle border border-border-subtle rounded-lg\">\n <p className=\"text-sm text-status-success-text\">\n {tr('billing.plans.updateSuccess', 'Plan updated successfully! Redirecting...')}\n </p>\n </div>\n )}\n\n {/* Two-column layout on desktop */}\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n {/* Basic Info */}\n <div className=\"border border-border-subtle rounded-card bg-bg-surface overflow-hidden shadow-[var(--shadow-elevation-1)] h-fit\">\n <div className=\"p-4 border-b border-border-subtle bg-bg-sunken/30\">\n <h2 className=\"font-semibold text-text-primary\">\n {tr('billing.plans.basicInfo', 'Basic Information')}\n </h2>\n </div>\n <div className=\"p-4 space-y-4\">\n {/* Name */}\n <div>\n <label htmlFor=\"name\" className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('billing.plans.planNameLabel', 'Plan Name')} *\n </label>\n <input\n id=\"name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(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 placeholder={tr('billing.plans.planNamePlaceholder', 'e.g., Pro Plan')}\n required\n />\n </div>\n\n {/* Price & Currency */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label\n htmlFor=\"price\"\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr('billing.plans.priceLabel', 'Price')} *\n </label>\n <input\n id=\"price\"\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n value={price}\n onChange={(e) => setPrice(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 placeholder=\"49.99\"\n required\n />\n </div>\n <div>\n <label\n htmlFor=\"currency\"\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr('billing.plans.currencyLabel', 'Currency')} *\n </label>\n <select\n id=\"currency\"\n value={currency}\n onChange={(e) => setCurrency(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 >\n <option value=\"USD\">USD ($)</option>\n <option value=\"EUR\">EUR</option>\n <option value=\"GBP\">GBP</option>\n <option value=\"INR\">INR</option>\n <option value=\"AUD\">AUD</option>\n <option value=\"CAD\">CAD</option>\n <option value=\"JPY\">JPY</option>\n <option value=\"SGD\">SGD</option>\n </select>\n </div>\n </div>\n\n {/* Duration */}\n <div>\n <label\n htmlFor=\"duration\"\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr('billing.plans.billingPeriodLabel', 'Billing Period')} *\n </label>\n <select\n id=\"duration\"\n value={duration}\n onChange={(e) => setDuration(e.target.value as PlanDuration)}\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 >\n <option value={PlanDuration.MONTHLY}>Monthly</option>\n <option value={PlanDuration.YEARLY}>Yearly</option>\n </select>\n </div>\n\n {/* Status */}\n <div className=\"flex items-center gap-3\">\n <input\n id=\"isActive\"\n type=\"checkbox\"\n checked={isActive}\n onChange={(e) => setIsActive(e.target.checked)}\n className=\"size-4 rounded border-border-subtle text-text-link focus:ring-[var(--color-focus-ring)]\"\n />\n <label htmlFor=\"isActive\" className=\"text-sm font-medium text-text-primary\">\n {tr('billing.plans.planIsActive', 'Plan is active')}\n </label>\n </div>\n\n {/* Purchasable toggle */}\n <div className=\"flex items-start justify-between gap-4 pt-1\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {tr('billing.plans.isPurchasableLabel', 'Publicly purchasable')}\n </p>\n <p className=\"text-xs text-text-muted mt-0.5\">\n {isPurchasable\n ? tr(\n 'billing.plans.isPurchasableOn',\n 'Visible on pricing page — users can subscribe directly.'\n )\n : tr(\n 'billing.plans.isPurchasableOff',\n 'Internal / custom plan — hidden from pricing page, assign via API only.'\n )}\n </p>\n </div>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={isPurchasable}\n onClick={() => setIsPurchasable((v) => !v)}\n className={`relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:ring-offset-2 ${\n isPurchasable ? 'bg-action-primary-bg' : 'bg-text-muted/30'\n }`}\n >\n <span\n className={`inline-block h-5 w-5 transform rounded-full bg-bg-surface shadow transition-transform ${\n isPurchasable ? 'translate-x-5' : 'translate-x-0'\n }`}\n />\n </button>\n </div>\n </div>\n </div>\n\n {/* Quota Allocations */}\n <div className=\"border border-border-subtle rounded-card bg-bg-surface overflow-hidden shadow-[var(--shadow-elevation-1)] h-fit\">\n <div className=\"p-4 border-b border-border-subtle bg-bg-sunken/30 flex items-center justify-between\">\n <h2 className=\"font-semibold text-text-primary\">\n {tr('billing.plans.quotaAllocations', 'Quota Allocations')}\n </h2>\n <button\n type=\"button\"\n onClick={handleAddQuota}\n className=\"px-3 py-1 text-sm font-medium text-text-link hover:bg-[var(--color-accent-soft)] rounded-md transition-colors\"\n >\n + Add Quota\n </button>\n </div>\n <div className=\"p-4 space-y-3\">\n {quotaAllocations.length === 0 ? (\n <p className=\"text-sm text-text-muted\">\n {tr(\n 'billing.plans.noQuotasAllocated',\n 'No quotas allocated. Click \"Add Quota\" to add one.'\n )}\n </p>\n ) : (\n quotaAllocations.map((allocation, index) => {\n const selectedQuota = quotas.find((q) => q.id === allocation.quotaId);\n const limits = selectedQuota?.limits as { type?: string; value?: number } | null;\n const limitValue = limits?.value ?? 0;\n const limitType = limits?.type ?? 'unknown';\n const totalValue = limitValue * allocation.quantity;\n\n return (\n <div\n key={index}\n className=\"p-3 border border-border-subtle rounded-lg bg-bg-sunken/20 space-y-3\"\n >\n <div className=\"flex items-center gap-3\">\n <select\n value={allocation.quotaId}\n onChange={(e) => handleQuotaChange(index, 'quotaId', e.target.value)}\n className={`flex-1 px-3 py-2 border border-border-subtle rounded-input bg-bg-surface focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] ${\n allocation.quotaId === '' ? 'text-text-muted' : 'text-text-primary'\n }`}\n >\n <option value=\"\" disabled>\n {tr('billing.plans.selectQuota', 'Select a quota...')}\n </option>\n {quotas.map((quota) => (\n <option key={quota.id} value={quota.id}>\n {quota.name}\n </option>\n ))}\n </select>\n <button\n type=\"button\"\n onClick={() => handleRemoveQuota(index)}\n className=\"p-2 text-status-error-text hover:bg-status-error-bg-subtle rounded-md transition-colors\"\n title=\"Remove quota\"\n >\n <svg\n className=\"size-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=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n />\n </svg>\n </button>\n </div>\n\n {/* Quota Info - only show when quota is selected */}\n {selectedQuota && (\n <>\n <div className=\"flex items-center justify-between text-sm\">\n <div className=\"text-text-muted\">\n <span className=\"capitalize\">Type: {limitType}</span>\n <span className=\"mx-2\">•</span>\n <span>\n Value per unit:{' '}\n <span className=\"font-medium text-text-primary\">\n {limitValue.toLocaleString()}\n </span>\n </span>\n </div>\n </div>\n\n {/* Quantity & Total */}\n <div className=\"flex items-center gap-4\">\n <div className=\"flex items-center gap-2\">\n <label className=\"text-sm text-text-muted\">\n {tr('billing.plans.quantity', 'Quantity')}:\n </label>\n <input\n type=\"number\"\n min=\"1\"\n value={allocation.quantity}\n onChange={(e) =>\n handleQuotaChange(index, 'quantity', e.target.value)\n }\n className=\"w-24 px-3 py-1.5 border border-border-subtle rounded-input bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] text-center\"\n />\n </div>\n <div className=\"flex items-center gap-2 text-sm\">\n <span className=\"text-text-muted\">=</span>\n <span className=\"font-semibold text-status-success-text\">\n {totalValue.toLocaleString()} total\n </span>\n </div>\n </div>\n </>\n )}\n </div>\n );\n })\n )}\n </div>\n </div>\n </div>\n\n <CurrencyPriceOverridesEditor\n overrides={currencyPriceOverrides}\n onChange={setCurrencyPriceOverrides}\n />\n\n {/* Actions */}\n <div className=\"flex items-center gap-3 pt-4\">\n <button\n type=\"submit\"\n disabled={isUpdating}\n className=\"px-6 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\"\n >\n {isUpdating\n ? tr('billing.plans.saving', 'Saving...')\n : tr('billing.plans.saveChanges', 'Save Changes')}\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/plans/${planId}`)}\n className=\"px-6 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors\"\n >\n Cancel\n </button>\n </div>\n </form>\n </div>\n );\n};\n"],"mappings":"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"}