@burdenoff/microfe-billing 2026.821.1 → 2026.825.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 (145) hide show
  1. package/dist/billing/BillingAdminRoutes.js.map +1 -1
  2. package/dist/billing/BillingRoot.js.map +1 -1
  3. package/dist/billing/BillingUserRoutes.js.map +1 -1
  4. package/dist/billing/hooks/useBillingAccountSelection.js.map +1 -1
  5. package/dist/billing/hooks/useBillingEventEmitter.js.map +1 -1
  6. package/dist/billing/hooks/useBillingNavigate.js.map +1 -1
  7. package/dist/billing/hooks/useBillingPermissions.js.map +1 -1
  8. package/dist/billing/hooks/useDefaultBillingCurrency.js.map +1 -1
  9. package/dist/billing/modules/addons/components/FloatingCartDrawer.js.map +1 -1
  10. package/dist/billing/modules/addons/hooks/useAddons.js.map +1 -1
  11. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js.map +1 -1
  12. package/dist/billing/modules/addons/pages/AddonCreatePage.js.map +1 -1
  13. package/dist/billing/modules/addons/pages/AddonDetailPage.js.map +1 -1
  14. package/dist/billing/modules/addons/pages/AddonEditPage.js.map +1 -1
  15. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js.map +1 -1
  16. package/dist/billing/modules/addons/pages/AddonsListPage.js.map +1 -1
  17. package/dist/billing/modules/addons/store/addonCartStore.js.map +1 -1
  18. package/dist/billing/modules/affiliate/api.js.map +1 -1
  19. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js +107 -107
  20. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js.map +1 -1
  21. package/dist/billing/modules/analytics/pages/AnalyticsPage.js +80 -81
  22. package/dist/billing/modules/analytics/pages/AnalyticsPage.js.map +1 -1
  23. package/dist/billing/modules/billing/hooks/useInvoices.js.map +1 -1
  24. package/dist/billing/modules/billing/hooks/useRefunds.js.map +1 -1
  25. package/dist/billing/modules/billing/hooks/useTransactions.js.map +1 -1
  26. package/dist/billing/modules/billing/pages/InvoiceDetailPage.js.map +1 -1
  27. package/dist/billing/modules/billing/pages/InvoicesListPage.js +1 -1
  28. package/dist/billing/modules/billing/pages/InvoicesListPage.js.map +1 -1
  29. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js.map +1 -1
  30. package/dist/billing/modules/billing/pages/RefundsPage.js.map +1 -1
  31. package/dist/billing/modules/billing/pages/TransactionsPage.js.map +1 -1
  32. package/dist/billing/modules/billing/pages/UserRefundsPage.js +127 -127
  33. package/dist/billing/modules/billing/pages/UserRefundsPage.js.map +1 -1
  34. package/dist/billing/modules/checkout/components/BillingAccountSelector.js.map +1 -1
  35. package/dist/billing/modules/checkout/components/CompleteBillingAccountModal.js.map +1 -1
  36. package/dist/billing/modules/checkout/components/CreditsAmountInput.js.map +1 -1
  37. package/dist/billing/modules/checkout/components/NativeCheckoutView.js.map +1 -1
  38. package/dist/billing/modules/checkout/components/OrderSummary.js.map +1 -1
  39. package/dist/billing/modules/checkout/components/PromoCodeInput.js.map +1 -1
  40. package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js.map +1 -1
  41. package/dist/billing/modules/checkout/components/SimpleAutoPayToggle.js.map +1 -1
  42. package/dist/billing/modules/checkout/components/StoreShippingSection.js.map +1 -1
  43. package/dist/billing/modules/checkout/components/StripePaymentForm.js.map +1 -1
  44. package/dist/billing/modules/checkout/components/SubscriptionSelector.js.map +1 -1
  45. package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js.map +1 -1
  46. package/dist/billing/modules/checkout/components/WorkspaceQuotaAssignmentModal.js.map +1 -1
  47. package/dist/billing/modules/checkout/hooks/useCheckout.js +0 -1
  48. package/dist/billing/modules/checkout/hooks/useCheckout.js.map +1 -1
  49. package/dist/billing/modules/checkout/hooks/useNativeCheckout.js.map +1 -1
  50. package/dist/billing/modules/checkout/hooks/usePaymentProviders.js.map +1 -1
  51. package/dist/billing/modules/checkout/hooks/usePaymentStatusPolling.js.map +1 -1
  52. package/dist/billing/modules/checkout/hooks/useStoreShipping.js.map +1 -1
  53. package/dist/billing/modules/checkout/pages/CheckoutPage.js +412 -395
  54. package/dist/billing/modules/checkout/pages/CheckoutPage.js.map +1 -1
  55. package/dist/billing/modules/checkout/utils/storeOrder.js.map +1 -1
  56. package/dist/billing/modules/coupons/pages/CouponDetailPage.js.map +1 -1
  57. package/dist/billing/modules/coupons/pages/CouponsListPage.js.map +1 -1
  58. package/dist/billing/modules/coupons/pages/CreateCouponPage.js.map +1 -1
  59. package/dist/billing/modules/coupons/pages/EditCouponPage.js.map +1 -1
  60. package/dist/billing/modules/credits/hooks/useCredits.js.map +1 -1
  61. package/dist/billing/modules/credits/pages/AdminCreditsPage.js.map +1 -1
  62. package/dist/billing/modules/credits/pages/CreditTransactionsPage.js.map +1 -1
  63. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js.map +1 -1
  64. package/dist/billing/modules/credits/pages/CreditsPage.js.map +1 -1
  65. package/dist/billing/modules/dashboard/components/ActiveSubscriptionCard.js.map +1 -1
  66. package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js.map +1 -1
  67. package/dist/billing/modules/dashboard/components/BillingAccountCard.js.map +1 -1
  68. package/dist/billing/modules/dashboard/components/CreateBillingAccountModal.js.map +1 -1
  69. package/dist/billing/modules/dashboard/components/PaymentMethodsSection.js.map +1 -1
  70. package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js.map +1 -1
  71. package/dist/billing/modules/dashboard/hooks/useBillingOverviewData.js.map +1 -1
  72. package/dist/billing/modules/dashboard/hooks/useDashboard.js.map +1 -1
  73. package/dist/billing/modules/dashboard/pages/OverviewPage.js.map +1 -1
  74. package/dist/billing/modules/discounts/pages/DiscountsListPage.js.map +1 -1
  75. package/dist/billing/modules/earnings/api.js.map +1 -1
  76. package/dist/billing/modules/earnings/pages/DeveloperRevenueAdminPage.js +145 -145
  77. package/dist/billing/modules/earnings/pages/DeveloperRevenueAdminPage.js.map +1 -1
  78. package/dist/billing/modules/earnings/pages/EarningsPage.js +133 -133
  79. package/dist/billing/modules/earnings/pages/EarningsPage.js.map +1 -1
  80. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +7 -9
  81. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
  82. package/dist/billing/modules/earnings/pages/PayoutsPage.js +95 -95
  83. package/dist/billing/modules/earnings/pages/PayoutsPage.js.map +1 -1
  84. package/dist/billing/modules/plans/constants/featuredQuotas.js.map +1 -1
  85. package/dist/billing/modules/plans/hooks/usePlans.js.map +1 -1
  86. package/dist/billing/modules/plans/hooks/useQuotas.js.map +1 -1
  87. package/dist/billing/modules/plans/pages/PlanAssignFreePage.js.map +1 -1
  88. package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js.map +1 -1
  89. package/dist/billing/modules/plans/pages/PlanCreatePage.js.map +1 -1
  90. package/dist/billing/modules/plans/pages/PlanDetailPage.js.map +1 -1
  91. package/dist/billing/modules/plans/pages/PlanEditPage.js.map +1 -1
  92. package/dist/billing/modules/plans/pages/PlansBrowsePage.js.map +1 -1
  93. package/dist/billing/modules/plans/pages/PlansListPage.js.map +1 -1
  94. package/dist/billing/modules/promotions/pages/CreatePromotionPage.js.map +1 -1
  95. package/dist/billing/modules/promotions/pages/PromotionsListPage.js.map +1 -1
  96. package/dist/billing/modules/quota/hooks/useQuotaTemplates.js.map +1 -1
  97. package/dist/billing/modules/quota/pages/QuotaAssignFreePage.js.map +1 -1
  98. package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js.map +1 -1
  99. package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js.map +1 -1
  100. package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js.map +1 -1
  101. package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js.map +1 -1
  102. package/dist/billing/modules/settings/pages/SettingsPage.js.map +1 -1
  103. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js.map +1 -1
  104. package/dist/billing/modules/store/pages/StoreCheckoutPage.js +5 -6
  105. package/dist/billing/modules/store/pages/StoreCheckoutPage.js.map +1 -1
  106. package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js.map +1 -1
  107. package/dist/billing/modules/subscriptions/hooks/useSubscriptions.js.map +1 -1
  108. package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js.map +1 -1
  109. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
  110. package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js.map +1 -1
  111. package/dist/billing/modules/usage/hooks/useUsage.js +14 -9
  112. package/dist/billing/modules/usage/hooks/useUsage.js.map +1 -1
  113. package/dist/billing/modules/usage/pages/UsagePage.js +481 -453
  114. package/dist/billing/modules/usage/pages/UsagePage.js.map +1 -1
  115. package/dist/billing/providers/BillingProvider.js.map +1 -1
  116. package/dist/billing/shared/components/AccessDenied.js.map +1 -1
  117. package/dist/billing/shared/components/ActorIdentity.js.map +1 -1
  118. package/dist/billing/shared/components/CurrencyPriceOverridesEditor.js.map +1 -1
  119. package/dist/billing/shared/components/EmptyState.js.map +1 -1
  120. package/dist/billing/shared/components/PageHeader.js.map +1 -1
  121. package/dist/billing/shared/components/ServerError.js.map +1 -1
  122. package/dist/billing/shared/components/StatCard.js.map +1 -1
  123. package/dist/billing/shared/hooks/useActorProfiles.js.map +1 -1
  124. package/dist/billing/shared/types/graphql.js.map +1 -1
  125. package/dist/billing/shared/ui/Card.js.map +1 -1
  126. package/dist/billing/shared/ui/MetricCard.js.map +1 -1
  127. package/dist/billing/shared/ui/ProgressBar.js.map +1 -1
  128. package/dist/billing/shared/ui/StatusPill.js.map +1 -1
  129. package/dist/billing/shared/utils/directBillingGraphql.js.map +1 -1
  130. package/dist/billing/shared/utils/error.js.map +1 -1
  131. package/dist/billing/shared/utils/format.js.map +1 -1
  132. package/dist/billing/shared/utils/gatewayGraphql.js.map +1 -1
  133. package/dist/billing/shared/utils/navigation.js.map +1 -1
  134. package/dist/billing/shared/utils/paymentTheme.js.map +1 -1
  135. package/dist/billing/shared/utils/planFeatureQuantity.js.map +1 -1
  136. package/dist/billing/shared/utils/status.js.map +1 -1
  137. package/dist/billing/shared/utils/tokens.js.map +1 -1
  138. package/dist/generated/global-operations.js +5 -1
  139. package/dist/generated/global-operations.js.map +1 -1
  140. package/dist/generated/global-types.js.map +1 -1
  141. package/dist/generated/wspace-operations.js +1 -1
  142. package/dist/generated/wspace-operations.js.map +1 -1
  143. package/dist/node_modules/@capacitor/core/dist/index.js +1 -1
  144. package/dist/node_modules/@capacitor/core/dist/index.js.map +1 -1
  145. package/package.json +13 -10
@@ -9,13 +9,13 @@ import { formatCurrency as o, formatDateTime as s } from "../../../shared/utils/
9
9
  import { isServerError as c } from "../../../shared/utils/error.js";
10
10
  import "../../../shared/utils/index.js";
11
11
  import { useBillingPermissions as l } from "../../../hooks/useBillingPermissions.js";
12
- import { addAffiliateCodeNote as ee, createAffiliateCode as u, deactivateAffiliateCode as d, fetchMyAffiliateAnalytics as f, fetchMyAffiliateCodes as p, fetchMyAffiliateJourneys as m, updateAffiliateCode as h } from "../api.js";
13
- import { useEffect as g, useMemo as _, useState as v } from "react";
14
- import { Link2 as y, Plus as b, RefreshCw as x, StickyNote as S, Ticket as C, TrendingUp as w, Users as T } from "lucide-react";
15
- import { jsx as E, jsxs as D } from "react/jsx-runtime";
16
- import { CTAOverflowMenu as O, EmphasisPanel as k, IllustratedEmptyState as A, PagePurpose as j, ResponsiveTable as M } from "@burdenoff/fe-libs/ui";
12
+ import { addAffiliateCodeNote as u, createAffiliateCode as d, deactivateAffiliateCode as f, fetchMyAffiliateAnalytics as p, fetchMyAffiliateCodes as ee, fetchMyAffiliateJourneys as te, updateAffiliateCode as m } from "../api.js";
13
+ import { useCallback as h, useEffect as g, useMemo as _, useState as v } from "react";
14
+ import { Link2 as y, Plus as b, RefreshCw as x, StickyNote as S, Ticket as ne, TrendingUp as C, Users as w } from "lucide-react";
15
+ import { jsx as T, jsxs as E } from "react/jsx-runtime";
16
+ import { CTAOverflowMenu as D, EmphasisPanel as O, IllustratedEmptyState as k, PagePurpose as A, ResponsiveTable as j } from "@burdenoff/fe-libs/ui";
17
17
  //#region src/billing/modules/affiliate/pages/AffiliateDashboardPage.tsx
18
- var N = [
18
+ var M = [
19
19
  {
20
20
  key: "code",
21
21
  header: "Code",
@@ -47,8 +47,8 @@ var N = [
47
47
  header: "Visited",
48
48
  cell: (e) => s(e.lastVisitedAt)
49
49
  }
50
- ], P = () => {
51
- let s = l(), { emit: P } = a(), { apiGatewayUrl: F, authToken: I, orgId: L } = e(), [R, z] = v([]), [B, V] = v([]), [H, te] = v(null), [U, W] = v(!0), [G, K] = v(null), [q, J] = v(null), [Y, X] = v({
50
+ ], N = () => {
51
+ let s = l(), { emit: N } = a(), { apiGatewayUrl: P, authToken: F, orgId: I } = e(), [L, R] = v([]), [z, B] = v([]), [V, H] = v(null), [U, W] = v(!0), [G, K] = v(null), [q, J] = v(null), [Y, X] = v({
52
52
  label: "",
53
53
  description: "",
54
54
  notes: "",
@@ -56,56 +56,56 @@ var N = [
56
56
  destinationPath: "",
57
57
  destinationUrl: ""
58
58
  }), Z = _(() => ({
59
- apiGatewayUrl: F,
60
- authToken: I,
61
- orgId: L
59
+ apiGatewayUrl: P,
60
+ authToken: F,
61
+ orgId: I
62
62
  }), [
63
+ P,
63
64
  F,
64
- I,
65
- L
66
- ]), Q = async () => {
65
+ I
66
+ ]), Q = h(async () => {
67
67
  W(!0), K(null);
68
68
  try {
69
69
  let [e, t, n] = await Promise.all([
70
+ ee(Z),
70
71
  p(Z),
71
- f(Z),
72
- m(Z)
72
+ te(Z)
73
73
  ]);
74
- z(e), te(t), V(n);
74
+ R(e), H(t), B(n);
75
75
  } catch (e) {
76
76
  K(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load affiliate dashboard"));
77
77
  } finally {
78
78
  W(!1);
79
79
  }
80
- };
80
+ }, [Z]);
81
81
  if (g(() => {
82
82
  Q();
83
- }, [Z]), !s.canViewBillingAccount) return /* @__PURE__ */ E(t, { message: "You don't have permission to view affiliate analytics." });
84
- if (G && c(G)) return /* @__PURE__ */ E(i, {
83
+ }, [Q]), !s.canViewBillingAccount) return /* @__PURE__ */ T(t, { message: "You don't have permission to view affiliate analytics." });
84
+ if (G && c(G)) return /* @__PURE__ */ T(i, {
85
85
  title: "Affiliate service unavailable",
86
86
  message: G.message,
87
87
  onRetry: () => void Q(),
88
88
  showRetry: !0
89
89
  });
90
- let $ = R.find((e) => e.id === q) ?? null, ne = async () => {
90
+ let $ = L.find((e) => e.id === q) ?? null, re = async () => {
91
91
  if (!Y.productSlug.trim()) {
92
92
  K(/* @__PURE__ */ Error("Product slug is required"));
93
93
  return;
94
94
  }
95
95
  try {
96
- $ ? (await h($.id, {
96
+ $ ? (await m($.id, {
97
97
  label: Y.label,
98
98
  description: Y.description,
99
99
  notes: Y.notes,
100
100
  destinationPath: Y.destinationPath,
101
101
  destinationUrl: Y.destinationUrl
102
- }, Z), P("billing.affiliate_code.updated", {
102
+ }, Z), N("billing.affiliate_code.updated", {
103
103
  route: "/billing/affiliate",
104
104
  entityId: $.id,
105
105
  source: "affiliate-dashboard"
106
- })) : P("billing.affiliate_code.created", {
106
+ })) : N("billing.affiliate_code.created", {
107
107
  route: "/billing/affiliate",
108
- entityId: (await u({
108
+ entityId: (await d({
109
109
  label: Y.label,
110
110
  description: Y.description,
111
111
  notes: Y.notes,
@@ -125,7 +125,7 @@ var N = [
125
125
  } catch (e) {
126
126
  K(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to save affiliate code"));
127
127
  }
128
- }, re = (e) => {
128
+ }, ie = (e) => {
129
129
  J(e.id), X({
130
130
  label: e.label ?? "",
131
131
  description: e.description ?? "",
@@ -134,93 +134,93 @@ var N = [
134
134
  destinationPath: e.destinationPath ?? "",
135
135
  destinationUrl: e.destinationUrl ?? ""
136
136
  });
137
- }, ie = async (e) => {
138
- await d(e, Z), P("billing.affiliate_code.deactivated", {
137
+ }, ae = async (e) => {
138
+ await f(e, Z), N("billing.affiliate_code.deactivated", {
139
139
  route: "/billing/affiliate",
140
140
  entityId: e,
141
141
  source: "affiliate-dashboard"
142
142
  }), await Q();
143
- }, ae = async (e) => {
143
+ }, oe = async (e) => {
144
144
  let t = window.prompt("Add an internal note for this affiliate code");
145
- t && (await ee(e, t, Z), P("billing.affiliate_code.note_added", {
145
+ t && (await u(e, t, Z), N("billing.affiliate_code.note_added", {
146
146
  route: "/billing/affiliate",
147
147
  entityId: e,
148
148
  source: "affiliate-dashboard"
149
149
  }), await Q());
150
- }, oe = H ? [
150
+ }, se = V ? [
151
151
  {
152
152
  title: "Codes",
153
- value: H.totalCodes,
154
- icon: /* @__PURE__ */ E(C, { className: "size-5" })
153
+ value: V.totalCodes,
154
+ icon: /* @__PURE__ */ T(ne, { className: "size-5" })
155
155
  },
156
156
  {
157
157
  title: "Visits",
158
- value: H.totalVisits,
159
- icon: /* @__PURE__ */ E(T, { className: "size-5" })
158
+ value: V.totalVisits,
159
+ icon: /* @__PURE__ */ T(w, { className: "size-5" })
160
160
  },
161
161
  {
162
162
  title: "Journeys",
163
- value: H.totalJourneys,
164
- icon: /* @__PURE__ */ E(y, { className: "size-5" })
163
+ value: V.totalJourneys,
164
+ icon: /* @__PURE__ */ T(y, { className: "size-5" })
165
165
  },
166
166
  {
167
167
  title: "Revenue influenced",
168
- value: o(H.totalRevenueAmount, "USD"),
169
- icon: /* @__PURE__ */ E(w, { className: "size-5" })
168
+ value: o(V.totalRevenueAmount, "USD"),
169
+ icon: /* @__PURE__ */ T(C, { className: "size-5" })
170
170
  }
171
171
  ] : [];
172
- return /* @__PURE__ */ D("div", {
172
+ return /* @__PURE__ */ E("div", {
173
173
  className: "space-y-6 p-6",
174
174
  children: [
175
- /* @__PURE__ */ E(n, {
175
+ /* @__PURE__ */ T(n, {
176
176
  title: "Affiliate codes",
177
177
  description: "Create referral codes, add internal notes, and monitor attributed journeys.",
178
- actions: /* @__PURE__ */ E(O, { actions: [{
178
+ actions: /* @__PURE__ */ T(D, { actions: [{
179
179
  label: "Refresh",
180
180
  onSelect: () => void Q(),
181
- icon: /* @__PURE__ */ E(x, { className: "size-4" })
181
+ icon: /* @__PURE__ */ T(x, { className: "size-4" })
182
182
  }] })
183
183
  }),
184
- /* @__PURE__ */ E(j, { children: "Generate referral links for any product, share them, and see exactly what they drive — visits, signups, paid conversions and the rewards you have earned. Create and manage your codes on the left and watch attributed visitor journeys on the right." }),
185
- U ? /* @__PURE__ */ E("div", {
184
+ /* @__PURE__ */ T(A, { children: "Generate referral links for any product, share them, and see exactly what they drive — visits, signups, paid conversions and the rewards you have earned. Create and manage your codes on the left and watch attributed visitor journeys on the right." }),
185
+ U ? /* @__PURE__ */ T("div", {
186
186
  className: "grid gap-4 md:grid-cols-2 xl:grid-cols-4",
187
187
  children: [
188
188
  1,
189
189
  2,
190
190
  3,
191
191
  4
192
- ].map((e) => /* @__PURE__ */ E("div", { className: "h-28 animate-pulse rounded-lg border border-border-subtle bg-bg-surface" }, e))
193
- }) : H ? /* @__PURE__ */ E(k, {
192
+ ].map((e) => /* @__PURE__ */ T("div", { className: "h-28 animate-pulse rounded-lg border border-border-subtle bg-bg-surface" }, e))
193
+ }) : V ? /* @__PURE__ */ T(O, {
194
194
  className: "p-4 sm:p-5",
195
- children: /* @__PURE__ */ E("div", {
195
+ children: /* @__PURE__ */ T("div", {
196
196
  className: "grid gap-4 md:grid-cols-2 xl:grid-cols-4",
197
- children: oe.map((e) => /* @__PURE__ */ E(r, {
197
+ children: se.map((e) => /* @__PURE__ */ T(r, {
198
198
  label: e.title,
199
199
  value: e.value,
200
200
  icon: e.icon
201
201
  }, e.title))
202
202
  })
203
203
  }) : null,
204
- G && !c(G) ? /* @__PURE__ */ E("div", {
204
+ G && !c(G) ? /* @__PURE__ */ T("div", {
205
205
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4 text-sm text-status-error-text",
206
206
  children: G.message
207
207
  }) : null,
208
- /* @__PURE__ */ D("div", {
208
+ /* @__PURE__ */ E("div", {
209
209
  className: "grid gap-6 xl:grid-cols-[1.1fr,1.9fr]",
210
- children: [/* @__PURE__ */ D("section", {
210
+ children: [/* @__PURE__ */ E("section", {
211
211
  className: "rounded-lg border border-border-seam bg-bg-surface p-4 xl:sticky xl:top-6 xl:self-start",
212
212
  children: [
213
- /* @__PURE__ */ D("div", {
213
+ /* @__PURE__ */ E("div", {
214
214
  className: "mb-4 flex items-center justify-between",
215
- children: [/* @__PURE__ */ E("h2", {
215
+ children: [/* @__PURE__ */ T("h2", {
216
216
  className: "text-lg font-semibold text-text-primary",
217
217
  children: $ ? "Update affiliate code" : "Create affiliate code"
218
- }), $ ? null : /* @__PURE__ */ E(b, { className: "size-4 text-text-secondary" })]
218
+ }), $ ? null : /* @__PURE__ */ T(b, { className: "size-4 text-text-secondary" })]
219
219
  }),
220
- /* @__PURE__ */ D("div", {
220
+ /* @__PURE__ */ E("div", {
221
221
  className: "space-y-3",
222
222
  children: [
223
- /* @__PURE__ */ E("input", {
223
+ /* @__PURE__ */ T("input", {
224
224
  value: Y.label,
225
225
  onChange: (e) => X((t) => ({
226
226
  ...t,
@@ -229,7 +229,7 @@ var N = [
229
229
  placeholder: "Label",
230
230
  className: "w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
231
231
  }),
232
- /* @__PURE__ */ E("input", {
232
+ /* @__PURE__ */ T("input", {
233
233
  value: Y.productSlug,
234
234
  onChange: (e) => X((t) => ({
235
235
  ...t,
@@ -239,7 +239,7 @@ var N = [
239
239
  className: "w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary",
240
240
  disabled: !!$
241
241
  }),
242
- /* @__PURE__ */ E("input", {
242
+ /* @__PURE__ */ T("input", {
243
243
  value: Y.destinationPath,
244
244
  onChange: (e) => X((t) => ({
245
245
  ...t,
@@ -248,7 +248,7 @@ var N = [
248
248
  placeholder: "Destination path (eg. /pricing)",
249
249
  className: "w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
250
250
  }),
251
- /* @__PURE__ */ E("input", {
251
+ /* @__PURE__ */ T("input", {
252
252
  value: Y.destinationUrl,
253
253
  onChange: (e) => X((t) => ({
254
254
  ...t,
@@ -257,7 +257,7 @@ var N = [
257
257
  placeholder: "Absolute destination URL (optional)",
258
258
  className: "w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
259
259
  }),
260
- /* @__PURE__ */ E("textarea", {
260
+ /* @__PURE__ */ T("textarea", {
261
261
  value: Y.description,
262
262
  onChange: (e) => X((t) => ({
263
263
  ...t,
@@ -266,7 +266,7 @@ var N = [
266
266
  placeholder: "Description",
267
267
  className: "min-h-24 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
268
268
  }),
269
- /* @__PURE__ */ E("textarea", {
269
+ /* @__PURE__ */ T("textarea", {
270
270
  value: Y.notes,
271
271
  onChange: (e) => X((t) => ({
272
272
  ...t,
@@ -277,14 +277,14 @@ var N = [
277
277
  })
278
278
  ]
279
279
  }),
280
- /* @__PURE__ */ D("div", {
280
+ /* @__PURE__ */ E("div", {
281
281
  className: "mt-4 flex flex-wrap gap-3",
282
- children: [/* @__PURE__ */ E("button", {
282
+ children: [/* @__PURE__ */ T("button", {
283
283
  type: "button",
284
- onClick: () => void ne(),
284
+ onClick: () => void re(),
285
285
  className: "rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text",
286
286
  children: $ ? "Save changes" : "Create code"
287
- }), $ ? /* @__PURE__ */ E("button", {
287
+ }), $ ? /* @__PURE__ */ T("button", {
288
288
  type: "button",
289
289
  onClick: () => {
290
290
  J(null), X({
@@ -301,32 +301,32 @@ var N = [
301
301
  }) : null]
302
302
  })
303
303
  ]
304
- }), /* @__PURE__ */ D("section", {
304
+ }), /* @__PURE__ */ E("section", {
305
305
  className: "space-y-4",
306
- children: [/* @__PURE__ */ D("div", {
306
+ children: [/* @__PURE__ */ E("div", {
307
307
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
308
- children: [/* @__PURE__ */ E("h2", {
308
+ children: [/* @__PURE__ */ T("h2", {
309
309
  className: "mb-4 text-lg font-semibold text-text-primary",
310
310
  children: "My codes"
311
- }), R.length === 0 && !U ? /* @__PURE__ */ E(A, {
311
+ }), L.length === 0 && !U ? /* @__PURE__ */ T(k, {
312
312
  illustration: "empty-data",
313
313
  title: "No affiliate codes yet",
314
314
  description: "Create your first code to start tracking attributable journeys."
315
- }) : /* @__PURE__ */ E("div", {
315
+ }) : /* @__PURE__ */ T("div", {
316
316
  className: "space-y-4",
317
- children: R.map((e) => {
317
+ children: L.map((e) => {
318
318
  let t = e.destinationUrl || `https://${e.productSlug}.com${e.destinationPath || ""}?ref=${e.code}`;
319
- return /* @__PURE__ */ D("div", {
319
+ return /* @__PURE__ */ E("div", {
320
320
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
321
321
  children: [
322
- /* @__PURE__ */ D("div", {
322
+ /* @__PURE__ */ E("div", {
323
323
  className: "flex flex-wrap items-start justify-between gap-4",
324
- children: [/* @__PURE__ */ D("div", { children: [
325
- /* @__PURE__ */ E("p", {
324
+ children: [/* @__PURE__ */ E("div", { children: [
325
+ /* @__PURE__ */ T("p", {
326
326
  className: "text-sm font-semibold text-text-primary",
327
327
  children: e.label || e.code
328
328
  }),
329
- /* @__PURE__ */ D("p", {
329
+ /* @__PURE__ */ E("p", {
330
330
  className: "text-xs text-text-secondary",
331
331
  children: [
332
332
  e.code,
@@ -334,80 +334,80 @@ var N = [
334
334
  e.productSlug
335
335
  ]
336
336
  }),
337
- /* @__PURE__ */ E("p", {
337
+ /* @__PURE__ */ T("p", {
338
338
  className: "mt-1 break-all text-xs text-text-secondary",
339
339
  children: t
340
340
  })
341
- ] }), /* @__PURE__ */ D("div", {
341
+ ] }), /* @__PURE__ */ E("div", {
342
342
  className: "flex flex-wrap gap-2",
343
343
  children: [
344
- /* @__PURE__ */ E("button", {
344
+ /* @__PURE__ */ T("button", {
345
345
  type: "button",
346
- onClick: () => re(e),
346
+ onClick: () => ie(e),
347
347
  className: "rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary",
348
348
  children: "Edit"
349
349
  }),
350
- /* @__PURE__ */ D("button", {
350
+ /* @__PURE__ */ E("button", {
351
351
  type: "button",
352
- onClick: () => void ae(e.id),
352
+ onClick: () => void oe(e.id),
353
353
  className: "inline-flex items-center gap-1 rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary",
354
- children: [/* @__PURE__ */ E(S, { className: "size-3.5" }), "Note"]
354
+ children: [/* @__PURE__ */ T(S, { className: "size-3.5" }), "Note"]
355
355
  }),
356
- e.status === "ACTIVE" ? /* @__PURE__ */ E("button", {
356
+ e.status === "ACTIVE" ? /* @__PURE__ */ T("button", {
357
357
  type: "button",
358
- onClick: () => void ie(e.id),
358
+ onClick: () => void ae(e.id),
359
359
  className: "rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-status-error-text",
360
360
  children: "Deactivate"
361
361
  }) : null
362
362
  ]
363
363
  })]
364
364
  }),
365
- /* @__PURE__ */ D("div", {
365
+ /* @__PURE__ */ E("div", {
366
366
  className: "mt-4 grid gap-3 sm:grid-cols-2 xl:grid-cols-4",
367
367
  children: [
368
- /* @__PURE__ */ D("div", {
368
+ /* @__PURE__ */ E("div", {
369
369
  className: "rounded-md border border-border-subtle bg-bg-surface p-3",
370
- children: [/* @__PURE__ */ E("p", {
370
+ children: [/* @__PURE__ */ T("p", {
371
371
  className: "text-xs text-text-secondary",
372
372
  children: "Visits"
373
- }), /* @__PURE__ */ E("p", {
373
+ }), /* @__PURE__ */ T("p", {
374
374
  className: "text-lg font-semibold text-text-primary",
375
375
  children: e.totalVisits
376
376
  })]
377
377
  }),
378
- /* @__PURE__ */ D("div", {
378
+ /* @__PURE__ */ E("div", {
379
379
  className: "rounded-md border border-border-subtle bg-bg-surface p-3",
380
- children: [/* @__PURE__ */ E("p", {
380
+ children: [/* @__PURE__ */ T("p", {
381
381
  className: "text-xs text-text-secondary",
382
382
  children: "Signups"
383
- }), /* @__PURE__ */ E("p", {
383
+ }), /* @__PURE__ */ T("p", {
384
384
  className: "text-lg font-semibold text-text-primary",
385
385
  children: e.totalSignups
386
386
  })]
387
387
  }),
388
- /* @__PURE__ */ D("div", {
388
+ /* @__PURE__ */ E("div", {
389
389
  className: "rounded-md border border-border-subtle bg-bg-surface p-3",
390
- children: [/* @__PURE__ */ E("p", {
390
+ children: [/* @__PURE__ */ T("p", {
391
391
  className: "text-xs text-text-secondary",
392
392
  children: "Paid conversions"
393
- }), /* @__PURE__ */ E("p", {
393
+ }), /* @__PURE__ */ T("p", {
394
394
  className: "text-lg font-semibold text-text-primary",
395
395
  children: e.totalPaidConversions + e.totalStorePurchases
396
396
  })]
397
397
  }),
398
- /* @__PURE__ */ D("div", {
398
+ /* @__PURE__ */ E("div", {
399
399
  className: "rounded-md border border-border-subtle bg-bg-surface p-3",
400
- children: [/* @__PURE__ */ E("p", {
400
+ children: [/* @__PURE__ */ T("p", {
401
401
  className: "text-xs text-text-secondary",
402
402
  children: "Rewards earned"
403
- }), /* @__PURE__ */ E("p", {
403
+ }), /* @__PURE__ */ T("p", {
404
404
  className: "text-lg font-semibold text-text-primary",
405
405
  children: o(e.totalRewardAmount, "USD")
406
406
  })]
407
407
  })
408
408
  ]
409
409
  }),
410
- e.notes ? /* @__PURE__ */ E("p", {
410
+ e.notes ? /* @__PURE__ */ T("p", {
411
411
  className: "mt-3 text-sm text-text-secondary",
412
412
  children: e.notes
413
413
  }) : null
@@ -415,19 +415,19 @@ var N = [
415
415
  }, e.id);
416
416
  })
417
417
  })]
418
- }), /* @__PURE__ */ D("div", {
418
+ }), /* @__PURE__ */ E("div", {
419
419
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
420
- children: [/* @__PURE__ */ E("h2", {
420
+ children: [/* @__PURE__ */ T("h2", {
421
421
  className: "mb-4 text-lg font-semibold text-text-primary",
422
422
  children: "Recent attributed journeys"
423
- }), B.length === 0 ? /* @__PURE__ */ E(A, {
423
+ }), z.length === 0 ? /* @__PURE__ */ T(k, {
424
424
  illustration: "empty-people",
425
425
  title: "No journeys yet",
426
426
  description: "Journeys will appear as visitors land on your affiliate links."
427
- }) : /* @__PURE__ */ E(M, {
428
- data: B,
427
+ }) : /* @__PURE__ */ T(j, {
428
+ data: z,
429
429
  rowKey: (e) => e.id,
430
- columns: N
430
+ columns: M
431
431
  })]
432
432
  })]
433
433
  })]
@@ -436,6 +436,6 @@ var N = [
436
436
  });
437
437
  };
438
438
  //#endregion
439
- export { P as AffiliateDashboardPage };
439
+ export { N as AffiliateDashboardPage };
440
440
 
441
441
  //# sourceMappingURL=AffiliateDashboardPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AffiliateDashboardPage.js","names":[],"sources":["../../../../../src/billing/modules/affiliate/pages/AffiliateDashboardPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState, type FC } from 'react';\nimport { Link2, Plus, RefreshCw, StickyNote, Ticket, TrendingUp, Users } from 'lucide-react';\nimport { ResponsiveTable, type ResponsiveTableColumn } from '@burdenoff/fe-libs/ui';\n\nimport { useBilling } from '../../../providers/BillingProvider';\nimport { useBillingEventEmitter } from '../../../hooks/useBillingEventEmitter';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { AccessDenied, PageHeader, ServerError, StatCard } from '../../../shared/components';\nimport {\n CTAOverflowMenu,\n PagePurpose,\n EmphasisPanel,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { formatCurrency, formatDateTime, isServerError } from '../../../shared/utils';\n\nconst journeyColumns: ResponsiveTableColumn<AffiliateJourney>[] = [\n { key: 'code', header: 'Code', priority: 'primary', cell: (journey) => journey.codeValue },\n { key: 'product', header: 'Product', cell: (journey) => journey.productSlug },\n {\n key: 'path',\n header: 'Path',\n cell: (journey) => journey.currentPath || journey.landingPath || '-',\n },\n { key: 'country', header: 'Country', cell: (journey) => journey.geographyCountry || '-' },\n { key: 'status', header: 'Status', cell: (journey) => journey.status },\n {\n key: 'visited',\n header: 'Visited',\n cell: (journey) => formatDateTime(journey.lastVisitedAt),\n },\n];\nimport {\n addAffiliateCodeNote,\n createAffiliateCode,\n deactivateAffiliateCode,\n fetchMyAffiliateAnalytics,\n fetchMyAffiliateCodes,\n fetchMyAffiliateJourneys,\n updateAffiliateCode,\n type AffiliateCode,\n type AffiliateJourney,\n type AffiliateAnalyticsSummary,\n} from '../api';\n\nexport const AffiliateDashboardPage: FC = () => {\n const permissions = useBillingPermissions();\n const { emit } = useBillingEventEmitter();\n const { apiGatewayUrl, authToken, orgId } = useBilling();\n\n const [codes, setCodes] = useState<AffiliateCode[]>([]);\n const [journeys, setJourneys] = useState<AffiliateJourney[]>([]);\n const [analytics, setAnalytics] = useState<AffiliateAnalyticsSummary | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const [selectedCodeId, setSelectedCodeId] = useState<string | null>(null);\n const [form, setForm] = useState({\n label: '',\n description: '',\n notes: '',\n productSlug: '',\n destinationPath: '',\n destinationUrl: '',\n });\n\n const requestContext = useMemo(\n () => ({\n apiGatewayUrl,\n authToken,\n orgId,\n }),\n [apiGatewayUrl, authToken, orgId]\n );\n\n const loadData = async () => {\n setLoading(true);\n setError(null);\n try {\n const [loadedCodes, loadedAnalytics, loadedJourneys] = await Promise.all([\n fetchMyAffiliateCodes(requestContext),\n fetchMyAffiliateAnalytics(requestContext),\n fetchMyAffiliateJourneys(requestContext),\n ]);\n setCodes(loadedCodes);\n setAnalytics(loadedAnalytics);\n setJourneys(loadedJourneys);\n } catch (loadError) {\n setError(\n loadError instanceof Error ? loadError : new Error('Failed to load affiliate dashboard')\n );\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n void loadData();\n }, [requestContext]);\n\n if (!permissions.canViewBillingAccount) {\n return <AccessDenied message=\"You don't have permission to view affiliate analytics.\" />;\n }\n\n if (error && isServerError(error)) {\n return (\n <ServerError\n title=\"Affiliate service unavailable\"\n message={error.message}\n onRetry={() => void loadData()}\n showRetry\n />\n );\n }\n\n const selectedCode = codes.find((item) => item.id === selectedCodeId) ?? null;\n\n const handleSubmit = async () => {\n if (!form.productSlug.trim()) {\n setError(new Error('Product slug is required'));\n return;\n }\n\n try {\n if (selectedCode) {\n await updateAffiliateCode(\n selectedCode.id,\n {\n label: form.label,\n description: form.description,\n notes: form.notes,\n destinationPath: form.destinationPath,\n destinationUrl: form.destinationUrl,\n },\n requestContext\n );\n emit('billing.affiliate_code.updated', {\n route: '/billing/affiliate',\n entityId: selectedCode.id,\n source: 'affiliate-dashboard',\n });\n } else {\n const createdCode = await createAffiliateCode(\n {\n label: form.label,\n description: form.description,\n notes: form.notes,\n productSlug: form.productSlug,\n destinationPath: form.destinationPath,\n destinationUrl: form.destinationUrl,\n },\n requestContext\n );\n emit('billing.affiliate_code.created', {\n route: '/billing/affiliate',\n entityId: createdCode.id,\n source: 'affiliate-dashboard',\n });\n }\n\n setSelectedCodeId(null);\n setForm({\n label: '',\n description: '',\n notes: '',\n productSlug: '',\n destinationPath: '',\n destinationUrl: '',\n });\n await loadData();\n } catch (submitError) {\n setError(\n submitError instanceof Error ? submitError : new Error('Failed to save affiliate code')\n );\n }\n };\n\n const handleEdit = (code: AffiliateCode) => {\n setSelectedCodeId(code.id);\n setForm({\n label: code.label ?? '',\n description: code.description ?? '',\n notes: code.notes ?? '',\n productSlug: code.productSlug,\n destinationPath: code.destinationPath ?? '',\n destinationUrl: code.destinationUrl ?? '',\n });\n };\n\n const handleDeactivate = async (codeId: string) => {\n await deactivateAffiliateCode(codeId, requestContext);\n emit('billing.affiliate_code.deactivated', {\n route: '/billing/affiliate',\n entityId: codeId,\n source: 'affiliate-dashboard',\n });\n await loadData();\n };\n\n const handleQuickNote = async (codeId: string) => {\n const note = window.prompt('Add an internal note for this affiliate code');\n if (!note) return;\n await addAffiliateCodeNote(codeId, note, requestContext);\n emit('billing.affiliate_code.note_added', {\n route: '/billing/affiliate',\n entityId: codeId,\n source: 'affiliate-dashboard',\n });\n await loadData();\n };\n\n const metricCards = analytics\n ? [\n { title: 'Codes', value: analytics.totalCodes, icon: <Ticket className=\"size-5\" /> },\n { title: 'Visits', value: analytics.totalVisits, icon: <Users className=\"size-5\" /> },\n { title: 'Journeys', value: analytics.totalJourneys, icon: <Link2 className=\"size-5\" /> },\n {\n title: 'Revenue influenced',\n value: formatCurrency(analytics.totalRevenueAmount, 'USD'),\n icon: <TrendingUp className=\"size-5\" />,\n },\n ]\n : [];\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title=\"Affiliate codes\"\n description=\"Create referral codes, add internal notes, and monitor attributed journeys.\"\n actions={\n <CTAOverflowMenu\n actions={[\n {\n label: 'Refresh',\n onSelect: () => void loadData(),\n icon: <RefreshCw className=\"size-4\" />,\n },\n ]}\n />\n }\n />\n\n <PagePurpose>\n Generate referral links for any product, share them, and see exactly what they drive —\n visits, signups, paid conversions and the rewards you have earned. Create and manage your\n codes on the left and watch attributed visitor journeys on the right.\n </PagePurpose>\n\n {loading ? (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {[1, 2, 3, 4].map((item) => (\n <div\n key={item}\n className=\"h-28 animate-pulse rounded-lg border border-border-subtle bg-bg-surface\"\n />\n ))}\n </div>\n ) : analytics ? (\n <EmphasisPanel className=\"p-4 sm:p-5\">\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {metricCards.map((card) => (\n <StatCard key={card.title} label={card.title} value={card.value} icon={card.icon} />\n ))}\n </div>\n </EmphasisPanel>\n ) : null}\n\n {error && !isServerError(error) ? (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 text-sm text-status-error-text\">\n {error.message}\n </div>\n ) : null}\n\n <div className=\"grid gap-6 xl:grid-cols-[1.1fr,1.9fr]\">\n <section className=\"rounded-lg border border-border-seam bg-bg-surface p-4 xl:sticky xl:top-6 xl:self-start\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {selectedCode ? 'Update affiliate code' : 'Create affiliate code'}\n </h2>\n {!selectedCode ? <Plus className=\"size-4 text-text-secondary\" /> : null}\n </div>\n\n <div className=\"space-y-3\">\n <input\n value={form.label}\n onChange={(event) =>\n setForm((current) => ({ ...current, label: event.target.value }))\n }\n placeholder=\"Label\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n <input\n value={form.productSlug}\n onChange={(event) =>\n setForm((current) => ({ ...current, productSlug: event.target.value }))\n }\n placeholder=\"Product slug (eg. bigconsole)\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n disabled={Boolean(selectedCode)}\n />\n <input\n value={form.destinationPath}\n onChange={(event) =>\n setForm((current) => ({ ...current, destinationPath: event.target.value }))\n }\n placeholder=\"Destination path (eg. /pricing)\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n <input\n value={form.destinationUrl}\n onChange={(event) =>\n setForm((current) => ({ ...current, destinationUrl: event.target.value }))\n }\n placeholder=\"Absolute destination URL (optional)\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n <textarea\n value={form.description}\n onChange={(event) =>\n setForm((current) => ({ ...current, description: event.target.value }))\n }\n placeholder=\"Description\"\n className=\"min-h-24 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n <textarea\n value={form.notes}\n onChange={(event) =>\n setForm((current) => ({ ...current, notes: event.target.value }))\n }\n placeholder=\"Internal notes\"\n className=\"min-h-24 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </div>\n\n <div className=\"mt-4 flex flex-wrap gap-3\">\n <button\n type=\"button\"\n onClick={() => void handleSubmit()}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text\"\n >\n {selectedCode ? 'Save changes' : 'Create code'}\n </button>\n {selectedCode ? (\n <button\n type=\"button\"\n onClick={() => {\n setSelectedCodeId(null);\n setForm({\n label: '',\n description: '',\n notes: '',\n productSlug: '',\n destinationPath: '',\n destinationUrl: '',\n });\n }}\n className=\"rounded-md border border-border-subtle bg-bg-surface px-4 py-2 text-sm font-medium text-text-primary\"\n >\n Cancel\n </button>\n ) : null}\n </div>\n </section>\n\n <section className=\"space-y-4\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">My codes</h2>\n {codes.length === 0 && !loading ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No affiliate codes yet\"\n description=\"Create your first code to start tracking attributable journeys.\"\n />\n ) : (\n <div className=\"space-y-4\">\n {codes.map((code) => {\n const shareUrl =\n code.destinationUrl ||\n `https://${code.productSlug}.com${code.destinationPath || ''}?ref=${code.code}`;\n return (\n <div\n key={code.id}\n className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\"\n >\n <div className=\"flex flex-wrap items-start justify-between gap-4\">\n <div>\n <p className=\"text-sm font-semibold text-text-primary\">\n {code.label || code.code}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {code.code} · {code.productSlug}\n </p>\n <p className=\"mt-1 break-all text-xs text-text-secondary\">{shareUrl}</p>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={() => handleEdit(code)}\n className=\"rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary\"\n >\n Edit\n </button>\n <button\n type=\"button\"\n onClick={() => void handleQuickNote(code.id)}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary\"\n >\n <StickyNote className=\"size-3.5\" />\n Note\n </button>\n {code.status === 'ACTIVE' ? (\n <button\n type=\"button\"\n onClick={() => void handleDeactivate(code.id)}\n className=\"rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-status-error-text\"\n >\n Deactivate\n </button>\n ) : null}\n </div>\n </div>\n <div className=\"mt-4 grid gap-3 sm:grid-cols-2 xl:grid-cols-4\">\n <div className=\"rounded-md border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Visits</p>\n <p className=\"text-lg font-semibold text-text-primary\">\n {code.totalVisits}\n </p>\n </div>\n <div className=\"rounded-md border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Signups</p>\n <p className=\"text-lg font-semibold text-text-primary\">\n {code.totalSignups}\n </p>\n </div>\n <div className=\"rounded-md border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Paid conversions</p>\n <p className=\"text-lg font-semibold text-text-primary\">\n {code.totalPaidConversions + code.totalStorePurchases}\n </p>\n </div>\n <div className=\"rounded-md border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Rewards earned</p>\n <p className=\"text-lg font-semibold text-text-primary\">\n {formatCurrency(code.totalRewardAmount, 'USD')}\n </p>\n </div>\n </div>\n {code.notes ? (\n <p className=\"mt-3 text-sm text-text-secondary\">{code.notes}</p>\n ) : null}\n </div>\n );\n })}\n </div>\n )}\n </div>\n\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">\n Recent attributed journeys\n </h2>\n {journeys.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title=\"No journeys yet\"\n description=\"Journeys will appear as visitors land on your affiliate links.\"\n />\n ) : (\n <ResponsiveTable\n data={journeys}\n rowKey={(journey) => journey.id}\n columns={journeyColumns}\n />\n )}\n </div>\n </section>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AffiliateDashboardPage.js","names":[],"sources":["../../../../../src/billing/modules/affiliate/pages/AffiliateDashboardPage.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState, type FC } from 'react';\nimport { Link2, Plus, RefreshCw, StickyNote, Ticket, TrendingUp, Users } from 'lucide-react';\nimport { ResponsiveTable, type ResponsiveTableColumn } from '@burdenoff/fe-libs/ui';\n\nimport { useBilling } from '../../../providers/BillingProvider';\nimport { useBillingEventEmitter } from '../../../hooks/useBillingEventEmitter';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { AccessDenied, PageHeader, ServerError, StatCard } from '../../../shared/components';\nimport {\n CTAOverflowMenu,\n PagePurpose,\n EmphasisPanel,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { formatCurrency, formatDateTime, isServerError } from '../../../shared/utils';\n\nconst journeyColumns: ResponsiveTableColumn<AffiliateJourney>[] = [\n { key: 'code', header: 'Code', priority: 'primary', cell: (journey) => journey.codeValue },\n { key: 'product', header: 'Product', cell: (journey) => journey.productSlug },\n {\n key: 'path',\n header: 'Path',\n cell: (journey) => journey.currentPath || journey.landingPath || '-',\n },\n { key: 'country', header: 'Country', cell: (journey) => journey.geographyCountry || '-' },\n { key: 'status', header: 'Status', cell: (journey) => journey.status },\n {\n key: 'visited',\n header: 'Visited',\n cell: (journey) => formatDateTime(journey.lastVisitedAt),\n },\n];\nimport {\n addAffiliateCodeNote,\n createAffiliateCode,\n deactivateAffiliateCode,\n fetchMyAffiliateAnalytics,\n fetchMyAffiliateCodes,\n fetchMyAffiliateJourneys,\n updateAffiliateCode,\n type AffiliateCode,\n type AffiliateJourney,\n type AffiliateAnalyticsSummary,\n} from '../api';\n\nexport const AffiliateDashboardPage: FC = () => {\n const permissions = useBillingPermissions();\n const { emit } = useBillingEventEmitter();\n const { apiGatewayUrl, authToken, orgId } = useBilling();\n\n const [codes, setCodes] = useState<AffiliateCode[]>([]);\n const [journeys, setJourneys] = useState<AffiliateJourney[]>([]);\n const [analytics, setAnalytics] = useState<AffiliateAnalyticsSummary | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const [selectedCodeId, setSelectedCodeId] = useState<string | null>(null);\n const [form, setForm] = useState({\n label: '',\n description: '',\n notes: '',\n productSlug: '',\n destinationPath: '',\n destinationUrl: '',\n });\n\n const requestContext = useMemo(\n () => ({\n apiGatewayUrl,\n authToken,\n orgId,\n }),\n [apiGatewayUrl, authToken, orgId]\n );\n\n const loadData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const [loadedCodes, loadedAnalytics, loadedJourneys] = await Promise.all([\n fetchMyAffiliateCodes(requestContext),\n fetchMyAffiliateAnalytics(requestContext),\n fetchMyAffiliateJourneys(requestContext),\n ]);\n setCodes(loadedCodes);\n setAnalytics(loadedAnalytics);\n setJourneys(loadedJourneys);\n } catch (loadError) {\n setError(\n loadError instanceof Error ? loadError : new Error('Failed to load affiliate dashboard')\n );\n } finally {\n setLoading(false);\n }\n }, [requestContext]);\n\n useEffect(() => {\n void loadData();\n }, [loadData]);\n\n if (!permissions.canViewBillingAccount) {\n return <AccessDenied message=\"You don't have permission to view affiliate analytics.\" />;\n }\n\n if (error && isServerError(error)) {\n return (\n <ServerError\n title=\"Affiliate service unavailable\"\n message={error.message}\n onRetry={() => void loadData()}\n showRetry\n />\n );\n }\n\n const selectedCode = codes.find((item) => item.id === selectedCodeId) ?? null;\n\n const handleSubmit = async () => {\n if (!form.productSlug.trim()) {\n setError(new Error('Product slug is required'));\n return;\n }\n\n try {\n if (selectedCode) {\n await updateAffiliateCode(\n selectedCode.id,\n {\n label: form.label,\n description: form.description,\n notes: form.notes,\n destinationPath: form.destinationPath,\n destinationUrl: form.destinationUrl,\n },\n requestContext\n );\n emit('billing.affiliate_code.updated', {\n route: '/billing/affiliate',\n entityId: selectedCode.id,\n source: 'affiliate-dashboard',\n });\n } else {\n const createdCode = await createAffiliateCode(\n {\n label: form.label,\n description: form.description,\n notes: form.notes,\n productSlug: form.productSlug,\n destinationPath: form.destinationPath,\n destinationUrl: form.destinationUrl,\n },\n requestContext\n );\n emit('billing.affiliate_code.created', {\n route: '/billing/affiliate',\n entityId: createdCode.id,\n source: 'affiliate-dashboard',\n });\n }\n\n setSelectedCodeId(null);\n setForm({\n label: '',\n description: '',\n notes: '',\n productSlug: '',\n destinationPath: '',\n destinationUrl: '',\n });\n await loadData();\n } catch (submitError) {\n setError(\n submitError instanceof Error ? submitError : new Error('Failed to save affiliate code')\n );\n }\n };\n\n const handleEdit = (code: AffiliateCode) => {\n setSelectedCodeId(code.id);\n setForm({\n label: code.label ?? '',\n description: code.description ?? '',\n notes: code.notes ?? '',\n productSlug: code.productSlug,\n destinationPath: code.destinationPath ?? '',\n destinationUrl: code.destinationUrl ?? '',\n });\n };\n\n const handleDeactivate = async (codeId: string) => {\n await deactivateAffiliateCode(codeId, requestContext);\n emit('billing.affiliate_code.deactivated', {\n route: '/billing/affiliate',\n entityId: codeId,\n source: 'affiliate-dashboard',\n });\n await loadData();\n };\n\n const handleQuickNote = async (codeId: string) => {\n const note = window.prompt('Add an internal note for this affiliate code');\n if (!note) return;\n await addAffiliateCodeNote(codeId, note, requestContext);\n emit('billing.affiliate_code.note_added', {\n route: '/billing/affiliate',\n entityId: codeId,\n source: 'affiliate-dashboard',\n });\n await loadData();\n };\n\n const metricCards = analytics\n ? [\n { title: 'Codes', value: analytics.totalCodes, icon: <Ticket className=\"size-5\" /> },\n { title: 'Visits', value: analytics.totalVisits, icon: <Users className=\"size-5\" /> },\n { title: 'Journeys', value: analytics.totalJourneys, icon: <Link2 className=\"size-5\" /> },\n {\n title: 'Revenue influenced',\n value: formatCurrency(analytics.totalRevenueAmount, 'USD'),\n icon: <TrendingUp className=\"size-5\" />,\n },\n ]\n : [];\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title=\"Affiliate codes\"\n description=\"Create referral codes, add internal notes, and monitor attributed journeys.\"\n actions={\n <CTAOverflowMenu\n actions={[\n {\n label: 'Refresh',\n onSelect: () => void loadData(),\n icon: <RefreshCw className=\"size-4\" />,\n },\n ]}\n />\n }\n />\n\n <PagePurpose>\n Generate referral links for any product, share them, and see exactly what they drive —\n visits, signups, paid conversions and the rewards you have earned. Create and manage your\n codes on the left and watch attributed visitor journeys on the right.\n </PagePurpose>\n\n {loading ? (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {[1, 2, 3, 4].map((item) => (\n <div\n key={item}\n className=\"h-28 animate-pulse rounded-lg border border-border-subtle bg-bg-surface\"\n />\n ))}\n </div>\n ) : analytics ? (\n <EmphasisPanel className=\"p-4 sm:p-5\">\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {metricCards.map((card) => (\n <StatCard key={card.title} label={card.title} value={card.value} icon={card.icon} />\n ))}\n </div>\n </EmphasisPanel>\n ) : null}\n\n {error && !isServerError(error) ? (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 text-sm text-status-error-text\">\n {error.message}\n </div>\n ) : null}\n\n <div className=\"grid gap-6 xl:grid-cols-[1.1fr,1.9fr]\">\n <section className=\"rounded-lg border border-border-seam bg-bg-surface p-4 xl:sticky xl:top-6 xl:self-start\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {selectedCode ? 'Update affiliate code' : 'Create affiliate code'}\n </h2>\n {!selectedCode ? <Plus className=\"size-4 text-text-secondary\" /> : null}\n </div>\n\n <div className=\"space-y-3\">\n <input\n value={form.label}\n onChange={(event) =>\n setForm((current) => ({ ...current, label: event.target.value }))\n }\n placeholder=\"Label\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n <input\n value={form.productSlug}\n onChange={(event) =>\n setForm((current) => ({ ...current, productSlug: event.target.value }))\n }\n placeholder=\"Product slug (eg. bigconsole)\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n disabled={Boolean(selectedCode)}\n />\n <input\n value={form.destinationPath}\n onChange={(event) =>\n setForm((current) => ({ ...current, destinationPath: event.target.value }))\n }\n placeholder=\"Destination path (eg. /pricing)\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n <input\n value={form.destinationUrl}\n onChange={(event) =>\n setForm((current) => ({ ...current, destinationUrl: event.target.value }))\n }\n placeholder=\"Absolute destination URL (optional)\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n <textarea\n value={form.description}\n onChange={(event) =>\n setForm((current) => ({ ...current, description: event.target.value }))\n }\n placeholder=\"Description\"\n className=\"min-h-24 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n <textarea\n value={form.notes}\n onChange={(event) =>\n setForm((current) => ({ ...current, notes: event.target.value }))\n }\n placeholder=\"Internal notes\"\n className=\"min-h-24 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </div>\n\n <div className=\"mt-4 flex flex-wrap gap-3\">\n <button\n type=\"button\"\n onClick={() => void handleSubmit()}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text\"\n >\n {selectedCode ? 'Save changes' : 'Create code'}\n </button>\n {selectedCode ? (\n <button\n type=\"button\"\n onClick={() => {\n setSelectedCodeId(null);\n setForm({\n label: '',\n description: '',\n notes: '',\n productSlug: '',\n destinationPath: '',\n destinationUrl: '',\n });\n }}\n className=\"rounded-md border border-border-subtle bg-bg-surface px-4 py-2 text-sm font-medium text-text-primary\"\n >\n Cancel\n </button>\n ) : null}\n </div>\n </section>\n\n <section className=\"space-y-4\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">My codes</h2>\n {codes.length === 0 && !loading ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No affiliate codes yet\"\n description=\"Create your first code to start tracking attributable journeys.\"\n />\n ) : (\n <div className=\"space-y-4\">\n {codes.map((code) => {\n const shareUrl =\n code.destinationUrl ||\n `https://${code.productSlug}.com${code.destinationPath || ''}?ref=${code.code}`;\n return (\n <div\n key={code.id}\n className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\"\n >\n <div className=\"flex flex-wrap items-start justify-between gap-4\">\n <div>\n <p className=\"text-sm font-semibold text-text-primary\">\n {code.label || code.code}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {code.code} · {code.productSlug}\n </p>\n <p className=\"mt-1 break-all text-xs text-text-secondary\">{shareUrl}</p>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={() => handleEdit(code)}\n className=\"rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary\"\n >\n Edit\n </button>\n <button\n type=\"button\"\n onClick={() => void handleQuickNote(code.id)}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary\"\n >\n <StickyNote className=\"size-3.5\" />\n Note\n </button>\n {code.status === 'ACTIVE' ? (\n <button\n type=\"button\"\n onClick={() => void handleDeactivate(code.id)}\n className=\"rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-status-error-text\"\n >\n Deactivate\n </button>\n ) : null}\n </div>\n </div>\n <div className=\"mt-4 grid gap-3 sm:grid-cols-2 xl:grid-cols-4\">\n <div className=\"rounded-md border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Visits</p>\n <p className=\"text-lg font-semibold text-text-primary\">\n {code.totalVisits}\n </p>\n </div>\n <div className=\"rounded-md border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Signups</p>\n <p className=\"text-lg font-semibold text-text-primary\">\n {code.totalSignups}\n </p>\n </div>\n <div className=\"rounded-md border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Paid conversions</p>\n <p className=\"text-lg font-semibold text-text-primary\">\n {code.totalPaidConversions + code.totalStorePurchases}\n </p>\n </div>\n <div className=\"rounded-md border border-border-subtle bg-bg-surface p-3\">\n <p className=\"text-xs text-text-secondary\">Rewards earned</p>\n <p className=\"text-lg font-semibold text-text-primary\">\n {formatCurrency(code.totalRewardAmount, 'USD')}\n </p>\n </div>\n </div>\n {code.notes ? (\n <p className=\"mt-3 text-sm text-text-secondary\">{code.notes}</p>\n ) : null}\n </div>\n );\n })}\n </div>\n )}\n </div>\n\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">\n Recent attributed journeys\n </h2>\n {journeys.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title=\"No journeys yet\"\n description=\"Journeys will appear as visitors land on your affiliate links.\"\n />\n ) : (\n <ResponsiveTable\n data={journeys}\n rowKey={(journey) => journey.id}\n columns={journeyColumns}\n />\n )}\n </div>\n </section>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}