@datatechsolutions/ui 3.13.0 → 3.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/dist/astrlabe/graph-node.js +6 -6
  2. package/dist/astrlabe/graph-node.mjs +2 -2
  3. package/dist/astrlabe/index.js +114 -114
  4. package/dist/astrlabe/index.mjs +6 -6
  5. package/dist/astrlabe/workflow-canvas.js +6 -6
  6. package/dist/astrlabe/workflow-canvas.mjs +5 -5
  7. package/dist/{chunk-AMCFAGK3.js → chunk-2II2NLAZ.js} +42 -41
  8. package/dist/chunk-2II2NLAZ.js.map +1 -0
  9. package/dist/{chunk-WR55H7DH.mjs → chunk-2SBVFLPZ.mjs} +19 -2
  10. package/dist/chunk-2SBVFLPZ.mjs.map +1 -0
  11. package/dist/{chunk-UXHJS2SH.mjs → chunk-33ZWFDVG.mjs} +282 -331
  12. package/dist/chunk-33ZWFDVG.mjs.map +1 -0
  13. package/dist/{chunk-2ECLDHAT.js → chunk-4HZ55YKZ.js} +9 -9
  14. package/dist/{chunk-2ECLDHAT.js.map → chunk-4HZ55YKZ.js.map} +1 -1
  15. package/dist/{chunk-VI4IUTMX.js → chunk-4P72IJOM.js} +6 -6
  16. package/dist/{chunk-VI4IUTMX.js.map → chunk-4P72IJOM.js.map} +1 -1
  17. package/dist/{chunk-D5OTZGA2.js → chunk-5SCZB5UI.js} +382 -431
  18. package/dist/chunk-5SCZB5UI.js.map +1 -0
  19. package/dist/{chunk-4VHFGW7I.mjs → chunk-5YCH7FHT.mjs} +3 -3
  20. package/dist/{chunk-4VHFGW7I.mjs.map → chunk-5YCH7FHT.mjs.map} +1 -1
  21. package/dist/{chunk-P4RVGMZL.js → chunk-6NBQTIXX.js} +9 -37
  22. package/dist/chunk-6NBQTIXX.js.map +1 -0
  23. package/dist/{chunk-EZQ2D47U.js → chunk-6NEESZVO.js} +4 -4
  24. package/dist/{chunk-EZQ2D47U.js.map → chunk-6NEESZVO.js.map} +1 -1
  25. package/dist/{chunk-N4YT3QA5.js → chunk-72XZ7DSF.js} +13 -13
  26. package/dist/{chunk-N4YT3QA5.js.map → chunk-72XZ7DSF.js.map} +1 -1
  27. package/dist/{chunk-QGRTV35L.mjs → chunk-7NHJSD4A.mjs} +6 -6
  28. package/dist/{chunk-QGRTV35L.mjs.map → chunk-7NHJSD4A.mjs.map} +1 -1
  29. package/dist/{chunk-PPIUMCUZ.js → chunk-7SDB2VC2.js} +4 -4
  30. package/dist/{chunk-PPIUMCUZ.js.map → chunk-7SDB2VC2.js.map} +1 -1
  31. package/dist/{chunk-QGLGQXJE.js → chunk-A5OMGPMR.js} +10 -10
  32. package/dist/chunk-A5OMGPMR.js.map +1 -0
  33. package/dist/{chunk-K5567JM5.js → chunk-AUCS2KF4.js} +26 -26
  34. package/dist/{chunk-K5567JM5.js.map → chunk-AUCS2KF4.js.map} +1 -1
  35. package/dist/{chunk-MSKKNPRE.mjs → chunk-F4KHAKTP.mjs} +172 -116
  36. package/dist/chunk-F4KHAKTP.mjs.map +1 -0
  37. package/dist/{chunk-SDYKXLCU.js → chunk-FHGWXWVZ.js} +67 -67
  38. package/dist/{chunk-SDYKXLCU.js.map → chunk-FHGWXWVZ.js.map} +1 -1
  39. package/dist/{chunk-5ETT54QS.js → chunk-FZUV7GNB.js} +241 -184
  40. package/dist/chunk-FZUV7GNB.js.map +1 -0
  41. package/dist/{chunk-6KDTVSZT.mjs → chunk-HQNIETHV.mjs} +11 -10
  42. package/dist/chunk-HQNIETHV.mjs.map +1 -0
  43. package/dist/{chunk-PLTLRL2V.mjs → chunk-KDDXDQR2.mjs} +3 -3
  44. package/dist/{chunk-PLTLRL2V.mjs.map → chunk-KDDXDQR2.mjs.map} +1 -1
  45. package/dist/{chunk-6YTYD4P5.js → chunk-LJGPMMKB.js} +156 -193
  46. package/dist/chunk-LJGPMMKB.js.map +1 -0
  47. package/dist/{chunk-BHOT22QL.js → chunk-MXQ2EYG2.js} +19 -2
  48. package/dist/chunk-MXQ2EYG2.js.map +1 -0
  49. package/dist/{chunk-ANFSQJNI.mjs → chunk-N6SGVUTR.mjs} +17 -20
  50. package/dist/chunk-N6SGVUTR.mjs.map +1 -0
  51. package/dist/{chunk-IIRS5XZY.js → chunk-NIZSQJRW.js} +33 -33
  52. package/dist/{chunk-IIRS5XZY.js.map → chunk-NIZSQJRW.js.map} +1 -1
  53. package/dist/{chunk-AKWCT53S.mjs → chunk-NXWIT4YQ.mjs} +47 -50
  54. package/dist/chunk-NXWIT4YQ.mjs.map +1 -0
  55. package/dist/{chunk-OC4AOYU5.mjs → chunk-OTQXU4WG.mjs} +83 -120
  56. package/dist/chunk-OTQXU4WG.mjs.map +1 -0
  57. package/dist/{chunk-CSOMZ5UM.mjs → chunk-PO66V2PN.mjs} +9 -9
  58. package/dist/{chunk-CSOMZ5UM.mjs.map → chunk-PO66V2PN.mjs.map} +1 -1
  59. package/dist/{chunk-OY5HUZSD.js → chunk-PXGESUKI.js} +94 -97
  60. package/dist/chunk-PXGESUKI.js.map +1 -0
  61. package/dist/{chunk-7TYNV6SY.mjs → chunk-Q2FUNDCP.mjs} +14 -14
  62. package/dist/{chunk-7TYNV6SY.mjs.map → chunk-Q2FUNDCP.mjs.map} +1 -1
  63. package/dist/{chunk-KWH7JIRP.mjs → chunk-Q5TZTA6H.mjs} +9 -8
  64. package/dist/chunk-Q5TZTA6H.mjs.map +1 -0
  65. package/dist/{chunk-ZRCXDKBE.mjs → chunk-T7DROKWJ.mjs} +4 -4
  66. package/dist/{chunk-ZRCXDKBE.mjs.map → chunk-T7DROKWJ.mjs.map} +1 -1
  67. package/dist/{chunk-3VYD7QL2.mjs → chunk-TQADF23S.mjs} +9 -9
  68. package/dist/chunk-TQADF23S.mjs.map +1 -0
  69. package/dist/{chunk-VIB42VMZ.mjs → chunk-U7VMFQFN.mjs} +5 -5
  70. package/dist/{chunk-VIB42VMZ.mjs.map → chunk-U7VMFQFN.mjs.map} +1 -1
  71. package/dist/{chunk-AHNH2PMI.mjs → chunk-WE35EV7J.mjs} +3 -3
  72. package/dist/{chunk-AHNH2PMI.mjs.map → chunk-WE35EV7J.mjs.map} +1 -1
  73. package/dist/{chunk-UPYACFZJ.mjs → chunk-WTSMTLSP.mjs} +303 -347
  74. package/dist/chunk-WTSMTLSP.mjs.map +1 -0
  75. package/dist/{chunk-WOTKBKS6.js → chunk-YFMMZHL5.js} +47 -50
  76. package/dist/chunk-YFMMZHL5.js.map +1 -0
  77. package/dist/{chunk-DJ33CSGJ.mjs → chunk-ZBX7UCAP.mjs} +9 -37
  78. package/dist/chunk-ZBX7UCAP.mjs.map +1 -0
  79. package/dist/{chunk-NF5DDM5V.js → chunk-ZE6U4N4Q.js} +44 -43
  80. package/dist/chunk-ZE6U4N4Q.js.map +1 -0
  81. package/dist/{chunk-MQDCUBVW.js → chunk-ZIRD3X6G.js} +459 -503
  82. package/dist/chunk-ZIRD3X6G.js.map +1 -0
  83. package/dist/index.d.mts +77 -7
  84. package/dist/index.d.ts +77 -7
  85. package/dist/index.js +708 -704
  86. package/dist/index.mjs +3 -3
  87. package/dist/platform/admin/index.js +12 -12
  88. package/dist/platform/admin/index.mjs +6 -6
  89. package/dist/platform/agents-workspace.js +9 -9
  90. package/dist/platform/agents-workspace.mjs +8 -8
  91. package/dist/platform/app-shell.js +5 -5
  92. package/dist/platform/app-shell.mjs +4 -4
  93. package/dist/platform/auth/index.js +29 -29
  94. package/dist/platform/auth/index.mjs +6 -6
  95. package/dist/platform/billing/index.js +7 -7
  96. package/dist/platform/billing/index.mjs +5 -5
  97. package/dist/platform/impersonation/index.js +5 -5
  98. package/dist/platform/impersonation/index.mjs +4 -4
  99. package/dist/platform/index.js +99 -99
  100. package/dist/platform/index.js.map +1 -1
  101. package/dist/platform/index.mjs +30 -30
  102. package/dist/platform/index.mjs.map +1 -1
  103. package/dist/platform/pages/index.d.mts +115 -3
  104. package/dist/platform/pages/index.d.ts +115 -3
  105. package/dist/platform/pages/index.js +966 -519
  106. package/dist/platform/pages/index.js.map +1 -1
  107. package/dist/platform/pages/index.mjs +562 -121
  108. package/dist/platform/pages/index.mjs.map +1 -1
  109. package/dist/platform/settings/index.js +9 -9
  110. package/dist/platform/settings/index.mjs +8 -8
  111. package/dist/platform/workflow-canvas-shell.js +7 -7
  112. package/dist/platform/workflow-canvas-shell.mjs +6 -6
  113. package/package.json +1 -1
  114. package/dist/chunk-3VYD7QL2.mjs.map +0 -1
  115. package/dist/chunk-5ETT54QS.js.map +0 -1
  116. package/dist/chunk-6KDTVSZT.mjs.map +0 -1
  117. package/dist/chunk-6YTYD4P5.js.map +0 -1
  118. package/dist/chunk-AKWCT53S.mjs.map +0 -1
  119. package/dist/chunk-AMCFAGK3.js.map +0 -1
  120. package/dist/chunk-ANFSQJNI.mjs.map +0 -1
  121. package/dist/chunk-BHOT22QL.js.map +0 -1
  122. package/dist/chunk-D5OTZGA2.js.map +0 -1
  123. package/dist/chunk-DJ33CSGJ.mjs.map +0 -1
  124. package/dist/chunk-KWH7JIRP.mjs.map +0 -1
  125. package/dist/chunk-MQDCUBVW.js.map +0 -1
  126. package/dist/chunk-MSKKNPRE.mjs.map +0 -1
  127. package/dist/chunk-NF5DDM5V.js.map +0 -1
  128. package/dist/chunk-OC4AOYU5.mjs.map +0 -1
  129. package/dist/chunk-OY5HUZSD.js.map +0 -1
  130. package/dist/chunk-P4RVGMZL.js.map +0 -1
  131. package/dist/chunk-QGLGQXJE.js.map +0 -1
  132. package/dist/chunk-UPYACFZJ.mjs.map +0 -1
  133. package/dist/chunk-UXHJS2SH.mjs.map +0 -1
  134. package/dist/chunk-WOTKBKS6.js.map +0 -1
  135. package/dist/chunk-WR55H7DH.mjs.map +0 -1
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunk5ETT54QS_js = require('./chunk-5ETT54QS.js');
4
+ var chunkFZUV7GNB_js = require('./chunk-FZUV7GNB.js');
5
5
  var chunkY5VN4SPH_js = require('./chunk-Y5VN4SPH.js');
6
- var chunkBHOT22QL_js = require('./chunk-BHOT22QL.js');
6
+ var chunkMXQ2EYG2_js = require('./chunk-MXQ2EYG2.js');
7
7
  var chunkUZ3CMNUJ_js = require('./chunk-UZ3CMNUJ.js');
8
8
  var react = require('react');
9
9
  var jsxRuntime = require('react/jsx-runtime');
@@ -20,7 +20,7 @@ function BillingPanel({
20
20
  }) {
21
21
  const t = chunkY5VN4SPH_js.useTranslations("windsock");
22
22
  const format = chunkY5VN4SPH_js.useFormatter();
23
- const { client } = chunk5ETT54QS_js.useAuth();
23
+ const { client } = chunkFZUV7GNB_js.useAuth();
24
24
  const [subscription, setSubscription] = react.useState(null);
25
25
  const [plans, setPlans] = react.useState([]);
26
26
  const [isLoading, setIsLoading] = react.useState(true);
@@ -104,7 +104,7 @@ function BillingPanel({
104
104
  }
105
105
  }, [client, load, t]);
106
106
  if (isLoading) {
107
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx(chunk5ETT54QS_js.InlineSpinner, {}) });
107
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx(chunkFZUV7GNB_js.InlineSpinner, {}) });
108
108
  }
109
109
  const currentPlan = subscription?.plan ?? plans.find((plan) => plan.id === subscription?.planId) ?? null;
110
110
  const currentTier = subscription?.tier ?? currentPlan?.tier ?? null;
@@ -118,7 +118,7 @@ function BillingPanel({
118
118
  }
119
119
  ),
120
120
  /* @__PURE__ */ jsxRuntime.jsx(
121
- chunk5ETT54QS_js.SectionCard,
121
+ chunkFZUV7GNB_js.SectionCard,
122
122
  {
123
123
  header: {
124
124
  title: t("billing.currentPlan.title"),
@@ -126,20 +126,20 @@ function BillingPanel({
126
126
  },
127
127
  children: subscription && currentPlan ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
128
128
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
129
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: currentPlan.name }),
129
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg font-semibold text-slate-900 dark:text-white", children: currentPlan.name }),
130
130
  /* @__PURE__ */ jsxRuntime.jsx(
131
- chunk5ETT54QS_js.StatusBadge,
131
+ chunkFZUV7GNB_js.StatusBadge,
132
132
  {
133
133
  status: subscription.status === "active" ? "success" : subscription.status === "past_due" ? "pending" : "error",
134
134
  label: t(`billing.status.${subscription.status}`)
135
135
  }
136
136
  ),
137
- subscription.cancelAtPeriodEnd && /* @__PURE__ */ jsxRuntime.jsx(chunkBHOT22QL_js.Badge, { color: "amber", children: t("billing.currentPlan.cancelAtPeriodEnd") })
137
+ subscription.cancelAtPeriodEnd && /* @__PURE__ */ jsxRuntime.jsx(chunkMXQ2EYG2_js.Badge, { color: "amber", children: t("billing.currentPlan.cancelAtPeriodEnd") })
138
138
  ] }),
139
139
  /* @__PURE__ */ jsxRuntime.jsxs("dl", { className: "grid grid-cols-1 gap-3 text-sm sm:grid-cols-2", children: [
140
140
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
141
- /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-gray-500 dark:text-gray-400", children: t("billing.currentPlan.price") }),
142
- /* @__PURE__ */ jsxRuntime.jsxs("dd", { className: "font-medium text-gray-900 dark:text-white", children: [
141
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-slate-500 dark:text-slate-400", children: t("billing.currentPlan.price") }),
142
+ /* @__PURE__ */ jsxRuntime.jsxs("dd", { className: "font-medium text-slate-900 dark:text-white", children: [
143
143
  format.number(currentPlan.price, { style: "currency", currency: currentPlan.currency }),
144
144
  " ",
145
145
  "/",
@@ -148,13 +148,13 @@ function BillingPanel({
148
148
  ] })
149
149
  ] }),
150
150
  subscription.currentPeriodEnd && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
151
- /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-gray-500 dark:text-gray-400", children: t("billing.currentPlan.renewsOn") }),
152
- /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "font-medium text-gray-900 dark:text-white", children: format.dateTime(new Date(subscription.currentPeriodEnd), { dateStyle: "medium" }) })
151
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-slate-500 dark:text-slate-400", children: t("billing.currentPlan.renewsOn") }),
152
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "font-medium text-slate-900 dark:text-white", children: format.dateTime(new Date(subscription.currentPeriodEnd), { dateStyle: "medium" }) })
153
153
  ] })
154
154
  ] }),
155
155
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2 pt-2", children: [
156
156
  /* @__PURE__ */ jsxRuntime.jsx(
157
- chunkBHOT22QL_js.Button,
157
+ chunkMXQ2EYG2_js.Button,
158
158
  {
159
159
  size: "sm",
160
160
  color: "ios-glass-blue",
@@ -165,7 +165,7 @@ function BillingPanel({
165
165
  }
166
166
  ),
167
167
  subscription.status === "active" && !subscription.cancelAtPeriodEnd && /* @__PURE__ */ jsxRuntime.jsx(
168
- chunkBHOT22QL_js.Button,
168
+ chunkMXQ2EYG2_js.Button,
169
169
  {
170
170
  size: "sm",
171
171
  color: "ios-glass-red",
@@ -176,25 +176,25 @@ function BillingPanel({
176
176
  }
177
177
  )
178
178
  ] })
179
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: t("billing.currentPlan.noSubscription") })
179
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-slate-500 dark:text-slate-400", children: t("billing.currentPlan.noSubscription") })
180
180
  }
181
181
  ),
182
182
  /* @__PURE__ */ jsxRuntime.jsx(
183
- chunk5ETT54QS_js.SectionCard,
183
+ chunkFZUV7GNB_js.SectionCard,
184
184
  {
185
185
  header: {
186
186
  title: t("billing.plans.title"),
187
187
  subtitle: t("billing.plans.description")
188
188
  },
189
- children: plans.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: t("billing.plans.empty") }) : /* @__PURE__ */ jsxRuntime.jsx(chunk5ETT54QS_js.ListCard, { children: plans.map((plan) => {
189
+ children: plans.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-slate-500 dark:text-slate-400", children: t("billing.plans.empty") }) : /* @__PURE__ */ jsxRuntime.jsx(chunkFZUV7GNB_js.ListCard, { children: plans.map((plan) => {
190
190
  const isCurrent = currentPlan?.id === plan.id;
191
191
  const isDowngrade = currentTier != null && (TIER_ORDER[plan.tier] ?? 0) < (TIER_ORDER[currentTier] ?? 0);
192
192
  return /* @__PURE__ */ jsxRuntime.jsx(
193
- chunk5ETT54QS_js.ListCardItem,
193
+ chunkFZUV7GNB_js.ListCardItem,
194
194
  {
195
195
  leading: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-xl bg-gradient-to-br from-violet-500/20 to-blue-500/20 text-violet-600 dark:text-violet-300", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-bold uppercase", children: plan.tier.charAt(0) }) }),
196
- trailing: isCurrent ? /* @__PURE__ */ jsxRuntime.jsx(chunkBHOT22QL_js.Badge, { color: "green", children: t("billing.plans.currentBadge") }) : isDowngrade ? /* @__PURE__ */ jsxRuntime.jsx(
197
- chunkBHOT22QL_js.Button,
196
+ trailing: isCurrent ? /* @__PURE__ */ jsxRuntime.jsx(chunkMXQ2EYG2_js.Badge, { color: "green", children: t("billing.plans.currentBadge") }) : isDowngrade ? /* @__PURE__ */ jsxRuntime.jsx(
197
+ chunkMXQ2EYG2_js.Button,
198
198
  {
199
199
  size: "sm",
200
200
  plain: true,
@@ -204,7 +204,7 @@ function BillingPanel({
204
204
  children: t("billing.plans.downgradeAction")
205
205
  }
206
206
  ) : /* @__PURE__ */ jsxRuntime.jsx(
207
- chunkBHOT22QL_js.Button,
207
+ chunkMXQ2EYG2_js.Button,
208
208
  {
209
209
  size: "sm",
210
210
  color: "ios-glass-blue",
@@ -216,8 +216,8 @@ function BillingPanel({
216
216
  ),
217
217
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
218
218
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
219
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-900 dark:text-white", children: plan.name }),
220
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
219
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-slate-900 dark:text-white", children: plan.name }),
220
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-slate-500 dark:text-slate-400", children: [
221
221
  format.number(plan.price, { style: "currency", currency: plan.currency }),
222
222
  " ",
223
223
  "/",
@@ -225,7 +225,7 @@ function BillingPanel({
225
225
  t(`billing.interval.${plan.interval}`)
226
226
  ] })
227
227
  ] }),
228
- plan.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: plan.description })
228
+ plan.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: plan.description })
229
229
  ] })
230
230
  },
231
231
  plan.id
@@ -237,5 +237,5 @@ function BillingPanel({
237
237
  }
238
238
 
239
239
  exports.BillingPanel = BillingPanel;
240
- //# sourceMappingURL=chunk-K5567JM5.js.map
241
- //# sourceMappingURL=chunk-K5567JM5.js.map
240
+ //# sourceMappingURL=chunk-AUCS2KF4.js.map
241
+ //# sourceMappingURL=chunk-AUCS2KF4.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/platform/billing/billing-panel.tsx"],"names":["useTranslations","useFormatter","useAuth","useState","useCallback","useEffect","triggerHaptic","jsx","InlineSpinner","jsxs","SectionCard","StatusBadge","Badge","Button","ListCard","ListCardItem"],"mappings":"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","file":"chunk-K5567JM5.js","sourcesContent":["// =============================================================================\n// @datatechsolutions/windsock/ui — BillingPanel\n// Shows the current organization subscription plus the plan catalogue, with\n// actions for opening the Stripe portal, starting checkout, or cancelling.\n// Backed by `AuthClient.getSubscription / getPlans / createPortalSession /\n// createCheckoutSession / cancelSubscription`.\n// =============================================================================\n\nimport { useEffect, useState, useCallback } from 'react'\nimport { useTranslations, useFormatter } from '@ui/lib/i18n-context'\nimport {\n SectionCard,\n Button,\n Badge,\n StatusBadge,\n InlineSpinner,\n ListCard,\n ListCardItem,\n triggerHaptic,\n} from '@ui/index'\nimport type {\n SubscriptionDetails,\n PlanDefinition,\n SubscriptionTier,\n} from '@datatechsolutions/shared-domain'\nimport { useAuth } from '../../_auth'\n\nexport interface BillingPanelProps {\n /**\n * Which billing interval to prefer when starting checkout. Defaults to\n * `'monthly'`. Surface a toggle in the host app if both matter.\n */\n defaultBillingInterval?: 'monthly' | 'yearly'\n /**\n * Called after the portal/checkout URL is resolved. Defaults to\n * `window.location.assign(url)`. Override to open in a new tab, use a\n * router, etc.\n */\n onRedirect?: (url: string) => void\n}\n\nconst TIER_ORDER: Record<SubscriptionTier, number> = {\n free_trial: 0,\n starter: 1,\n professional: 2,\n enterprise: 3,\n}\n\nexport function BillingPanel({\n defaultBillingInterval = 'monthly',\n onRedirect,\n}: BillingPanelProps) {\n const t = useTranslations('windsock')\n const format = useFormatter()\n const { client } = useAuth()\n\n const [subscription, setSubscription] = useState<SubscriptionDetails | null>(null)\n const [plans, setPlans] = useState<PlanDefinition[]>([])\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n const [busyAction, setBusyAction] = useState<string | null>(null)\n\n const redirect = useCallback((url: string) => {\n if (onRedirect) {\n onRedirect(url)\n } else if (typeof window !== 'undefined') {\n window.location.assign(url)\n }\n }, [onRedirect])\n\n const load = useCallback(async () => {\n setIsLoading(true)\n setError(null)\n try {\n const [sub, availablePlans] = await Promise.all([\n client.getSubscription(),\n client.getPlans(),\n ])\n setSubscription(sub)\n setPlans(\n [...availablePlans]\n .filter((plan: { active: boolean }) => plan.active)\n .sort(\n (a: { tier: SubscriptionTier }, b: { tier: SubscriptionTier }) =>\n (TIER_ORDER[a.tier] ?? 0) - (TIER_ORDER[b.tier] ?? 0),\n ),\n )\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError.message : String(loadError))\n } finally {\n setIsLoading(false)\n }\n }, [client])\n\n useEffect(() => {\n void load()\n }, [load])\n\n const handleOpenPortal = useCallback(async () => {\n setBusyAction('portal')\n triggerHaptic('light')\n try {\n const { url } = await client.createPortalSession()\n redirect(url)\n } catch (portalError) {\n setError(portalError instanceof Error ? portalError.message : String(portalError))\n triggerHaptic('error')\n } finally {\n setBusyAction(null)\n }\n }, [client, redirect])\n\n const handleStartCheckout = useCallback(async (planCode: string) => {\n setBusyAction(`checkout:${planCode}`)\n triggerHaptic('light')\n try {\n const { url } = await client.createCheckoutSession(planCode, defaultBillingInterval)\n redirect(url)\n } catch (checkoutError) {\n setError(checkoutError instanceof Error ? checkoutError.message : String(checkoutError))\n triggerHaptic('error')\n } finally {\n setBusyAction(null)\n }\n }, [client, defaultBillingInterval, redirect])\n\n const handleCancel = useCallback(async () => {\n if (typeof window !== 'undefined') {\n const confirmed = window.confirm(t('billing.cancelConfirm'))\n if (!confirmed) return\n }\n setBusyAction('cancel')\n triggerHaptic('warning')\n try {\n const result = await client.cancelSubscription()\n if (!result.success) {\n throw new Error(result.error ?? 'Subscription cancellation failed')\n }\n triggerHaptic('success')\n await load()\n } catch (cancelError) {\n setError(cancelError instanceof Error ? cancelError.message : String(cancelError))\n triggerHaptic('error')\n } finally {\n setBusyAction(null)\n }\n }, [client, load, t])\n\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center py-12\">\n <InlineSpinner />\n </div>\n )\n }\n\n const currentPlan = subscription?.plan ?? plans.find((plan) => plan.id === subscription?.planId) ?? null\n const currentTier = subscription?.tier ?? currentPlan?.tier ?? null\n\n return (\n <div className=\"space-y-6\">\n {error && (\n <div\n role=\"alert\"\n className=\"rounded-xl border border-red-300/40 bg-red-50/80 px-4 py-3 text-sm text-red-700 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-300\"\n >\n {error}\n </div>\n )}\n\n <SectionCard\n header={{\n title: t('billing.currentPlan.title'),\n subtitle: t('billing.currentPlan.description'),\n }}\n >\n {subscription && currentPlan ? (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <span className=\"text-lg font-semibold text-gray-900 dark:text-white\">\n {currentPlan.name}\n </span>\n <StatusBadge\n status={\n subscription.status === 'active' ? 'success'\n : subscription.status === 'past_due' ? 'pending'\n : 'error'\n }\n label={t(`billing.status.${subscription.status}`)}\n />\n {subscription.cancelAtPeriodEnd && (\n <Badge color=\"amber\">{t('billing.currentPlan.cancelAtPeriodEnd')}</Badge>\n )}\n </div>\n\n <dl className=\"grid grid-cols-1 gap-3 text-sm sm:grid-cols-2\">\n <div>\n <dt className=\"text-gray-500 dark:text-gray-400\">\n {t('billing.currentPlan.price')}\n </dt>\n <dd className=\"font-medium text-gray-900 dark:text-white\">\n {format.number(currentPlan.price, { style: 'currency', currency: currentPlan.currency })}\n {' '}/{' '}\n {t(`billing.interval.${currentPlan.interval}`)}\n </dd>\n </div>\n {subscription.currentPeriodEnd && (\n <div>\n <dt className=\"text-gray-500 dark:text-gray-400\">\n {t('billing.currentPlan.renewsOn')}\n </dt>\n <dd className=\"font-medium text-gray-900 dark:text-white\">\n {format.dateTime(new Date(subscription.currentPeriodEnd), { dateStyle: 'medium' })}\n </dd>\n </div>\n )}\n </dl>\n\n <div className=\"flex flex-wrap gap-2 pt-2\">\n <Button\n size=\"sm\"\n color=\"ios-glass-blue\"\n onClick={handleOpenPortal}\n loading={busyAction === 'portal'}\n disabled={busyAction !== null}\n >\n {t('billing.currentPlan.manageInPortal')}\n </Button>\n {subscription.status === 'active' && !subscription.cancelAtPeriodEnd && (\n <Button\n size=\"sm\"\n color=\"ios-glass-red\"\n onClick={handleCancel}\n loading={busyAction === 'cancel'}\n disabled={busyAction !== null}\n >\n {t('billing.currentPlan.cancel')}\n </Button>\n )}\n </div>\n </div>\n ) : (\n <p className=\"text-sm text-gray-500 dark:text-gray-400\">\n {t('billing.currentPlan.noSubscription')}\n </p>\n )}\n </SectionCard>\n\n <SectionCard\n header={{\n title: t('billing.plans.title'),\n subtitle: t('billing.plans.description'),\n }}\n >\n {plans.length === 0 ? (\n <p className=\"text-sm text-gray-500 dark:text-gray-400\">\n {t('billing.plans.empty')}\n </p>\n ) : (\n <ListCard>\n {plans.map((plan) => {\n const isCurrent = currentPlan?.id === plan.id\n const isDowngrade = currentTier != null\n && (TIER_ORDER[plan.tier] ?? 0) < (TIER_ORDER[currentTier] ?? 0)\n return (\n <ListCardItem\n key={plan.id}\n leading={\n <div className=\"flex h-10 w-10 items-center justify-center rounded-xl bg-gradient-to-br from-violet-500/20 to-blue-500/20 text-violet-600 dark:text-violet-300\">\n <span className=\"text-sm font-bold uppercase\">{plan.tier.charAt(0)}</span>\n </div>\n }\n trailing={\n isCurrent ? (\n <Badge color=\"green\">{t('billing.plans.currentBadge')}</Badge>\n ) : (\n isDowngrade ? (\n <Button\n size=\"sm\"\n plain\n onClick={() => handleStartCheckout(plan.code)}\n loading={busyAction === `checkout:${plan.code}`}\n disabled={busyAction !== null}\n >\n {t('billing.plans.downgradeAction')}\n </Button>\n ) : (\n <Button\n size=\"sm\"\n color=\"ios-glass-blue\"\n onClick={() => handleStartCheckout(plan.code)}\n loading={busyAction === `checkout:${plan.code}`}\n disabled={busyAction !== null}\n >\n {t('billing.plans.selectAction')}\n </Button>\n )\n )\n }\n >\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex items-center gap-2\">\n <p className=\"text-sm font-medium text-gray-900 dark:text-white\">\n {plan.name}\n </p>\n <span className=\"text-xs text-gray-500 dark:text-gray-400\">\n {format.number(plan.price, { style: 'currency', currency: plan.currency })}\n {' '}/{' '}\n {t(`billing.interval.${plan.interval}`)}\n </span>\n </div>\n {plan.description && (\n <p className=\"text-xs text-gray-500 dark:text-gray-400\">\n {plan.description}\n </p>\n )}\n </div>\n </ListCardItem>\n )\n })}\n </ListCard>\n )}\n </SectionCard>\n </div>\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/platform/billing/billing-panel.tsx"],"names":["useTranslations","useFormatter","useAuth","useState","useCallback","useEffect","triggerHaptic","jsx","InlineSpinner","jsxs","SectionCard","StatusBadge","Badge","Button","ListCard","ListCardItem"],"mappings":";;;;;;;;;AAyCA,IAAM,UAAA,GAA+C;AAAA,EACnD,UAAA,EAAY,CAAA;AAAA,EACZ,OAAA,EAAS,CAAA;AAAA,EACT,YAAA,EAAc,CAAA;AAAA,EACd,UAAA,EAAY;AACd,CAAA;AAEO,SAAS,YAAA,CAAa;AAAA,EAC3B,sBAAA,GAAyB,SAAA;AAAA,EACzB;AACF,CAAA,EAAsB;AACpB,EAAA,MAAM,CAAA,GAAIA,iCAAgB,UAAU,CAAA;AACpC,EAAA,MAAM,SAASC,6BAAA,EAAa;AAC5B,EAAA,MAAM,EAAE,MAAA,EAAO,GAAIC,wBAAA,EAAQ;AAE3B,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIC,eAAqC,IAAI,CAAA;AACjF,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,cAAA,CAA2B,EAAE,CAAA;AACvD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,eAAS,IAAI,CAAA;AAC/C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAwB,IAAI,CAAA;AACtD,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,eAAwB,IAAI,CAAA;AAEhE,EAAA,MAAM,QAAA,GAAWC,iBAAA,CAAY,CAAC,GAAA,KAAgB;AAC5C,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,UAAA,CAAW,GAAG,CAAA;AAAA,IAChB,CAAA,MAAA,IAAW,OAAO,MAAA,KAAW,WAAA,EAAa;AACxC,MAAA,MAAA,CAAO,QAAA,CAAS,OAAO,GAAG,CAAA;AAAA,IAC5B;AAAA,EACF,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAEf,EAAA,MAAM,IAAA,GAAOA,kBAAY,YAAY;AACnC,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,IAAI;AACF,MAAA,MAAM,CAAC,GAAA,EAAK,cAAc,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA,QAC9C,OAAO,eAAA,EAAgB;AAAA,QACvB,OAAO,QAAA;AAAS,OACjB,CAAA;AACD,MAAA,eAAA,CAAgB,GAAG,CAAA;AACnB,MAAA,QAAA;AAAA,QACE,CAAC,GAAG,cAAc,CAAA,CACf,OAAO,CAAC,IAAA,KAA8B,IAAA,CAAK,MAAM,CAAA,CACjD,IAAA;AAAA,UACC,CAAC,CAAA,EAA+B,CAAA,KAAA,CAC7B,UAAA,CAAW,CAAA,CAAE,IAAI,CAAA,IAAK,CAAA,KAAM,UAAA,CAAW,CAAA,CAAE,IAAI,CAAA,IAAK,CAAA;AAAA;AACvD,OACJ;AAAA,IACF,SAAS,SAAA,EAAW;AAClB,MAAA,QAAA,CAAS,qBAAqB,KAAA,GAAQ,SAAA,CAAU,OAAA,GAAU,MAAA,CAAO,SAAS,CAAC,CAAA;AAAA,IAC7E,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,KAAK,IAAA,EAAK;AAAA,EACZ,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,MAAM,gBAAA,GAAmBD,kBAAY,YAAY;AAC/C,IAAA,aAAA,CAAc,QAAQ,CAAA;AACtB,IAAAE,8BAAA,CAAc,OAAO,CAAA;AACrB,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,OAAO,mBAAA,EAAoB;AACjD,MAAA,QAAA,CAAS,GAAG,CAAA;AAAA,IACd,SAAS,WAAA,EAAa;AACpB,MAAA,QAAA,CAAS,uBAAuB,KAAA,GAAQ,WAAA,CAAY,OAAA,GAAU,MAAA,CAAO,WAAW,CAAC,CAAA;AACjF,MAAAA,8BAAA,CAAc,OAAO,CAAA;AAAA,IACvB,CAAA,SAAE;AACA,MAAA,aAAA,CAAc,IAAI,CAAA;AAAA,IACpB;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,QAAQ,CAAC,CAAA;AAErB,EAAA,MAAM,mBAAA,GAAsBF,iBAAA,CAAY,OAAO,QAAA,KAAqB;AAClE,IAAA,aAAA,CAAc,CAAA,SAAA,EAAY,QAAQ,CAAA,CAAE,CAAA;AACpC,IAAAE,8BAAA,CAAc,OAAO,CAAA;AACrB,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,qBAAA,CAAsB,UAAU,sBAAsB,CAAA;AACnF,MAAA,QAAA,CAAS,GAAG,CAAA;AAAA,IACd,SAAS,aAAA,EAAe;AACtB,MAAA,QAAA,CAAS,yBAAyB,KAAA,GAAQ,aAAA,CAAc,OAAA,GAAU,MAAA,CAAO,aAAa,CAAC,CAAA;AACvF,MAAAA,8BAAA,CAAc,OAAO,CAAA;AAAA,IACvB,CAAA,SAAE;AACA,MAAA,aAAA,CAAc,IAAI,CAAA;AAAA,IACpB;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,sBAAA,EAAwB,QAAQ,CAAC,CAAA;AAE7C,EAAA,MAAM,YAAA,GAAeF,kBAAY,YAAY;AAC3C,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,MAAA,MAAM,SAAA,GAAY,MAAA,CAAO,OAAA,CAAQ,CAAA,CAAE,uBAAuB,CAAC,CAAA;AAC3D,MAAA,IAAI,CAAC,SAAA,EAAW;AAAA,IAClB;AACA,IAAA,aAAA,CAAc,QAAQ,CAAA;AACtB,IAAAE,8BAAA,CAAc,SAAS,CAAA;AACvB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,kBAAA,EAAmB;AAC/C,MAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,QAAA,MAAM,IAAI,KAAA,CAAM,MAAA,CAAO,KAAA,IAAS,kCAAkC,CAAA;AAAA,MACpE;AACA,MAAAA,8BAAA,CAAc,SAAS,CAAA;AACvB,MAAA,MAAM,IAAA,EAAK;AAAA,IACb,SAAS,WAAA,EAAa;AACpB,MAAA,QAAA,CAAS,uBAAuB,KAAA,GAAQ,WAAA,CAAY,OAAA,GAAU,MAAA,CAAO,WAAW,CAAC,CAAA;AACjF,MAAAA,8BAAA,CAAc,OAAO,CAAA;AAAA,IACvB,CAAA,SAAE;AACA,MAAA,aAAA,CAAc,IAAI,CAAA;AAAA,IACpB;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,IAAA,EAAM,CAAC,CAAC,CAAA;AAEpB,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,sCACG,KAAA,EAAA,EAAI,SAAA,EAAU,wCAAA,EACb,QAAA,kBAAAC,cAAA,CAACC,kCAAc,CAAA,EACjB,CAAA;AAAA,EAEJ;AAEA,EAAA,MAAM,WAAA,GAAc,YAAA,EAAc,IAAA,IAAQ,KAAA,CAAM,IAAA,CAAK,CAAC,IAAA,KAAS,IAAA,CAAK,EAAA,KAAO,YAAA,EAAc,MAAM,CAAA,IAAK,IAAA;AACpG,EAAA,MAAM,WAAA,GAAc,YAAA,EAAc,IAAA,IAAQ,WAAA,EAAa,IAAA,IAAQ,IAAA;AAE/D,EAAA,uBACEC,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACZ,QAAA,EAAA;AAAA,IAAA,KAAA,oBACCF,cAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,OAAA;AAAA,QACL,SAAA,EAAU,6IAAA;AAAA,QAET,QAAA,EAAA;AAAA;AAAA,KACH;AAAA,oBAGFA,cAAA;AAAA,MAACG,4BAAA;AAAA,MAAA;AAAA,QACC,MAAA,EAAQ;AAAA,UACN,KAAA,EAAO,EAAE,2BAA2B,CAAA;AAAA,UACpC,QAAA,EAAU,EAAE,iCAAiC;AAAA,SAC/C;AAAA,QAEC,QAAA,EAAA,YAAA,IAAgB,WAAA,mBACfD,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,WAAA,EACb,QAAA,EAAA;AAAA,0BAAAA,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,mCAAA,EACb,QAAA,EAAA;AAAA,4BAAAF,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,sDAAA,EACb,QAAA,EAAA,WAAA,CAAY,IAAA,EACf,CAAA;AAAA,4BACAA,cAAA;AAAA,cAACI,4BAAA;AAAA,cAAA;AAAA,gBACC,MAAA,EACE,aAAa,MAAA,KAAW,QAAA,GAAW,YACjC,YAAA,CAAa,MAAA,KAAW,aAAa,SAAA,GACrC,OAAA;AAAA,gBAEJ,KAAA,EAAO,CAAA,CAAE,CAAA,eAAA,EAAkB,YAAA,CAAa,MAAM,CAAA,CAAE;AAAA;AAAA,aAClD;AAAA,YACC,YAAA,CAAa,qCACZJ,cAAA,CAACK,sBAAA,EAAA,EAAM,OAAM,OAAA,EAAS,QAAA,EAAA,CAAA,CAAE,uCAAuC,CAAA,EAAE;AAAA,WAAA,EAErE,CAAA;AAAA,0BAEAH,eAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,+CAAA,EACZ,QAAA,EAAA;AAAA,4BAAAA,eAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,8BAAAF,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,oCAAA,EACX,QAAA,EAAA,CAAA,CAAE,2BAA2B,CAAA,EAChC,CAAA;AAAA,8BACAE,eAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,4CAAA,EACX,QAAA,EAAA;AAAA,gBAAA,MAAA,CAAO,MAAA,CAAO,YAAY,KAAA,EAAO,EAAE,OAAO,UAAA,EAAY,QAAA,EAAU,WAAA,CAAY,QAAA,EAAU,CAAA;AAAA,gBACtF,GAAA;AAAA,gBAAI,GAAA;AAAA,gBAAE,GAAA;AAAA,gBACN,CAAA,CAAE,CAAA,iBAAA,EAAoB,WAAA,CAAY,QAAQ,CAAA,CAAE;AAAA,eAAA,EAC/C;AAAA,aAAA,EACF,CAAA;AAAA,YACC,YAAA,CAAa,gBAAA,oBACZA,eAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,8BAAAF,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,oCAAA,EACX,QAAA,EAAA,CAAA,CAAE,8BAA8B,CAAA,EACnC,CAAA;AAAA,8BACAA,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,4CAAA,EACX,iBAAO,QAAA,CAAS,IAAI,IAAA,CAAK,YAAA,CAAa,gBAAgB,CAAA,EAAG,EAAE,SAAA,EAAW,QAAA,EAAU,CAAA,EACnF;AAAA,aAAA,EACF;AAAA,WAAA,EAEJ,CAAA;AAAA,0BAEAE,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EACb,QAAA,EAAA;AAAA,4BAAAF,cAAA;AAAA,cAACM,uBAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,IAAA;AAAA,gBACL,KAAA,EAAM,gBAAA;AAAA,gBACN,OAAA,EAAS,gBAAA;AAAA,gBACT,SAAS,UAAA,KAAe,QAAA;AAAA,gBACxB,UAAU,UAAA,KAAe,IAAA;AAAA,gBAExB,YAAE,oCAAoC;AAAA;AAAA,aACzC;AAAA,YACC,YAAA,CAAa,MAAA,KAAW,QAAA,IAAY,CAAC,aAAa,iBAAA,oBACjDN,cAAA;AAAA,cAACM,uBAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,IAAA;AAAA,gBACL,KAAA,EAAM,eAAA;AAAA,gBACN,OAAA,EAAS,YAAA;AAAA,gBACT,SAAS,UAAA,KAAe,QAAA;AAAA,gBACxB,UAAU,UAAA,KAAe,IAAA;AAAA,gBAExB,YAAE,4BAA4B;AAAA;AAAA;AACjC,WAAA,EAEJ;AAAA,SAAA,EACF,oBAEAN,cAAA,CAAC,GAAA,EAAA,EAAE,WAAU,4CAAA,EACV,QAAA,EAAA,CAAA,CAAE,oCAAoC,CAAA,EACzC;AAAA;AAAA,KAEJ;AAAA,oBAEAA,cAAA;AAAA,MAACG,4BAAA;AAAA,MAAA;AAAA,QACC,MAAA,EAAQ;AAAA,UACN,KAAA,EAAO,EAAE,qBAAqB,CAAA;AAAA,UAC9B,QAAA,EAAU,EAAE,2BAA2B;AAAA,SACzC;AAAA,QAEC,gBAAM,MAAA,KAAW,CAAA,mBAChBH,cAAA,CAAC,GAAA,EAAA,EAAE,WAAU,4CAAA,EACV,QAAA,EAAA,CAAA,CAAE,qBAAqB,CAAA,EAC1B,oBAEAA,cAAA,CAACO,yBAAA,EAAA,EACE,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS;AACnB,UAAA,MAAM,SAAA,GAAY,WAAA,EAAa,EAAA,KAAO,IAAA,CAAK,EAAA;AAC3C,UAAA,MAAM,WAAA,GAAc,WAAA,IAAe,IAAA,IAAA,CAC7B,UAAA,CAAW,IAAA,CAAK,IAAI,CAAA,IAAK,CAAA,KAAM,UAAA,CAAW,WAAW,CAAA,IAAK,CAAA,CAAA;AAChE,UAAA,uBACEP,cAAA;AAAA,YAACQ,6BAAA;AAAA,YAAA;AAAA,cAEC,OAAA,kBACER,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kJACb,QAAA,kBAAAA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,6BAAA,EAA+B,QAAA,EAAA,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,CAAC,GAAE,CAAA,EACrE,CAAA;AAAA,cAEF,QAAA,EACE,SAAA,mBACEA,cAAA,CAACK,sBAAA,EAAA,EAAM,KAAA,EAAM,SAAS,QAAA,EAAA,CAAA,CAAE,4BAA4B,CAAA,EAAE,CAAA,GAEtD,WAAA,mBACEL,cAAA;AAAA,gBAACM,uBAAA;AAAA,gBAAA;AAAA,kBACC,IAAA,EAAK,IAAA;AAAA,kBACL,KAAA,EAAK,IAAA;AAAA,kBACL,OAAA,EAAS,MAAM,mBAAA,CAAoB,IAAA,CAAK,IAAI,CAAA;AAAA,kBAC5C,OAAA,EAAS,UAAA,KAAe,CAAA,SAAA,EAAY,IAAA,CAAK,IAAI,CAAA,CAAA;AAAA,kBAC7C,UAAU,UAAA,KAAe,IAAA;AAAA,kBAExB,YAAE,+BAA+B;AAAA;AAAA,eACpC,mBAEAN,cAAA;AAAA,gBAACM,uBAAA;AAAA,gBAAA;AAAA,kBACC,IAAA,EAAK,IAAA;AAAA,kBACL,KAAA,EAAM,gBAAA;AAAA,kBACN,OAAA,EAAS,MAAM,mBAAA,CAAoB,IAAA,CAAK,IAAI,CAAA;AAAA,kBAC5C,OAAA,EAAS,UAAA,KAAe,CAAA,SAAA,EAAY,IAAA,CAAK,IAAI,CAAA,CAAA;AAAA,kBAC7C,UAAU,UAAA,KAAe,IAAA;AAAA,kBAExB,YAAE,4BAA4B;AAAA;AAAA,eACjC;AAAA,cAKN,QAAA,kBAAAJ,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACb,QAAA,EAAA;AAAA,gCAAAA,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yBAAA,EACb,QAAA,EAAA;AAAA,kCAAAF,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,oDAAA,EACV,QAAA,EAAA,IAAA,CAAK,IAAA,EACR,CAAA;AAAA,kCACAE,eAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4CAAA,EACb,QAAA,EAAA;AAAA,oBAAA,MAAA,CAAO,MAAA,CAAO,KAAK,KAAA,EAAO,EAAE,OAAO,UAAA,EAAY,QAAA,EAAU,IAAA,CAAK,QAAA,EAAU,CAAA;AAAA,oBACxE,GAAA;AAAA,oBAAI,GAAA;AAAA,oBAAE,GAAA;AAAA,oBACN,CAAA,CAAE,CAAA,iBAAA,EAAoB,IAAA,CAAK,QAAQ,CAAA,CAAE;AAAA,mBAAA,EACxC;AAAA,iBAAA,EACF,CAAA;AAAA,gBACC,KAAK,WAAA,oBACJF,cAAA,CAAC,OAAE,SAAA,EAAU,4CAAA,EACV,eAAK,WAAA,EACR;AAAA,eAAA,EAEJ;AAAA,aAAA;AAAA,YAlDK,IAAA,CAAK;AAAA,WAmDZ;AAAA,QAEJ,CAAC,CAAA,EACH;AAAA;AAAA;AAEJ,GAAA,EACF,CAAA;AAEJ","file":"chunk-AUCS2KF4.js","sourcesContent":["// =============================================================================\n// @datatechsolutions/windsock/ui — BillingPanel\n// Shows the current organization subscription plus the plan catalogue, with\n// actions for opening the Stripe portal, starting checkout, or cancelling.\n// Backed by `AuthClient.getSubscription / getPlans / createPortalSession /\n// createCheckoutSession / cancelSubscription`.\n// =============================================================================\n\nimport { useEffect, useState, useCallback } from 'react'\nimport { useTranslations, useFormatter } from '@ui/lib/i18n-context'\nimport {\n SectionCard,\n Button,\n Badge,\n StatusBadge,\n InlineSpinner,\n ListCard,\n ListCardItem,\n triggerHaptic,\n} from '@ui/index'\nimport type {\n SubscriptionDetails,\n PlanDefinition,\n SubscriptionTier,\n} from '@datatechsolutions/shared-domain'\nimport { useAuth } from '../../_auth'\n\nexport interface BillingPanelProps {\n /**\n * Which billing interval to prefer when starting checkout. Defaults to\n * `'monthly'`. Surface a toggle in the host app if both matter.\n */\n defaultBillingInterval?: 'monthly' | 'yearly'\n /**\n * Called after the portal/checkout URL is resolved. Defaults to\n * `window.location.assign(url)`. Override to open in a new tab, use a\n * router, etc.\n */\n onRedirect?: (url: string) => void\n}\n\nconst TIER_ORDER: Record<SubscriptionTier, number> = {\n free_trial: 0,\n starter: 1,\n professional: 2,\n enterprise: 3,\n}\n\nexport function BillingPanel({\n defaultBillingInterval = 'monthly',\n onRedirect,\n}: BillingPanelProps) {\n const t = useTranslations('windsock')\n const format = useFormatter()\n const { client } = useAuth()\n\n const [subscription, setSubscription] = useState<SubscriptionDetails | null>(null)\n const [plans, setPlans] = useState<PlanDefinition[]>([])\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n const [busyAction, setBusyAction] = useState<string | null>(null)\n\n const redirect = useCallback((url: string) => {\n if (onRedirect) {\n onRedirect(url)\n } else if (typeof window !== 'undefined') {\n window.location.assign(url)\n }\n }, [onRedirect])\n\n const load = useCallback(async () => {\n setIsLoading(true)\n setError(null)\n try {\n const [sub, availablePlans] = await Promise.all([\n client.getSubscription(),\n client.getPlans(),\n ])\n setSubscription(sub)\n setPlans(\n [...availablePlans]\n .filter((plan: { active: boolean }) => plan.active)\n .sort(\n (a: { tier: SubscriptionTier }, b: { tier: SubscriptionTier }) =>\n (TIER_ORDER[a.tier] ?? 0) - (TIER_ORDER[b.tier] ?? 0),\n ),\n )\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError.message : String(loadError))\n } finally {\n setIsLoading(false)\n }\n }, [client])\n\n useEffect(() => {\n void load()\n }, [load])\n\n const handleOpenPortal = useCallback(async () => {\n setBusyAction('portal')\n triggerHaptic('light')\n try {\n const { url } = await client.createPortalSession()\n redirect(url)\n } catch (portalError) {\n setError(portalError instanceof Error ? portalError.message : String(portalError))\n triggerHaptic('error')\n } finally {\n setBusyAction(null)\n }\n }, [client, redirect])\n\n const handleStartCheckout = useCallback(async (planCode: string) => {\n setBusyAction(`checkout:${planCode}`)\n triggerHaptic('light')\n try {\n const { url } = await client.createCheckoutSession(planCode, defaultBillingInterval)\n redirect(url)\n } catch (checkoutError) {\n setError(checkoutError instanceof Error ? checkoutError.message : String(checkoutError))\n triggerHaptic('error')\n } finally {\n setBusyAction(null)\n }\n }, [client, defaultBillingInterval, redirect])\n\n const handleCancel = useCallback(async () => {\n if (typeof window !== 'undefined') {\n const confirmed = window.confirm(t('billing.cancelConfirm'))\n if (!confirmed) return\n }\n setBusyAction('cancel')\n triggerHaptic('warning')\n try {\n const result = await client.cancelSubscription()\n if (!result.success) {\n throw new Error(result.error ?? 'Subscription cancellation failed')\n }\n triggerHaptic('success')\n await load()\n } catch (cancelError) {\n setError(cancelError instanceof Error ? cancelError.message : String(cancelError))\n triggerHaptic('error')\n } finally {\n setBusyAction(null)\n }\n }, [client, load, t])\n\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center py-12\">\n <InlineSpinner />\n </div>\n )\n }\n\n const currentPlan = subscription?.plan ?? plans.find((plan) => plan.id === subscription?.planId) ?? null\n const currentTier = subscription?.tier ?? currentPlan?.tier ?? null\n\n return (\n <div className=\"space-y-6\">\n {error && (\n <div\n role=\"alert\"\n className=\"rounded-xl border border-red-300/40 bg-red-50/80 px-4 py-3 text-sm text-red-700 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-300\"\n >\n {error}\n </div>\n )}\n\n <SectionCard\n header={{\n title: t('billing.currentPlan.title'),\n subtitle: t('billing.currentPlan.description'),\n }}\n >\n {subscription && currentPlan ? (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <span className=\"text-lg font-semibold text-slate-900 dark:text-white\">\n {currentPlan.name}\n </span>\n <StatusBadge\n status={\n subscription.status === 'active' ? 'success'\n : subscription.status === 'past_due' ? 'pending'\n : 'error'\n }\n label={t(`billing.status.${subscription.status}`)}\n />\n {subscription.cancelAtPeriodEnd && (\n <Badge color=\"amber\">{t('billing.currentPlan.cancelAtPeriodEnd')}</Badge>\n )}\n </div>\n\n <dl className=\"grid grid-cols-1 gap-3 text-sm sm:grid-cols-2\">\n <div>\n <dt className=\"text-slate-500 dark:text-slate-400\">\n {t('billing.currentPlan.price')}\n </dt>\n <dd className=\"font-medium text-slate-900 dark:text-white\">\n {format.number(currentPlan.price, { style: 'currency', currency: currentPlan.currency })}\n {' '}/{' '}\n {t(`billing.interval.${currentPlan.interval}`)}\n </dd>\n </div>\n {subscription.currentPeriodEnd && (\n <div>\n <dt className=\"text-slate-500 dark:text-slate-400\">\n {t('billing.currentPlan.renewsOn')}\n </dt>\n <dd className=\"font-medium text-slate-900 dark:text-white\">\n {format.dateTime(new Date(subscription.currentPeriodEnd), { dateStyle: 'medium' })}\n </dd>\n </div>\n )}\n </dl>\n\n <div className=\"flex flex-wrap gap-2 pt-2\">\n <Button\n size=\"sm\"\n color=\"ios-glass-blue\"\n onClick={handleOpenPortal}\n loading={busyAction === 'portal'}\n disabled={busyAction !== null}\n >\n {t('billing.currentPlan.manageInPortal')}\n </Button>\n {subscription.status === 'active' && !subscription.cancelAtPeriodEnd && (\n <Button\n size=\"sm\"\n color=\"ios-glass-red\"\n onClick={handleCancel}\n loading={busyAction === 'cancel'}\n disabled={busyAction !== null}\n >\n {t('billing.currentPlan.cancel')}\n </Button>\n )}\n </div>\n </div>\n ) : (\n <p className=\"text-sm text-slate-500 dark:text-slate-400\">\n {t('billing.currentPlan.noSubscription')}\n </p>\n )}\n </SectionCard>\n\n <SectionCard\n header={{\n title: t('billing.plans.title'),\n subtitle: t('billing.plans.description'),\n }}\n >\n {plans.length === 0 ? (\n <p className=\"text-sm text-slate-500 dark:text-slate-400\">\n {t('billing.plans.empty')}\n </p>\n ) : (\n <ListCard>\n {plans.map((plan) => {\n const isCurrent = currentPlan?.id === plan.id\n const isDowngrade = currentTier != null\n && (TIER_ORDER[plan.tier] ?? 0) < (TIER_ORDER[currentTier] ?? 0)\n return (\n <ListCardItem\n key={plan.id}\n leading={\n <div className=\"flex h-10 w-10 items-center justify-center rounded-xl bg-gradient-to-br from-violet-500/20 to-blue-500/20 text-violet-600 dark:text-violet-300\">\n <span className=\"text-sm font-bold uppercase\">{plan.tier.charAt(0)}</span>\n </div>\n }\n trailing={\n isCurrent ? (\n <Badge color=\"green\">{t('billing.plans.currentBadge')}</Badge>\n ) : (\n isDowngrade ? (\n <Button\n size=\"sm\"\n plain\n onClick={() => handleStartCheckout(plan.code)}\n loading={busyAction === `checkout:${plan.code}`}\n disabled={busyAction !== null}\n >\n {t('billing.plans.downgradeAction')}\n </Button>\n ) : (\n <Button\n size=\"sm\"\n color=\"ios-glass-blue\"\n onClick={() => handleStartCheckout(plan.code)}\n loading={busyAction === `checkout:${plan.code}`}\n disabled={busyAction !== null}\n >\n {t('billing.plans.selectAction')}\n </Button>\n )\n )\n }\n >\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex items-center gap-2\">\n <p className=\"text-sm font-medium text-slate-900 dark:text-white\">\n {plan.name}\n </p>\n <span className=\"text-xs text-slate-500 dark:text-slate-400\">\n {format.number(plan.price, { style: 'currency', currency: plan.currency })}\n {' '}/{' '}\n {t(`billing.interval.${plan.interval}`)}\n </span>\n </div>\n {plan.description && (\n <p className=\"text-xs text-slate-500 dark:text-slate-400\">\n {plan.description}\n </p>\n )}\n </div>\n </ListCardItem>\n )\n })}\n </ListCard>\n )}\n </SectionCard>\n </div>\n )\n}\n"]}