@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.
- package/dist/billing/BillingAdminRoutes.js +7 -6
- package/dist/billing/BillingAdminRoutes.js.map +1 -1
- package/dist/billing/BillingRoot.js +1 -1
- package/dist/billing/BillingRoot.js.map +1 -1
- package/dist/billing/modules/addons/components/FloatingCartDrawer.js +22 -22
- package/dist/billing/modules/addons/components/FloatingCartDrawer.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonCreatePage.js +31 -31
- package/dist/billing/modules/addons/pages/AddonCreatePage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonDetailPage.js +39 -39
- package/dist/billing/modules/addons/pages/AddonDetailPage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonEditPage.js +29 -29
- package/dist/billing/modules/addons/pages/AddonEditPage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonsListPage.js +91 -91
- package/dist/billing/modules/addons/pages/AddonsListPage.js.map +1 -1
- package/dist/billing/modules/analytics/pages/AnalyticsPage.js +40 -40
- package/dist/billing/modules/analytics/pages/AnalyticsPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/InvoiceDetailPage.js +115 -115
- package/dist/billing/modules/billing/pages/InvoiceDetailPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/InvoicesListPage.js +75 -72
- package/dist/billing/modules/billing/pages/InvoicesListPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/RefundsPage.js +126 -126
- package/dist/billing/modules/billing/pages/RefundsPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/UserRefundsPage.js +45 -45
- package/dist/billing/modules/billing/pages/UserRefundsPage.js.map +1 -1
- package/dist/billing/modules/checkout/components/BillingAccountSelector.js +25 -25
- package/dist/billing/modules/checkout/components/BillingAccountSelector.js.map +1 -1
- package/dist/billing/modules/checkout/components/CompleteBillingAccountModal.js +31 -35
- package/dist/billing/modules/checkout/components/CompleteBillingAccountModal.js.map +1 -1
- package/dist/billing/modules/checkout/components/CreditsAmountInput.js +9 -9
- package/dist/billing/modules/checkout/components/CreditsAmountInput.js.map +1 -1
- package/dist/billing/modules/checkout/components/OrderSummary.js +31 -31
- package/dist/billing/modules/checkout/components/OrderSummary.js.map +1 -1
- package/dist/billing/modules/checkout/components/PromoCodeInput.js +8 -8
- package/dist/billing/modules/checkout/components/PromoCodeInput.js.map +1 -1
- package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js +5 -5
- package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js.map +1 -1
- package/dist/billing/modules/checkout/components/SimpleAutoPayToggle.js +9 -9
- package/dist/billing/modules/checkout/components/SimpleAutoPayToggle.js.map +1 -1
- package/dist/billing/modules/checkout/components/StripePaymentForm.js +21 -21
- package/dist/billing/modules/checkout/components/StripePaymentForm.js.map +1 -1
- package/dist/billing/modules/checkout/components/SubscriptionSelector.js +11 -11
- package/dist/billing/modules/checkout/components/SubscriptionSelector.js.map +1 -1
- package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js +31 -31
- package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js.map +1 -1
- package/dist/billing/modules/checkout/components/WorkspaceQuotaAssignmentModal.js +23 -23
- package/dist/billing/modules/checkout/components/WorkspaceQuotaAssignmentModal.js.map +1 -1
- package/dist/billing/modules/checkout/pages/CheckoutPage.js +91 -91
- package/dist/billing/modules/checkout/pages/CheckoutPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/CouponDetailPage.js +62 -62
- package/dist/billing/modules/coupons/pages/CouponDetailPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/CouponsListPage.js +72 -60
- package/dist/billing/modules/coupons/pages/CouponsListPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/CreateCouponPage.js +66 -66
- package/dist/billing/modules/coupons/pages/CreateCouponPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/EditCouponPage.js +46 -46
- package/dist/billing/modules/coupons/pages/EditCouponPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/AdminCreditsPage.js +19 -19
- package/dist/billing/modules/credits/pages/AdminCreditsPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/CreditTransactionsPage.js +37 -37
- package/dist/billing/modules/credits/pages/CreditTransactionsPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js +90 -90
- package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/CreditsPage.js +41 -41
- package/dist/billing/modules/credits/pages/CreditsPage.js.map +1 -1
- package/dist/billing/modules/dashboard/components/ActiveSubscriptionCard.js +31 -31
- package/dist/billing/modules/dashboard/components/ActiveSubscriptionCard.js.map +1 -1
- package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js +35 -35
- package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js.map +1 -1
- package/dist/billing/modules/dashboard/components/BillingAccountCard.js +24 -24
- package/dist/billing/modules/dashboard/components/BillingAccountCard.js.map +1 -1
- package/dist/billing/modules/dashboard/components/CreateBillingAccountModal.js +99 -99
- package/dist/billing/modules/dashboard/components/CreateBillingAccountModal.js.map +1 -1
- package/dist/billing/modules/dashboard/components/PaymentMethodsSection.js +23 -23
- package/dist/billing/modules/dashboard/components/PaymentMethodsSection.js.map +1 -1
- package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js +22 -22
- package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js.map +1 -1
- package/dist/billing/modules/dashboard/pages/OverviewPage.js +58 -58
- package/dist/billing/modules/dashboard/pages/OverviewPage.js.map +1 -1
- package/dist/billing/modules/discounts/pages/DiscountsListPage.js +126 -126
- package/dist/billing/modules/discounts/pages/DiscountsListPage.js.map +1 -1
- package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +83 -79
- package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanAssignFreePage.js +16 -16
- package/dist/billing/modules/plans/pages/PlanAssignFreePage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js +40 -40
- package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanCreatePage.js +35 -35
- package/dist/billing/modules/plans/pages/PlanCreatePage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanDetailPage.js +57 -57
- package/dist/billing/modules/plans/pages/PlanDetailPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanEditPage.js +35 -35
- package/dist/billing/modules/plans/pages/PlanEditPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlansBrowsePage.js +57 -57
- package/dist/billing/modules/plans/pages/PlansBrowsePage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlansListPage.js +52 -52
- package/dist/billing/modules/plans/pages/PlansListPage.js.map +1 -1
- package/dist/billing/modules/promotions/pages/CreatePromotionPage.js +40 -39
- package/dist/billing/modules/promotions/pages/CreatePromotionPage.js.map +1 -1
- package/dist/billing/modules/promotions/pages/PromotionsListPage.js +22 -19
- package/dist/billing/modules/promotions/pages/PromotionsListPage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js +34 -34
- package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js +47 -47
- package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js +39 -39
- package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js +52 -52
- package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js.map +1 -1
- package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js +23 -23
- package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js.map +1 -1
- package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js +259 -246
- package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js.map +1 -1
- package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js +88 -85
- package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
- package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js +51 -51
- package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js.map +1 -1
- package/dist/billing/modules/usage/pages/UsagePage.js +206 -196
- package/dist/billing/modules/usage/pages/UsagePage.js.map +1 -1
- package/dist/billing/shared/components/ServerError.js +4 -4
- package/dist/billing/shared/components/ServerError.js.map +1 -1
- package/dist/billing/shared/components/StatCard.js +11 -33
- package/dist/billing/shared/components/StatCard.js.map +1 -1
- package/dist/billing/shared/ui/Card.js +15 -0
- package/dist/billing/shared/ui/Card.js.map +1 -0
- package/dist/billing/shared/ui/MetricCard.js +44 -0
- package/dist/billing/shared/ui/MetricCard.js.map +1 -0
- package/dist/billing/shared/ui/ProgressBar.js +30 -0
- package/dist/billing/shared/ui/ProgressBar.js.map +1 -0
- package/dist/billing/shared/ui/SectionHeader.js +2 -0
- package/dist/billing/shared/ui/StatusPill.js +28 -0
- package/dist/billing/shared/ui/StatusPill.js.map +1 -0
- package/dist/billing/shared/ui/index.js +5 -0
- package/dist/billing/shared/utils/tokens.js +13 -30
- package/dist/billing/shared/utils/tokens.js.map +1 -1
- package/package.json +1 -1
|
@@ -33,21 +33,21 @@ var m = () => {
|
|
|
33
33
|
return n === e ? t : n;
|
|
34
34
|
}, { planId: h } = l(), g = o(), { plan: _, isLoading: v, error: y, refetch: b } = s(h), x = c(() => p(_?.features || []), [_?.features]);
|
|
35
35
|
return v ? /* @__PURE__ */ d("div", {
|
|
36
|
-
className: "space-y-6
|
|
36
|
+
className: "space-y-6 px-6 lg:px-8 py-6",
|
|
37
37
|
children: [/* @__PURE__ */ d("div", {
|
|
38
38
|
className: "flex items-center gap-4",
|
|
39
|
-
children: [/* @__PURE__ */ u("div", { className: "size-10 bg-
|
|
39
|
+
children: [/* @__PURE__ */ u("div", { className: "size-10 bg-bg-sunken animate-pulse rounded" }), /* @__PURE__ */ u("div", { className: "h-8 w-48 bg-bg-sunken animate-pulse rounded" })]
|
|
40
40
|
}), /* @__PURE__ */ d("div", {
|
|
41
41
|
className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
|
|
42
42
|
children: [/* @__PURE__ */ u("div", {
|
|
43
43
|
className: "lg:col-span-2 space-y-6",
|
|
44
44
|
children: /* @__PURE__ */ d("div", {
|
|
45
|
-
className: "border border-border rounded-lg p-6 space-y-4",
|
|
46
|
-
children: [/* @__PURE__ */ u("div", { className: "h-6 w-32 bg-
|
|
45
|
+
className: "border border-border-subtle rounded-lg p-6 space-y-4",
|
|
46
|
+
children: [/* @__PURE__ */ u("div", { className: "h-6 w-32 bg-bg-sunken animate-pulse rounded" }), /* @__PURE__ */ u("div", { className: "h-4 w-full bg-bg-sunken animate-pulse rounded" })]
|
|
47
47
|
})
|
|
48
48
|
}), /* @__PURE__ */ d("div", {
|
|
49
|
-
className: "border border-border rounded-lg p-6 space-y-4",
|
|
50
|
-
children: [/* @__PURE__ */ u("div", { className: "h-6 w-24 bg-
|
|
49
|
+
className: "border border-border-subtle rounded-lg p-6 space-y-4",
|
|
50
|
+
children: [/* @__PURE__ */ u("div", { className: "h-6 w-24 bg-bg-sunken animate-pulse rounded" }), /* @__PURE__ */ u("div", { className: "h-10 w-full bg-bg-sunken animate-pulse rounded" })]
|
|
51
51
|
})]
|
|
52
52
|
})]
|
|
53
53
|
}) : y && i(y) ? /* @__PURE__ */ u("div", {
|
|
@@ -59,7 +59,7 @@ var m = () => {
|
|
|
59
59
|
showRetry: !0
|
|
60
60
|
})
|
|
61
61
|
}) : _ ? /* @__PURE__ */ d("div", {
|
|
62
|
-
className: "space-y-6
|
|
62
|
+
className: "space-y-6 px-6 lg:px-8 py-6",
|
|
63
63
|
children: [/* @__PURE__ */ d("div", {
|
|
64
64
|
className: "flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between",
|
|
65
65
|
children: [/* @__PURE__ */ d("div", {
|
|
@@ -67,7 +67,7 @@ var m = () => {
|
|
|
67
67
|
children: [/* @__PURE__ */ u("button", {
|
|
68
68
|
type: "button",
|
|
69
69
|
onClick: () => g("/plans"),
|
|
70
|
-
className: "p-2 -ml-2 text-
|
|
70
|
+
className: "p-2 -ml-2 text-text-secondary hover:text-text-primary hover:bg-bg-sunken rounded-button transition-colors",
|
|
71
71
|
children: /* @__PURE__ */ u("svg", {
|
|
72
72
|
className: "size-5",
|
|
73
73
|
fill: "none",
|
|
@@ -81,16 +81,16 @@ var m = () => {
|
|
|
81
81
|
})
|
|
82
82
|
})
|
|
83
83
|
}), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("h1", {
|
|
84
|
-
className: "text-2xl font-
|
|
84
|
+
className: "text-2xl md:text-3xl font-semibold tracking-tight text-text-primary",
|
|
85
85
|
children: _.name
|
|
86
86
|
}), /* @__PURE__ */ d("p", {
|
|
87
|
-
className: "text-sm text-
|
|
87
|
+
className: "text-sm text-text-secondary mt-1",
|
|
88
88
|
children: [r(_.duration), " billing plan"]
|
|
89
89
|
})] })]
|
|
90
90
|
}), /* @__PURE__ */ u("button", {
|
|
91
91
|
type: "button",
|
|
92
92
|
onClick: () => g(`/checkout/${_.id}`),
|
|
93
|
-
className: "px-4 py-2 text-sm font-medium bg-primary text-primary-
|
|
93
|
+
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",
|
|
94
94
|
children: "Subscribe to Plan"
|
|
95
95
|
})]
|
|
96
96
|
}), /* @__PURE__ */ d("div", {
|
|
@@ -98,11 +98,11 @@ var m = () => {
|
|
|
98
98
|
children: [/* @__PURE__ */ d("div", {
|
|
99
99
|
className: "lg:col-span-2 space-y-6",
|
|
100
100
|
children: [/* @__PURE__ */ d("div", {
|
|
101
|
-
className: "border border-border rounded-
|
|
101
|
+
className: "border border-border-subtle rounded-card bg-bg-surface shadow-elevation-1 overflow-hidden",
|
|
102
102
|
children: [/* @__PURE__ */ u("div", {
|
|
103
|
-
className: "p-6 border-b border-border bg-
|
|
103
|
+
className: "p-6 border-b border-border-subtle bg-bg-sunken",
|
|
104
104
|
children: /* @__PURE__ */ u("h2", {
|
|
105
|
-
className: "text-lg font-semibold text-
|
|
105
|
+
className: "text-lg font-semibold text-text-primary",
|
|
106
106
|
children: m("billing.plans.pricing", "Pricing")
|
|
107
107
|
})
|
|
108
108
|
}), /* @__PURE__ */ d("div", {
|
|
@@ -110,14 +110,14 @@ var m = () => {
|
|
|
110
110
|
children: [/* @__PURE__ */ d("div", {
|
|
111
111
|
className: "flex items-baseline gap-1",
|
|
112
112
|
children: [/* @__PURE__ */ u("span", {
|
|
113
|
-
className: "text-4xl font-bold text-
|
|
113
|
+
className: "text-4xl font-bold text-text-primary",
|
|
114
114
|
children: t(_.price, _.currency)
|
|
115
115
|
}), /* @__PURE__ */ d("span", {
|
|
116
|
-
className: "text-lg text-
|
|
116
|
+
className: "text-lg text-text-secondary",
|
|
117
117
|
children: ["/ ", n(_.duration)]
|
|
118
118
|
})]
|
|
119
119
|
}), /* @__PURE__ */ d("p", {
|
|
120
|
-
className: "text-sm text-
|
|
120
|
+
className: "text-sm text-text-secondary mt-2",
|
|
121
121
|
children: [
|
|
122
122
|
m("billing.plans.billed", "Billed"),
|
|
123
123
|
" ",
|
|
@@ -126,11 +126,11 @@ var m = () => {
|
|
|
126
126
|
})]
|
|
127
127
|
})]
|
|
128
128
|
}), /* @__PURE__ */ d("div", {
|
|
129
|
-
className: "border border-border rounded-
|
|
129
|
+
className: "border border-border-subtle rounded-card bg-bg-surface shadow-elevation-1 overflow-hidden",
|
|
130
130
|
children: [/* @__PURE__ */ u("div", {
|
|
131
|
-
className: "p-6 border-b border-border bg-
|
|
131
|
+
className: "p-6 border-b border-border-subtle bg-bg-sunken",
|
|
132
132
|
children: /* @__PURE__ */ d("h2", {
|
|
133
|
-
className: "text-lg font-semibold text-
|
|
133
|
+
className: "text-lg font-semibold text-text-primary",
|
|
134
134
|
children: [
|
|
135
135
|
m("billing.plans.featuresAndQuotas", "Features & Quotas"),
|
|
136
136
|
" (",
|
|
@@ -141,12 +141,12 @@ var m = () => {
|
|
|
141
141
|
}), /* @__PURE__ */ u("div", {
|
|
142
142
|
className: "p-6",
|
|
143
143
|
children: x.length === 0 ? /* @__PURE__ */ u("p", {
|
|
144
|
-
className: "text-sm text-
|
|
144
|
+
className: "text-sm text-text-secondary",
|
|
145
145
|
children: m("billing.plans.noFeatures", "No features configured for this plan.")
|
|
146
146
|
}) : /* @__PURE__ */ u("ul", {
|
|
147
147
|
className: "space-y-3",
|
|
148
148
|
children: x.map((e) => /* @__PURE__ */ d("li", {
|
|
149
|
-
className: "flex items-start gap-3 p-3 rounded-lg bg-
|
|
149
|
+
className: "flex items-start gap-3 p-3 rounded-lg bg-bg-sunken",
|
|
150
150
|
children: [/* @__PURE__ */ u("div", {
|
|
151
151
|
className: "size-8 rounded-full bg-status-success-bg-subtle flex items-center justify-center shrink-0",
|
|
152
152
|
children: /* @__PURE__ */ u("svg", {
|
|
@@ -166,19 +166,19 @@ var m = () => {
|
|
|
166
166
|
children: [/* @__PURE__ */ d("div", {
|
|
167
167
|
className: "flex items-center justify-between",
|
|
168
168
|
children: [/* @__PURE__ */ u("p", {
|
|
169
|
-
className: "font-medium text-
|
|
169
|
+
className: "font-medium text-text-primary",
|
|
170
170
|
children: e.name
|
|
171
171
|
}), /* @__PURE__ */ u("span", {
|
|
172
|
-
className: "font-semibold text-
|
|
172
|
+
className: "font-semibold text-text-primary",
|
|
173
173
|
children: e.totalValue.toLocaleString()
|
|
174
174
|
})]
|
|
175
175
|
}), /* @__PURE__ */ d("div", {
|
|
176
176
|
className: "flex items-center gap-2 mt-1",
|
|
177
177
|
children: [/* @__PURE__ */ d("span", {
|
|
178
|
-
className: "text-sm text-
|
|
178
|
+
className: "text-sm text-text-secondary capitalize",
|
|
179
179
|
children: ["Type: ", e.limitType]
|
|
180
180
|
}), e.quotaType && /* @__PURE__ */ u("span", {
|
|
181
|
-
className: "px-2 py-0.5 text-xs font-medium bg-
|
|
181
|
+
className: "px-2 py-0.5 text-xs font-medium bg-bg-sunken text-text-secondary rounded",
|
|
182
182
|
children: e.quotaType
|
|
183
183
|
})]
|
|
184
184
|
})]
|
|
@@ -190,21 +190,21 @@ var m = () => {
|
|
|
190
190
|
}), /* @__PURE__ */ d("div", {
|
|
191
191
|
className: "space-y-6",
|
|
192
192
|
children: [/* @__PURE__ */ d("div", {
|
|
193
|
-
className: "border border-border rounded-
|
|
193
|
+
className: "border border-border-subtle rounded-card bg-bg-surface shadow-elevation-1 overflow-hidden",
|
|
194
194
|
children: [/* @__PURE__ */ u("div", {
|
|
195
|
-
className: "p-6 border-b border-border bg-
|
|
195
|
+
className: "p-6 border-b border-border-subtle bg-bg-sunken",
|
|
196
196
|
children: /* @__PURE__ */ u("h2", {
|
|
197
|
-
className: "text-lg font-semibold text-
|
|
197
|
+
className: "text-lg font-semibold text-text-primary",
|
|
198
198
|
children: m("billing.plans.subscribeTitle", "Subscribe")
|
|
199
199
|
})
|
|
200
200
|
}), /* @__PURE__ */ d("div", {
|
|
201
201
|
className: "p-6 space-y-4",
|
|
202
202
|
children: [
|
|
203
203
|
/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("p", {
|
|
204
|
-
className: "text-sm text-
|
|
204
|
+
className: "text-sm text-text-secondary",
|
|
205
205
|
children: m("billing.plans.price", "Price")
|
|
206
206
|
}), /* @__PURE__ */ d("p", {
|
|
207
|
-
className: "text-sm font-medium text-
|
|
207
|
+
className: "text-sm font-medium text-text-primary mt-0.5",
|
|
208
208
|
children: [
|
|
209
209
|
t(_.price, _.currency),
|
|
210
210
|
" / ",
|
|
@@ -212,23 +212,23 @@ var m = () => {
|
|
|
212
212
|
]
|
|
213
213
|
})] }),
|
|
214
214
|
/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("p", {
|
|
215
|
-
className: "text-sm text-
|
|
215
|
+
className: "text-sm text-text-secondary",
|
|
216
216
|
children: m("billing.plans.billingPeriod", "Billing Period")
|
|
217
217
|
}), /* @__PURE__ */ u("p", {
|
|
218
|
-
className: "text-sm text-
|
|
218
|
+
className: "text-sm text-text-primary mt-0.5",
|
|
219
219
|
children: r(_.duration)
|
|
220
220
|
})] }),
|
|
221
221
|
/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("p", {
|
|
222
|
-
className: "text-sm text-
|
|
222
|
+
className: "text-sm text-text-secondary",
|
|
223
223
|
children: m("billing.plans.quotasIncluded", "Quotas Included")
|
|
224
224
|
}), /* @__PURE__ */ u("p", {
|
|
225
|
-
className: "text-sm font-medium text-
|
|
225
|
+
className: "text-sm font-medium text-text-primary mt-0.5",
|
|
226
226
|
children: x.length
|
|
227
227
|
})] }),
|
|
228
228
|
/* @__PURE__ */ u("button", {
|
|
229
229
|
type: "button",
|
|
230
230
|
onClick: () => g(`/checkout/${_.id}`),
|
|
231
|
-
className: "w-full px-4 py-2.5 text-sm font-medium bg-primary text-primary-
|
|
231
|
+
className: "w-full px-4 py-2.5 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors",
|
|
232
232
|
children: "Subscribe to Plan"
|
|
233
233
|
})
|
|
234
234
|
]
|
|
@@ -236,7 +236,7 @@ var m = () => {
|
|
|
236
236
|
}), /* @__PURE__ */ u("button", {
|
|
237
237
|
type: "button",
|
|
238
238
|
onClick: () => g("/plans"),
|
|
239
|
-
className: "w-full px-4 py-2 text-sm font-medium border border-border text-
|
|
239
|
+
className: "w-full px-4 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors",
|
|
240
240
|
children: "Back to Plans"
|
|
241
241
|
})]
|
|
242
242
|
})]
|
|
@@ -247,17 +247,17 @@ var m = () => {
|
|
|
247
247
|
className: "text-center space-y-4",
|
|
248
248
|
children: [
|
|
249
249
|
/* @__PURE__ */ u("h2", {
|
|
250
|
-
className: "text-lg font-semibold text-
|
|
250
|
+
className: "text-lg font-semibold text-text-primary",
|
|
251
251
|
children: m("billing.plans.planNotFound", "Plan not found")
|
|
252
252
|
}),
|
|
253
253
|
/* @__PURE__ */ u("p", {
|
|
254
|
-
className: "text-sm text-
|
|
254
|
+
className: "text-sm text-text-secondary",
|
|
255
255
|
children: y?.message || m("billing.plans.planNotFoundMessage", "The plan you are looking for does not exist.")
|
|
256
256
|
}),
|
|
257
257
|
/* @__PURE__ */ u("button", {
|
|
258
258
|
type: "button",
|
|
259
259
|
onClick: () => g("/plans"),
|
|
260
|
-
className: "px-4 py-2 text-sm font-medium bg-primary text-primary-
|
|
260
|
+
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",
|
|
261
261
|
children: "Back to Plans"
|
|
262
262
|
})
|
|
263
263
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlanBrowseDetailPage.js","names":[],"sources":["../../../../../src/billing/modules/plans/pages/PlanBrowseDetailPage.tsx"],"sourcesContent":["/**\n * Plans Module - Plan Browse Detail Page (User-facing)\n * View plan details and subscribe. No edit/toggle actions.\n */\n\nimport { type FC, useMemo } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useBillingNavigate } from '../../../hooks/useBillingNavigate';\nimport { usePlan } from '../hooks';\nimport { ServerError } from '../../../shared/components';\nimport {\n formatCurrency,\n formatPlanDuration,\n formatPlanDurationLabel,\n getPlanFeatureQuantity,\n isServerError,\n} from '../../../shared/utils';\nimport type { PlanFeature } from '../../../shared/types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface CombinedQuota {\n quotaId: string;\n name: string;\n quotaType: string;\n limitType: string;\n totalValue: number;\n}\n\nfunction combineQuotas(features: PlanFeature[]): CombinedQuota[] {\n const quotaMap = new Map<string, CombinedQuota>();\n for (const feature of features) {\n if (!feature.quota) continue;\n const quotaId = feature.quota.id;\n const limits = feature.quota.limits as { type?: string; value?: number } | null;\n const limitType = limits?.type ?? 'unknown';\n const limitValue = getPlanFeatureQuantity(feature);\n const existing = quotaMap.get(quotaId);\n if (existing) {\n existing.totalValue += limitValue;\n } else {\n quotaMap.set(quotaId, {\n quotaId,\n name: feature.quota.name ?? 'Unknown Quota',\n quotaType: feature.quota.quotaType ?? '',\n limitType,\n totalValue: limitValue,\n });\n }\n }\n return Array.from(quotaMap.values());\n}\n\nexport const PlanBrowseDetailPage: 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 { plan, isLoading, error, refetch } = usePlan(planId);\n\n const combinedQuotas = useMemo(() => combineQuotas(plan?.features || []), [plan?.features]);\n\n if (isLoading) {\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center gap-4\">\n <div className=\"size-10 bg-muted animate-pulse rounded\" />\n <div className=\"h-8 w-48 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2 space-y-6\">\n <div className=\"border border-border rounded-lg p-6 space-y-4\">\n <div className=\"h-6 w-32 bg-muted animate-pulse rounded\" />\n <div className=\"h-4 w-full bg-muted animate-pulse rounded\" />\n </div>\n </div>\n <div className=\"border border-border rounded-lg p-6 space-y-4\">\n <div className=\"h-6 w-24 bg-muted animate-pulse rounded\" />\n <div className=\"h-10 w-full bg-muted animate-pulse rounded\" />\n </div>\n </div>\n </div>\n );\n }\n\n if (error && isServerError(error)) {\n return (\n <div className=\"p-6\">\n <ServerError\n title={tr('billing.plans.serverUnavailable', 'Server Unavailable')}\n message={tr('billing.plans.unableToLoadPlanDetails', 'Unable to load plan details.')}\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 <p className=\"text-sm text-muted-foreground\">\n {error?.message ||\n tr(\n 'billing.plans.planNotFoundMessage',\n 'The plan you are looking for does not exist.'\n )}\n </p>\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 transition-colors\"\n >\n Back to Plans\n </button>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex items-start gap-4\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/plans')}\n className=\"p-2 -ml-2 text-muted-foreground hover:text-foreground hover:bg-muted rounded-md transition-colors\"\n >\n <svg className=\"size-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n </button>\n <div>\n <h1 className=\"text-2xl font-bold text-foreground\">{plan.name}</h1>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {formatPlanDurationLabel(plan.duration)} billing plan\n </p>\n </div>\n </div>\n\n <button\n type=\"button\"\n onClick={() => navigateTo(`/checkout/${plan.id}`)}\n className=\"px-4 py-2 text-sm font-medium bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors\"\n >\n Subscribe to Plan\n </button>\n </div>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n {/* Main Content */}\n <div className=\"lg:col-span-2 space-y-6\">\n {/* Pricing Card */}\n <div className=\"border border-border rounded-lg bg-card overflow-hidden\">\n <div className=\"p-6 border-b border-border bg-muted/30\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n {tr('billing.plans.pricing', 'Pricing')}\n </h2>\n </div>\n <div className=\"p-6\">\n <div className=\"flex items-baseline gap-1\">\n <span className=\"text-4xl font-bold text-foreground\">\n {formatCurrency(plan.price, plan.currency)}\n </span>\n <span className=\"text-lg text-muted-foreground\">\n / {formatPlanDuration(plan.duration)}\n </span>\n </div>\n <p className=\"text-sm text-muted-foreground mt-2\">\n {tr('billing.plans.billed', 'Billed')}{' '}\n {plan.duration === 'monthly'\n ? tr('billing.plans.everyMonth', 'every month')\n : tr('billing.plans.annually', 'annually')}\n </p>\n </div>\n </div>\n\n {/* Features Card */}\n <div className=\"border border-border rounded-lg bg-card overflow-hidden\">\n <div className=\"p-6 border-b border-border bg-muted/30\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n {tr('billing.plans.featuresAndQuotas', 'Features & Quotas')} (\n {combinedQuotas.length})\n </h2>\n </div>\n <div className=\"p-6\">\n {combinedQuotas.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">\n {tr('billing.plans.noFeatures', 'No features configured for this plan.')}\n </p>\n ) : (\n <ul className=\"space-y-3\">\n {combinedQuotas.map((quota) => (\n <li\n key={quota.quotaId}\n className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/30\"\n >\n <div className=\"size-8 rounded-full bg-status-success-bg-subtle flex items-center justify-center shrink-0\">\n <svg\n className=\"size-4 text-status-success-text\"\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=\"M5 13l4 4L19 7\"\n />\n </svg>\n </div>\n <div className=\"flex-1\">\n <div className=\"flex items-center justify-between\">\n <p className=\"font-medium text-foreground\">{quota.name}</p>\n <span className=\"font-semibold text-foreground\">\n {quota.totalValue.toLocaleString()}\n </span>\n </div>\n <div className=\"flex items-center gap-2 mt-1\">\n <span className=\"text-sm text-muted-foreground capitalize\">\n Type: {quota.limitType}\n </span>\n {quota.quotaType && (\n <span className=\"px-2 py-0.5 text-xs font-medium bg-muted text-muted-foreground rounded\">\n {quota.quotaType}\n </span>\n )}\n </div>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Subscribe Card */}\n <div className=\"border border-border rounded-lg bg-card overflow-hidden\">\n <div className=\"p-6 border-b border-border bg-muted/30\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n {tr('billing.plans.subscribeTitle', 'Subscribe')}\n </h2>\n </div>\n <div className=\"p-6 space-y-4\">\n <div>\n <p className=\"text-sm text-muted-foreground\">\n {tr('billing.plans.price', 'Price')}\n </p>\n <p className=\"text-sm font-medium text-foreground mt-0.5\">\n {formatCurrency(plan.price, plan.currency)} / {formatPlanDuration(plan.duration)}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-muted-foreground\">\n {tr('billing.plans.billingPeriod', 'Billing Period')}\n </p>\n <p className=\"text-sm text-foreground mt-0.5\">\n {formatPlanDurationLabel(plan.duration)}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-muted-foreground\">\n {tr('billing.plans.quotasIncluded', 'Quotas Included')}\n </p>\n <p className=\"text-sm font-medium text-foreground mt-0.5\">\n {combinedQuotas.length}\n </p>\n </div>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/checkout/${plan.id}`)}\n className=\"w-full px-4 py-2.5 text-sm font-medium bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors\"\n >\n Subscribe to Plan\n </button>\n </div>\n </div>\n\n {/* Back */}\n <button\n type=\"button\"\n onClick={() => navigateTo('/plans')}\n className=\"w-full px-4 py-2 text-sm font-medium border border-border text-foreground rounded-md hover:bg-muted transition-colors\"\n >\n Back to Plans\n </button>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PlanBrowseDetailPage.js","names":[],"sources":["../../../../../src/billing/modules/plans/pages/PlanBrowseDetailPage.tsx"],"sourcesContent":["/**\n * Plans Module - Plan Browse Detail Page (User-facing)\n * View plan details and subscribe. No edit/toggle actions.\n */\n\nimport { type FC, useMemo } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useBillingNavigate } from '../../../hooks/useBillingNavigate';\nimport { usePlan } from '../hooks';\nimport { ServerError } from '../../../shared/components';\nimport {\n formatCurrency,\n formatPlanDuration,\n formatPlanDurationLabel,\n getPlanFeatureQuantity,\n isServerError,\n} from '../../../shared/utils';\nimport type { PlanFeature } from '../../../shared/types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface CombinedQuota {\n quotaId: string;\n name: string;\n quotaType: string;\n limitType: string;\n totalValue: number;\n}\n\nfunction combineQuotas(features: PlanFeature[]): CombinedQuota[] {\n const quotaMap = new Map<string, CombinedQuota>();\n for (const feature of features) {\n if (!feature.quota) continue;\n const quotaId = feature.quota.id;\n const limits = feature.quota.limits as { type?: string; value?: number } | null;\n const limitType = limits?.type ?? 'unknown';\n const limitValue = getPlanFeatureQuantity(feature);\n const existing = quotaMap.get(quotaId);\n if (existing) {\n existing.totalValue += limitValue;\n } else {\n quotaMap.set(quotaId, {\n quotaId,\n name: feature.quota.name ?? 'Unknown Quota',\n quotaType: feature.quota.quotaType ?? '',\n limitType,\n totalValue: limitValue,\n });\n }\n }\n return Array.from(quotaMap.values());\n}\n\nexport const PlanBrowseDetailPage: 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 { plan, isLoading, error, refetch } = usePlan(planId);\n\n const combinedQuotas = useMemo(() => combineQuotas(plan?.features || []), [plan?.features]);\n\n if (isLoading) {\n return (\n <div className=\"space-y-6 px-6 lg:px-8 py-6\">\n <div className=\"flex items-center gap-4\">\n <div className=\"size-10 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"h-8 w-48 bg-bg-sunken animate-pulse rounded\" />\n </div>\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2 space-y-6\">\n <div className=\"border border-border-subtle rounded-lg p-6 space-y-4\">\n <div className=\"h-6 w-32 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"h-4 w-full bg-bg-sunken animate-pulse rounded\" />\n </div>\n </div>\n <div className=\"border border-border-subtle rounded-lg p-6 space-y-4\">\n <div className=\"h-6 w-24 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"h-10 w-full bg-bg-sunken animate-pulse rounded\" />\n </div>\n </div>\n </div>\n );\n }\n\n if (error && isServerError(error)) {\n return (\n <div className=\"p-6\">\n <ServerError\n title={tr('billing.plans.serverUnavailable', 'Server Unavailable')}\n message={tr('billing.plans.unableToLoadPlanDetails', 'Unable to load plan details.')}\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 <p className=\"text-sm text-text-secondary\">\n {error?.message ||\n tr(\n 'billing.plans.planNotFoundMessage',\n 'The plan you are looking for does not exist.'\n )}\n </p>\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 transition-colors\"\n >\n Back to Plans\n </button>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 px-6 lg:px-8 py-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex items-start gap-4\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/plans')}\n className=\"p-2 -ml-2 text-text-secondary hover:text-text-primary hover:bg-bg-sunken rounded-button transition-colors\"\n >\n <svg className=\"size-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n </button>\n <div>\n <h1 className=\"text-2xl md:text-3xl font-semibold tracking-tight text-text-primary\">\n {plan.name}\n </h1>\n <p className=\"text-sm text-text-secondary mt-1\">\n {formatPlanDurationLabel(plan.duration)} billing plan\n </p>\n </div>\n </div>\n\n <button\n type=\"button\"\n onClick={() => navigateTo(`/checkout/${plan.id}`)}\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\"\n >\n Subscribe to Plan\n </button>\n </div>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n {/* Main Content */}\n <div className=\"lg:col-span-2 space-y-6\">\n {/* Pricing Card */}\n <div className=\"border border-border-subtle rounded-card bg-bg-surface shadow-elevation-1 overflow-hidden\">\n <div className=\"p-6 border-b border-border-subtle bg-bg-sunken\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('billing.plans.pricing', 'Pricing')}\n </h2>\n </div>\n <div className=\"p-6\">\n <div className=\"flex items-baseline gap-1\">\n <span className=\"text-4xl font-bold text-text-primary\">\n {formatCurrency(plan.price, plan.currency)}\n </span>\n <span className=\"text-lg text-text-secondary\">\n / {formatPlanDuration(plan.duration)}\n </span>\n </div>\n <p className=\"text-sm text-text-secondary mt-2\">\n {tr('billing.plans.billed', 'Billed')}{' '}\n {plan.duration === 'monthly'\n ? tr('billing.plans.everyMonth', 'every month')\n : tr('billing.plans.annually', 'annually')}\n </p>\n </div>\n </div>\n\n {/* Features Card */}\n <div className=\"border border-border-subtle rounded-card bg-bg-surface shadow-elevation-1 overflow-hidden\">\n <div className=\"p-6 border-b border-border-subtle bg-bg-sunken\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('billing.plans.featuresAndQuotas', 'Features & Quotas')} (\n {combinedQuotas.length})\n </h2>\n </div>\n <div className=\"p-6\">\n {combinedQuotas.length === 0 ? (\n <p className=\"text-sm text-text-secondary\">\n {tr('billing.plans.noFeatures', 'No features configured for this plan.')}\n </p>\n ) : (\n <ul className=\"space-y-3\">\n {combinedQuotas.map((quota) => (\n <li\n key={quota.quotaId}\n className=\"flex items-start gap-3 p-3 rounded-lg bg-bg-sunken\"\n >\n <div className=\"size-8 rounded-full bg-status-success-bg-subtle flex items-center justify-center shrink-0\">\n <svg\n className=\"size-4 text-status-success-text\"\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=\"M5 13l4 4L19 7\"\n />\n </svg>\n </div>\n <div className=\"flex-1\">\n <div className=\"flex items-center justify-between\">\n <p className=\"font-medium text-text-primary\">{quota.name}</p>\n <span className=\"font-semibold text-text-primary\">\n {quota.totalValue.toLocaleString()}\n </span>\n </div>\n <div className=\"flex items-center gap-2 mt-1\">\n <span className=\"text-sm text-text-secondary capitalize\">\n Type: {quota.limitType}\n </span>\n {quota.quotaType && (\n <span className=\"px-2 py-0.5 text-xs font-medium bg-bg-sunken text-text-secondary rounded\">\n {quota.quotaType}\n </span>\n )}\n </div>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Subscribe Card */}\n <div className=\"border border-border-subtle rounded-card bg-bg-surface shadow-elevation-1 overflow-hidden\">\n <div className=\"p-6 border-b border-border-subtle bg-bg-sunken\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('billing.plans.subscribeTitle', 'Subscribe')}\n </h2>\n </div>\n <div className=\"p-6 space-y-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">{tr('billing.plans.price', 'Price')}</p>\n <p className=\"text-sm font-medium text-text-primary mt-0.5\">\n {formatCurrency(plan.price, plan.currency)} / {formatPlanDuration(plan.duration)}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">\n {tr('billing.plans.billingPeriod', 'Billing Period')}\n </p>\n <p className=\"text-sm text-text-primary mt-0.5\">\n {formatPlanDurationLabel(plan.duration)}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">\n {tr('billing.plans.quotasIncluded', 'Quotas Included')}\n </p>\n <p className=\"text-sm font-medium text-text-primary mt-0.5\">\n {combinedQuotas.length}\n </p>\n </div>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/checkout/${plan.id}`)}\n className=\"w-full px-4 py-2.5 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors\"\n >\n Subscribe to Plan\n </button>\n </div>\n </div>\n\n {/* Back */}\n <button\n type=\"button\"\n onClick={() => navigateTo('/plans')}\n className=\"w-full px-4 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors\"\n >\n Back to Plans\n </button>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;AA4BA,SAAS,EAAc,GAA0C;CAC/D,IAAM,oBAAW,IAAI,KAA4B;AACjD,MAAK,IAAM,KAAW,GAAU;AAC9B,MAAI,CAAC,EAAQ,MAAO;EACpB,IAAM,IAAU,EAAQ,MAAM,IAExB,IADS,EAAQ,MAAM,QACH,QAAQ,WAC5B,IAAa,EAAuB,EAAQ,EAC5C,IAAW,EAAS,IAAI,EAAQ;AACtC,EAAI,IACF,EAAS,cAAc,IAEvB,EAAS,IAAI,GAAS;GACpB;GACA,MAAM,EAAQ,MAAM,QAAQ;GAC5B,WAAW,EAAQ,MAAM,aAAa;GACtC;GACA,YAAY;GACb,CAAC;;AAGN,QAAO,MAAM,KAAK,EAAS,QAAQ,CAAC;;AAGtC,IAAa,UAAiC;CAC5C,IAAM,EAAE,SAAM,GAAS,EACjB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAa,EAAE,EAAI;AACzB,SAAO,MAAe,IAAM,IAAW;IAEnC,EAAE,cAAW,GAA+B,EAC5C,IAAa,GAAoB,EACjC,EAAE,SAAM,cAAW,UAAO,eAAY,EAAQ,EAAO,EAErD,IAAiB,QAAc,EAAc,GAAM,YAAY,EAAE,CAAC,EAAE,CAAC,GAAM,SAAS,CAAC;AAgE3F,QA9DI,IAEA,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD,EAAK,WAAU,8CAA+C,CAAA,EAC9D,kBAAC,OAAD,EAAK,WAAU,+CAAgD,CAAA,CAC3D;MACN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD,EAAK,WAAU,+CAAgD,CAAA,EAC/D,kBAAC,OAAD,EAAK,WAAU,iDAAkD,CAAA,CAC7D;;IACF,CAAA,EACN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAK,WAAU,+CAAgD,CAAA,EAC/D,kBAAC,OAAD,EAAK,WAAU,kDAAmD,CAAA,CAC9D;MACF;KACF;MAIN,KAAS,EAAc,EAAM,GAE7B,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD;GACE,OAAO,EAAG,mCAAmC,qBAAqB;GAClE,SAAS,EAAG,yCAAyC,+BAA+B;GACpF,eAAe,GAAS;GACxB,WAAA;GACA,CAAA;EACE,CAAA,GAIL,IA2BH,kBAAC,OAAD;EAAK,WAAU;YAAf,CAEE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,EAAW,SAAS;KACnC,WAAU;eAEV,kBAAC,OAAD;MAAK,WAAU;MAAS,MAAK;MAAO,SAAQ;MAAY,QAAO;gBAC7D,kBAAC,QAAD;OACE,eAAc;OACd,gBAAe;OACf,aAAa;OACb,GAAE;OACF,CAAA;MACE,CAAA;KACC,CAAA,EACT,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;KAAI,WAAU;eACX,EAAK;KACH,CAAA,EACL,kBAAC,KAAD;KAAG,WAAU;eAAb,CACG,EAAwB,EAAK,SAAS,EAAC,gBACtC;OACA,EAAA,CAAA,CACF;OAEN,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAW,aAAa,EAAK,KAAK;IACjD,WAAU;cACX;IAEQ,CAAA,CACL;MAEN,kBAAC,OAAD;GAAK,WAAU;aAAf,CAEE,kBAAC,OAAD;IAAK,WAAU;cAAf,CAEE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,yBAAyB,UAAU;OACpC,CAAA;MACD,CAAA,EACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAe,EAAK,OAAO,EAAK,SAAS;QACrC,CAAA,EACP,kBAAC,QAAD;QAAM,WAAU;kBAAhB,CAA8C,MACzC,EAAmB,EAAK,SAAS,CAC/B;UACH;UACN,kBAAC,KAAD;OAAG,WAAU;iBAAb;QACG,EAAG,wBAAwB,SAAS;QAAE;QACtC,EAAK,aAAa,YACf,EAAG,4BAA4B,cAAc,GAC7C,EAAG,0BAA0B,WAAW;QAC1C;SACA;QACF;QAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,MAAD;OAAI,WAAU;iBAAd;QACG,EAAG,mCAAmC,oBAAoB;QAAC;QAC3D,EAAe;QAAO;QACpB;;MACD,CAAA,EACN,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAe,WAAW,IACzB,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAG,4BAA4B,wCAAwC;OACtE,CAAA,GAEJ,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAe,KAAK,MACnB,kBAAC,MAAD;QAEE,WAAU;kBAFZ,CAIE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,OAAD;UACE,WAAU;UACV,MAAK;UACL,SAAQ;UACR,QAAO;oBAEP,kBAAC,QAAD;WACE,eAAc;WACd,gBAAe;WACf,aAAa;WACb,GAAE;WACF,CAAA;UACE,CAAA;SACF,CAAA,EACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,KAAD;WAAG,WAAU;qBAAiC,EAAM;WAAS,CAAA,EAC7D,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAM,WAAW,gBAAgB;WAC7B,CAAA,CACH;aACN,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,QAAD;WAAM,WAAU;qBAAhB,CAAyD,UAChD,EAAM,UACR;cACN,EAAM,aACL,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAM;WACF,CAAA,CAEL;YACF;WACH;UApCE,EAAM,QAoCR,CACL;OACC,CAAA;MAEH,CAAA,CACF;OACF;OAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CAEE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,gCAAgC,YAAY;OAC7C,CAAA;MACD,CAAA,EACN,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBAA+B,EAAG,uBAAuB,QAAQ;QAAK,CAAA,EACnF,kBAAC,KAAD;QAAG,WAAU;kBAAb;SACG,EAAe,EAAK,OAAO,EAAK,SAAS;SAAC;SAAI,EAAmB,EAAK,SAAS;SAC9E;UACA,EAAA,CAAA;OACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAG,+BAA+B,iBAAiB;QAClD,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAwB,EAAK,SAAS;QACrC,CAAA,CACA,EAAA,CAAA;OACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAG,gCAAgC,kBAAkB;QACpD,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAe;QACd,CAAA,CACA,EAAA,CAAA;OACN,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAW,aAAa,EAAK,KAAK;QACjD,WAAU;kBACX;QAEQ,CAAA;OACL;QACF;QAGN,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,EAAW,SAAS;KACnC,WAAU;eACX;KAEQ,CAAA,CACL;MACF;KACF;MA3MJ,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,MAAD;KAAI,WAAU;eACX,EAAG,8BAA8B,iBAAiB;KAChD,CAAA;IACL,kBAAC,KAAD;KAAG,WAAU;eACV,GAAO,WACN,EACE,qCACA,+CACD;KACD,CAAA;IACJ,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,EAAW,SAAS;KACnC,WAAU;eACX;KAEQ,CAAA;IACL;;EACF,CAAA"}
|
|
@@ -20,7 +20,7 @@ var p = () => {
|
|
|
20
20
|
if (!g.canManagePlans) return /* @__PURE__ */ u(e, { message: m("billing.plans.noCreatePermission", "You don't have permission to create plans.") });
|
|
21
21
|
if (v) return /* @__PURE__ */ d("div", {
|
|
22
22
|
className: "space-y-6 p-6",
|
|
23
|
-
children: [/* @__PURE__ */ u("div", { className: "h-8 w-48 bg-
|
|
23
|
+
children: [/* @__PURE__ */ u("div", { className: "h-8 w-48 bg-bg-sunken animate-pulse rounded" }), /* @__PURE__ */ u("div", {
|
|
24
24
|
className: "max-w-2xl space-y-4",
|
|
25
25
|
children: [
|
|
26
26
|
1,
|
|
@@ -28,7 +28,7 @@ var p = () => {
|
|
|
28
28
|
3,
|
|
29
29
|
4,
|
|
30
30
|
5
|
|
31
|
-
].map((e) => /* @__PURE__ */ u("div", { className: "h-16 bg-
|
|
31
|
+
].map((e) => /* @__PURE__ */ u("div", { className: "h-16 bg-bg-sunken animate-pulse rounded" }, e))
|
|
32
32
|
})]
|
|
33
33
|
});
|
|
34
34
|
let V = () => {
|
|
@@ -107,11 +107,11 @@ var p = () => {
|
|
|
107
107
|
/* @__PURE__ */ d("div", {
|
|
108
108
|
className: "grid grid-cols-1 lg:grid-cols-2 gap-6",
|
|
109
109
|
children: [/* @__PURE__ */ d("div", {
|
|
110
|
-
className: "border border-border rounded-
|
|
110
|
+
className: "border border-border-subtle rounded-card bg-bg-surface overflow-hidden shadow-[var(--shadow-elevation-1)] h-fit",
|
|
111
111
|
children: [/* @__PURE__ */ u("div", {
|
|
112
|
-
className: "p-4 border-b border-border bg-
|
|
112
|
+
className: "p-4 border-b border-border-subtle bg-bg-sunken/30",
|
|
113
113
|
children: /* @__PURE__ */ u("h2", {
|
|
114
|
-
className: "font-semibold text-
|
|
114
|
+
className: "font-semibold text-text-primary",
|
|
115
115
|
children: m("billing.plans.basicInfo", "Basic Information")
|
|
116
116
|
})
|
|
117
117
|
}), /* @__PURE__ */ d("div", {
|
|
@@ -119,21 +119,21 @@ var p = () => {
|
|
|
119
119
|
children: [
|
|
120
120
|
/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ d("label", {
|
|
121
121
|
htmlFor: "name",
|
|
122
|
-
className: "block text-sm font-medium text-
|
|
122
|
+
className: "block text-sm font-medium text-text-primary mb-1",
|
|
123
123
|
children: [m("billing.plans.planNameLabel", "Plan Name"), " *"]
|
|
124
124
|
}), /* @__PURE__ */ u("input", {
|
|
125
125
|
id: "name",
|
|
126
126
|
type: "text",
|
|
127
127
|
value: x,
|
|
128
128
|
onChange: (e) => S(e.target.value),
|
|
129
|
-
className: "w-full px-3 py-2 border border-border rounded-
|
|
129
|
+
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)]",
|
|
130
130
|
placeholder: m("billing.plans.planNamePlaceholder", "e.g., Pro Plan"),
|
|
131
131
|
required: !0
|
|
132
132
|
})] }),
|
|
133
133
|
/* @__PURE__ */ d("div", { children: [
|
|
134
134
|
/* @__PURE__ */ d("label", {
|
|
135
135
|
htmlFor: "productId",
|
|
136
|
-
className: "block text-sm font-medium text-
|
|
136
|
+
className: "block text-sm font-medium text-text-primary mb-1",
|
|
137
137
|
children: [m("billing.plans.productId", "Product ID"), " *"]
|
|
138
138
|
}),
|
|
139
139
|
/* @__PURE__ */ u("input", {
|
|
@@ -141,12 +141,12 @@ var p = () => {
|
|
|
141
141
|
type: "text",
|
|
142
142
|
value: k,
|
|
143
143
|
onChange: (e) => A(e.target.value),
|
|
144
|
-
className: "w-full px-3 py-2 border border-border rounded-
|
|
144
|
+
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)]",
|
|
145
145
|
placeholder: m("billing.plans.productIdPlaceholder", "e.g., prod_abc123"),
|
|
146
146
|
required: !0
|
|
147
147
|
}),
|
|
148
148
|
/* @__PURE__ */ u("p", {
|
|
149
|
-
className: "text-xs text-muted
|
|
149
|
+
className: "text-xs text-text-muted mt-1",
|
|
150
150
|
children: m("billing.plans.productIdDesc", "The product this plan belongs to")
|
|
151
151
|
})
|
|
152
152
|
] }),
|
|
@@ -154,7 +154,7 @@ var p = () => {
|
|
|
154
154
|
className: "grid grid-cols-2 gap-4",
|
|
155
155
|
children: [/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ d("label", {
|
|
156
156
|
htmlFor: "price",
|
|
157
|
-
className: "block text-sm font-medium text-
|
|
157
|
+
className: "block text-sm font-medium text-text-primary mb-1",
|
|
158
158
|
children: [m("billing.plans.priceLabel", "Price"), " *"]
|
|
159
159
|
}), /* @__PURE__ */ u("input", {
|
|
160
160
|
id: "price",
|
|
@@ -163,18 +163,18 @@ var p = () => {
|
|
|
163
163
|
min: "0",
|
|
164
164
|
value: C,
|
|
165
165
|
onChange: (e) => w(e.target.value),
|
|
166
|
-
className: "w-full px-3 py-2 border border-border rounded-
|
|
166
|
+
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)]",
|
|
167
167
|
placeholder: "49.99",
|
|
168
168
|
required: !0
|
|
169
169
|
})] }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ d("label", {
|
|
170
170
|
htmlFor: "currency",
|
|
171
|
-
className: "block text-sm font-medium text-
|
|
171
|
+
className: "block text-sm font-medium text-text-primary mb-1",
|
|
172
172
|
children: [m("billing.plans.currencyLabel", "Currency"), " *"]
|
|
173
173
|
}), /* @__PURE__ */ d("select", {
|
|
174
174
|
id: "currency",
|
|
175
175
|
value: T,
|
|
176
176
|
onChange: (e) => E(e.target.value),
|
|
177
|
-
className: "w-full px-3 py-2 border border-border rounded-
|
|
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
|
children: [
|
|
179
179
|
/* @__PURE__ */ u("option", {
|
|
180
180
|
value: "USD",
|
|
@@ -213,13 +213,13 @@ var p = () => {
|
|
|
213
213
|
}),
|
|
214
214
|
/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ d("label", {
|
|
215
215
|
htmlFor: "duration",
|
|
216
|
-
className: "block text-sm font-medium text-
|
|
216
|
+
className: "block text-sm font-medium text-text-primary mb-1",
|
|
217
217
|
children: [m("billing.plans.billingPeriodLabel", "Billing Period"), " *"]
|
|
218
218
|
}), /* @__PURE__ */ d("select", {
|
|
219
219
|
id: "duration",
|
|
220
220
|
value: D,
|
|
221
221
|
onChange: (e) => O(e.target.value),
|
|
222
|
-
className: "w-full px-3 py-2 border border-border rounded-
|
|
222
|
+
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)]",
|
|
223
223
|
children: [/* @__PURE__ */ u("option", {
|
|
224
224
|
value: r.MONTHLY,
|
|
225
225
|
children: "Monthly"
|
|
@@ -231,54 +231,54 @@ var p = () => {
|
|
|
231
231
|
/* @__PURE__ */ d("div", {
|
|
232
232
|
className: "flex items-start justify-between gap-4 pt-1",
|
|
233
233
|
children: [/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("p", {
|
|
234
|
-
className: "text-sm font-medium text-
|
|
234
|
+
className: "text-sm font-medium text-text-primary",
|
|
235
235
|
children: m("billing.plans.isPurchasableLabel", "Publicly purchasable")
|
|
236
236
|
}), /* @__PURE__ */ u("p", {
|
|
237
|
-
className: "text-xs text-muted
|
|
237
|
+
className: "text-xs text-text-muted mt-0.5",
|
|
238
238
|
children: j ? m("billing.plans.isPurchasableOn", "Visible on pricing page — users can subscribe directly.") : m("billing.plans.isPurchasableOff", "Internal / custom plan — hidden from pricing page, assign via API only.")
|
|
239
239
|
})] }), /* @__PURE__ */ u("button", {
|
|
240
240
|
type: "button",
|
|
241
241
|
role: "switch",
|
|
242
242
|
"aria-checked": j,
|
|
243
243
|
onClick: () => M((e) => !e),
|
|
244
|
-
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-
|
|
245
|
-
children: /* @__PURE__ */ u("span", { className: `inline-block h-5 w-5 transform rounded-full bg-
|
|
244
|
+
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 ${j ? "bg-action-primary-bg" : "bg-text-muted/30"}`,
|
|
245
|
+
children: /* @__PURE__ */ u("span", { className: `inline-block h-5 w-5 transform rounded-full bg-bg-surface shadow transition-transform ${j ? "translate-x-5" : "translate-x-0"}` })
|
|
246
246
|
})]
|
|
247
247
|
})
|
|
248
248
|
]
|
|
249
249
|
})]
|
|
250
250
|
}), /* @__PURE__ */ d("div", {
|
|
251
|
-
className: "border border-border rounded-
|
|
251
|
+
className: "border border-border-subtle rounded-card bg-bg-surface overflow-hidden shadow-[var(--shadow-elevation-1)] h-fit",
|
|
252
252
|
children: [/* @__PURE__ */ d("div", {
|
|
253
|
-
className: "p-4 border-b border-border bg-
|
|
253
|
+
className: "p-4 border-b border-border-subtle bg-bg-sunken/30 flex items-center justify-between",
|
|
254
254
|
children: [/* @__PURE__ */ d("h2", {
|
|
255
|
-
className: "font-semibold text-
|
|
255
|
+
className: "font-semibold text-text-primary",
|
|
256
256
|
children: [m("billing.plans.quotaAllocations", "Quota Allocations"), " *"]
|
|
257
257
|
}), /* @__PURE__ */ u("button", {
|
|
258
258
|
type: "button",
|
|
259
259
|
onClick: V,
|
|
260
260
|
disabled: _.length === 0,
|
|
261
|
-
className: "px-3 py-1 text-sm font-medium text-
|
|
261
|
+
className: "px-3 py-1 text-sm font-medium text-text-link hover:bg-[var(--color-accent-soft)] rounded-md transition-colors disabled:opacity-50",
|
|
262
262
|
children: "+ Add Quota"
|
|
263
263
|
})]
|
|
264
264
|
}), /* @__PURE__ */ u("div", {
|
|
265
265
|
className: "p-4 space-y-3",
|
|
266
266
|
children: _.length === 0 ? /* @__PURE__ */ u("p", {
|
|
267
|
-
className: "text-sm text-muted
|
|
267
|
+
className: "text-sm text-text-muted",
|
|
268
268
|
children: m("billing.plans.noQuotasAvailable", "No quotas available. Please create quotas first.")
|
|
269
269
|
}) : N.length === 0 ? /* @__PURE__ */ u("p", {
|
|
270
|
-
className: "text-sm text-muted
|
|
270
|
+
className: "text-sm text-text-muted",
|
|
271
271
|
children: m("billing.plans.noQuotasAllocated", "No quotas allocated. Click \"Add Quota\" to add one.")
|
|
272
272
|
}) : N.map((e, t) => {
|
|
273
273
|
let n = _.find((t) => t.id === e.quotaId), r = n?.limits, i = r?.value ?? 0, a = r?.type ?? "unknown", o = i * e.quantity;
|
|
274
274
|
return /* @__PURE__ */ d("div", {
|
|
275
|
-
className: "p-3 border border-border rounded-lg bg-
|
|
275
|
+
className: "p-3 border border-border-subtle rounded-lg bg-bg-sunken/20 space-y-3",
|
|
276
276
|
children: [/* @__PURE__ */ d("div", {
|
|
277
277
|
className: "flex items-center gap-3",
|
|
278
278
|
children: [/* @__PURE__ */ d("select", {
|
|
279
279
|
value: e.quotaId,
|
|
280
280
|
onChange: (e) => U(t, "quotaId", e.target.value),
|
|
281
|
-
className: `flex-1 px-3 py-2 border border-border rounded-
|
|
281
|
+
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"}`,
|
|
282
282
|
children: [/* @__PURE__ */ u("option", {
|
|
283
283
|
value: "",
|
|
284
284
|
disabled: !0,
|
|
@@ -308,7 +308,7 @@ var p = () => {
|
|
|
308
308
|
}), n && /* @__PURE__ */ d(l, { children: [/* @__PURE__ */ u("div", {
|
|
309
309
|
className: "flex items-center justify-between text-sm",
|
|
310
310
|
children: /* @__PURE__ */ d("div", {
|
|
311
|
-
className: "text-muted
|
|
311
|
+
className: "text-text-muted",
|
|
312
312
|
children: [
|
|
313
313
|
/* @__PURE__ */ d("span", {
|
|
314
314
|
className: "capitalize",
|
|
@@ -322,7 +322,7 @@ var p = () => {
|
|
|
322
322
|
"Value per unit:",
|
|
323
323
|
" ",
|
|
324
324
|
/* @__PURE__ */ u("span", {
|
|
325
|
-
className: "font-medium text-
|
|
325
|
+
className: "font-medium text-text-primary",
|
|
326
326
|
children: i.toLocaleString()
|
|
327
327
|
})
|
|
328
328
|
] })
|
|
@@ -333,19 +333,19 @@ var p = () => {
|
|
|
333
333
|
children: [/* @__PURE__ */ d("div", {
|
|
334
334
|
className: "flex items-center gap-2",
|
|
335
335
|
children: [/* @__PURE__ */ d("label", {
|
|
336
|
-
className: "text-sm text-muted
|
|
336
|
+
className: "text-sm text-text-muted",
|
|
337
337
|
children: [m("billing.plans.quantity", "Quantity"), ":"]
|
|
338
338
|
}), /* @__PURE__ */ u("input", {
|
|
339
339
|
type: "number",
|
|
340
340
|
min: "1",
|
|
341
341
|
value: e.quantity,
|
|
342
342
|
onChange: (e) => U(t, "quantity", e.target.value),
|
|
343
|
-
className: "w-24 px-3 py-1.5 border border-border rounded-
|
|
343
|
+
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"
|
|
344
344
|
})]
|
|
345
345
|
}), /* @__PURE__ */ d("div", {
|
|
346
346
|
className: "flex items-center gap-2 text-sm",
|
|
347
347
|
children: [/* @__PURE__ */ u("span", {
|
|
348
|
-
className: "text-muted
|
|
348
|
+
className: "text-text-muted",
|
|
349
349
|
children: "="
|
|
350
350
|
}), /* @__PURE__ */ d("span", {
|
|
351
351
|
className: "font-semibold text-status-success-text",
|
|
@@ -367,12 +367,12 @@ var p = () => {
|
|
|
367
367
|
children: [/* @__PURE__ */ u("button", {
|
|
368
368
|
type: "submit",
|
|
369
369
|
disabled: b || _.length === 0,
|
|
370
|
-
className: "px-6 py-2 text-sm font-medium bg-primary text-primary-
|
|
370
|
+
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",
|
|
371
371
|
children: b ? m("billing.plans.creating", "Creating...") : m("billing.plans.createPlanBtn", "Create Plan")
|
|
372
372
|
}), /* @__PURE__ */ u("button", {
|
|
373
373
|
type: "button",
|
|
374
374
|
onClick: () => h("/plans"),
|
|
375
|
-
className: "px-6 py-2 text-sm font-medium border border-border text-
|
|
375
|
+
className: "px-6 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors",
|
|
376
376
|
children: "Cancel"
|
|
377
377
|
})]
|
|
378
378
|
})
|