@tangle-network/sandbox-ui 0.113.6 → 0.114.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 (106) hide show
  1. package/dist/WorkflowGraph-B-NsdYz_.js +1961 -0
  2. package/dist/assets.d.ts +214 -206
  3. package/dist/assets.js +1057 -908
  4. package/dist/auth-CWe17Hly.js +37 -0
  5. package/dist/auth.d.ts +2 -30
  6. package/dist/auth.js +2 -15
  7. package/dist/chat-BOvFAe6p.js +903 -0
  8. package/dist/chat.d.ts +2 -230
  9. package/dist/chat.js +2 -34
  10. package/dist/connectors.d.ts +52 -49
  11. package/dist/connectors.js +595 -643
  12. package/dist/dashboard-CZ3VgNPR.js +4969 -0
  13. package/dist/dashboard.d.ts +4 -1297
  14. package/dist/dashboard.js +4 -152
  15. package/dist/editor.d.ts +2 -1
  16. package/dist/editor.js +2 -31
  17. package/dist/files.d.ts +2 -6
  18. package/dist/files.js +2 -33
  19. package/dist/globals.css +63 -3
  20. package/dist/hooks.d.ts +146 -148
  21. package/dist/hooks.js +222 -55
  22. package/dist/index-CKRaj1pM.d.ts +776 -0
  23. package/dist/index-CXX5IpH2.d.ts +2 -0
  24. package/dist/index-DPePq7c8.d.ts +1340 -0
  25. package/dist/index-DiyLLZuJ.d.ts +230 -0
  26. package/dist/index-DvmZLMT1.d.ts +30 -0
  27. package/dist/index-I8ZLVtHd.d.ts +330 -0
  28. package/dist/index-PRM636Ex.d.ts +86 -0
  29. package/dist/index.d.ts +21 -33
  30. package/dist/index.js +21 -701
  31. package/dist/info-panel-C9cqDzOL.js +594 -0
  32. package/dist/integrations.d.ts +133 -139
  33. package/dist/integrations.js +491 -673
  34. package/dist/markdown.d.ts +2 -1
  35. package/dist/markdown.js +2 -13
  36. package/dist/model-I-NIxeM-.js +1250 -0
  37. package/dist/model-brand-B9A4H9pJ.d.ts +98 -0
  38. package/dist/model-brand-hMyDTUqB.js +624 -0
  39. package/dist/motion-DkyBRJb9.js +37 -0
  40. package/dist/openui.d.ts +2 -1
  41. package/dist/openui.js +2 -7
  42. package/dist/pages.d.ts +307 -300
  43. package/dist/pages.js +4404 -4181
  44. package/dist/primitives-Dh1vG6J3.js +113 -0
  45. package/dist/primitives.d.ts +2 -74
  46. package/dist/primitives.js +2 -204
  47. package/dist/provider-logo-DjqmConF.js +311 -0
  48. package/dist/run.d.ts +2 -1
  49. package/dist/run.js +2 -23
  50. package/dist/sdk-hooks.d.ts +3 -4
  51. package/dist/sdk-hooks.js +3 -31
  52. package/dist/sidecar-DgH_vQ6m.d.ts +9 -0
  53. package/dist/stores.d.ts +14 -15
  54. package/dist/stores.js +13 -81
  55. package/dist/styles.css +63 -3
  56. package/dist/template-card-L-4gmjx2.d.ts +90 -0
  57. package/dist/terminal-CN9ZgHRt.js +197 -0
  58. package/dist/terminal.d.ts +60 -60
  59. package/dist/terminal.js +2 -10
  60. package/dist/tokens.css +51 -0
  61. package/dist/types.d.ts +4 -11
  62. package/dist/types.js +0 -1
  63. package/dist/use-pty-session-C8cE0adT.js +669 -0
  64. package/dist/use-sidecar-auth-CCTJcrq7.d.ts +145 -0
  65. package/dist/use-sidecar-auth-DkdcufOz.js +742 -0
  66. package/dist/utils-DzWbktWG.js +2 -0
  67. package/dist/utils.d.ts +2 -1
  68. package/dist/utils.js +2 -37
  69. package/dist/workbench-BCaCKl-J.js +8347 -0
  70. package/dist/workbench.d.ts +2 -310
  71. package/dist/workbench.js +2 -44
  72. package/dist/workflows.d.ts +341 -339
  73. package/dist/workflows.js +74 -109
  74. package/dist/workspace-B6AtI6ld.js +2510 -0
  75. package/dist/workspace.d.ts +2 -761
  76. package/dist/workspace.js +2 -51
  77. package/package.json +46 -40
  78. package/dist/WorkflowGraph-2QOORYIR.js +0 -1722
  79. package/dist/chunk-2BUPSB7O.js +0 -0
  80. package/dist/chunk-3KBNPQQF.js +0 -2697
  81. package/dist/chunk-3LIXVEEE.js +0 -279
  82. package/dist/chunk-72UF2H5H.js +0 -707
  83. package/dist/chunk-AI25G5MX.js +0 -944
  84. package/dist/chunk-ANSC5AFC.js +0 -314
  85. package/dist/chunk-AZ3AWMTM.js +0 -8
  86. package/dist/chunk-BGVEHENC.js +0 -10
  87. package/dist/chunk-CZ7CSFO4.js +0 -39
  88. package/dist/chunk-DYXXYGS4.js +0 -4700
  89. package/dist/chunk-EI44GEQ5.js +0 -6
  90. package/dist/chunk-IACRDXER.js +0 -219
  91. package/dist/chunk-IOB2PW5Z.js +0 -55
  92. package/dist/chunk-M4K7ZGR2.js +0 -24
  93. package/dist/chunk-MYZAW4RX.js +0 -665
  94. package/dist/chunk-OMUIPJQZ.js +0 -555
  95. package/dist/chunk-RQZRXKMR.js +0 -398
  96. package/dist/chunk-SOKKTB7W.js +0 -230
  97. package/dist/chunk-TADGS4Q7.js +0 -1010
  98. package/dist/chunk-UCQNOUN3.js +0 -7964
  99. package/dist/chunk-ULPLRBMF.js +0 -34
  100. package/dist/chunk-WID73FPH.js +0 -89
  101. package/dist/chunk-X3YXP7FG.js +0 -38
  102. package/dist/logo-DiAjq759.d.ts +0 -15
  103. package/dist/model-brand-BNnaUKKZ.d.ts +0 -99
  104. package/dist/ports-list-CDIvTNnX.d.ts +0 -17
  105. package/dist/sdk-hooks-Djkjq4cp.d.ts +0 -145
  106. package/dist/template-card-Bn-Bw5xC.d.ts +0 -87
@@ -1,555 +0,0 @@
1
- import {
2
- cn
3
- } from "./chunk-EI44GEQ5.js";
4
-
5
- // src/dashboard/billing-dashboard.tsx
6
- import { Button } from "@tangle-network/ui/primitives";
7
- import { Badge } from "@tangle-network/ui/primitives";
8
- import {
9
- Card,
10
- CardContent,
11
- CardDescription,
12
- CardHeader,
13
- CardTitle
14
- } from "@tangle-network/ui/primitives";
15
- import { Progress } from "@tangle-network/ui/primitives";
16
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
17
- var variantColors = {
18
- sandbox: {
19
- accent: "text-[var(--accent-text)]",
20
- accentBg: "bg-[var(--accent-surface-soft)]",
21
- border: "border-[var(--border-accent)]",
22
- progress: "bg-[image:var(--accent-gradient-strong)]"
23
- }
24
- };
25
- function formatCredits(value) {
26
- if (value >= 1e6) {
27
- return `${(value / 1e6).toFixed(1)}M`;
28
- }
29
- if (value >= 1e3) {
30
- return `${(value / 1e3).toFixed(1)}K`;
31
- }
32
- return value.toLocaleString();
33
- }
34
- function formatDate(dateStr) {
35
- const date = new Date(dateStr);
36
- return date.toLocaleDateString("en-US", {
37
- month: "long",
38
- day: "numeric",
39
- year: "numeric"
40
- });
41
- }
42
- function getStatusBadgeVariant(status) {
43
- switch (status.toLowerCase()) {
44
- case "active":
45
- return "success";
46
- case "trialing":
47
- case "past_due":
48
- return "warning";
49
- case "canceled":
50
- case "unpaid":
51
- return "error";
52
- default:
53
- return "secondary";
54
- }
55
- }
56
- function CreditCardIcon({ className }) {
57
- return /* @__PURE__ */ jsxs(
58
- "svg",
59
- {
60
- xmlns: "http://www.w3.org/2000/svg",
61
- viewBox: "0 0 24 24",
62
- fill: "none",
63
- stroke: "currentColor",
64
- strokeWidth: "2",
65
- strokeLinecap: "round",
66
- strokeLinejoin: "round",
67
- className: cn("h-5 w-5", className),
68
- children: [
69
- /* @__PURE__ */ jsx("title", { children: "Credit card icon" }),
70
- /* @__PURE__ */ jsx("rect", { width: "20", height: "14", x: "2", y: "5", rx: "2" }),
71
- /* @__PURE__ */ jsx("line", { x1: "2", x2: "22", y1: "10", y2: "10" })
72
- ]
73
- }
74
- );
75
- }
76
- function CoinsIcon({ className }) {
77
- return /* @__PURE__ */ jsxs(
78
- "svg",
79
- {
80
- xmlns: "http://www.w3.org/2000/svg",
81
- viewBox: "0 0 24 24",
82
- fill: "none",
83
- stroke: "currentColor",
84
- strokeWidth: "2",
85
- strokeLinecap: "round",
86
- strokeLinejoin: "round",
87
- className: cn("h-5 w-5", className),
88
- children: [
89
- /* @__PURE__ */ jsx("title", { children: "Coins icon" }),
90
- /* @__PURE__ */ jsx("circle", { cx: "8", cy: "8", r: "6" }),
91
- /* @__PURE__ */ jsx("path", { d: "M18.09 10.37A6 6 0 1 1 10.34 18" }),
92
- /* @__PURE__ */ jsx("path", { d: "M7 6h1v4" }),
93
- /* @__PURE__ */ jsx("path", { d: "m16.71 13.88.7.71-2.82 2.82" })
94
- ]
95
- }
96
- );
97
- }
98
- function ChartIcon({ className }) {
99
- return /* @__PURE__ */ jsxs(
100
- "svg",
101
- {
102
- xmlns: "http://www.w3.org/2000/svg",
103
- viewBox: "0 0 24 24",
104
- fill: "none",
105
- stroke: "currentColor",
106
- strokeWidth: "2",
107
- strokeLinecap: "round",
108
- strokeLinejoin: "round",
109
- className: cn("h-5 w-5", className),
110
- children: [
111
- /* @__PURE__ */ jsx("title", { children: "Chart icon" }),
112
- /* @__PURE__ */ jsx("path", { d: "M3 3v18h18" }),
113
- /* @__PURE__ */ jsx("path", { d: "m19 9-5 5-4-4-3 3" })
114
- ]
115
- }
116
- );
117
- }
118
- function BillingDashboard({
119
- subscription,
120
- balance,
121
- usage,
122
- onManageSubscription,
123
- onAddCredits,
124
- variant = "sandbox",
125
- className,
126
- cardClassName
127
- }) {
128
- const colors2 = variantColors[variant];
129
- const totalCredits = balance.available + balance.used;
130
- const usagePercent = totalCredits > 0 ? balance.used / totalCredits * 100 : 0;
131
- const sortedModels = Object.entries(usage.byModel).sort(
132
- ([, a], [, b]) => b - a
133
- );
134
- return /* @__PURE__ */ jsxs("div", { className: cn("grid gap-6 lg:grid-cols-3", className), children: [
135
- /* @__PURE__ */ jsxs(Card, { variant, className: cn("lg:col-span-1", cardClassName), children: [
136
- /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
137
- /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center gap-2 text-base", children: [
138
- /* @__PURE__ */ jsx(CreditCardIcon, { className: colors2.accent }),
139
- "Current Plan"
140
- ] }),
141
- subscription && /* @__PURE__ */ jsx(Badge, { variant: getStatusBadgeVariant(subscription.status), children: subscription.status })
142
- ] }) }),
143
- /* @__PURE__ */ jsx(CardContent, { className: "space-y-4", children: subscription ? /* @__PURE__ */ jsxs(Fragment, { children: [
144
- /* @__PURE__ */ jsxs("div", { children: [
145
- /* @__PURE__ */ jsx("p", { className: cn("font-bold text-2xl", colors2.accent), children: subscription.tierName }),
146
- /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground text-sm", children: [
147
- "Renews ",
148
- formatDate(subscription.renewsAt)
149
- ] })
150
- ] }),
151
- /* @__PURE__ */ jsx(
152
- Button,
153
- {
154
- variant: "outline",
155
- className: "w-full",
156
- onClick: onManageSubscription,
157
- children: "Manage Subscription"
158
- }
159
- )
160
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
161
- /* @__PURE__ */ jsxs("div", { children: [
162
- /* @__PURE__ */ jsx("p", { className: "font-bold text-2xl text-muted-foreground", children: "No Active Plan" }),
163
- /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: "Subscribe to get started" })
164
- ] }),
165
- /* @__PURE__ */ jsx(
166
- Button,
167
- {
168
- variant,
169
- className: "w-full",
170
- onClick: onManageSubscription,
171
- children: "View Plans"
172
- }
173
- )
174
- ] }) })
175
- ] }),
176
- /* @__PURE__ */ jsxs(Card, { variant, className: cn("lg:col-span-1", cardClassName), children: [
177
- /* @__PURE__ */ jsxs(CardHeader, { children: [
178
- /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center gap-2 text-base", children: [
179
- /* @__PURE__ */ jsx(CoinsIcon, { className: colors2.accent }),
180
- "Credit Balance"
181
- ] }),
182
- /* @__PURE__ */ jsxs(CardDescription, { children: [
183
- formatCredits(balance.available),
184
- " credits remaining"
185
- ] })
186
- ] }),
187
- /* @__PURE__ */ jsxs(CardContent, { className: "space-y-4", children: [
188
- /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
189
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
190
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Used" }),
191
- /* @__PURE__ */ jsx("span", { className: "font-medium", children: formatCredits(balance.used) })
192
- ] }),
193
- /* @__PURE__ */ jsx(Progress, { value: usagePercent, variant, className: "h-3" }),
194
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
195
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Available" }),
196
- /* @__PURE__ */ jsx("span", { className: cn("font-medium", colors2.accent), children: formatCredits(balance.available) })
197
- ] })
198
- ] }),
199
- /* @__PURE__ */ jsx(Button, { variant, className: "w-full", onClick: onAddCredits, children: "Add Credits" })
200
- ] })
201
- ] }),
202
- /* @__PURE__ */ jsxs(Card, { variant, className: cn("lg:col-span-1", cardClassName), children: [
203
- /* @__PURE__ */ jsxs(CardHeader, { children: [
204
- /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center gap-2 text-base", children: [
205
- /* @__PURE__ */ jsx(ChartIcon, { className: colors2.accent }),
206
- "Usage Breakdown"
207
- ] }),
208
- /* @__PURE__ */ jsx(CardDescription, { children: usage.period })
209
- ] }),
210
- /* @__PURE__ */ jsxs(CardContent, { className: "space-y-4", children: [
211
- /* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between", children: [
212
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: "Total Usage" }),
213
- /* @__PURE__ */ jsx("span", { className: cn("font-bold text-2xl", colors2.accent), children: formatCredits(usage.total) })
214
- ] }),
215
- /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
216
- /* @__PURE__ */ jsx("p", { className: "font-medium text-muted-foreground text-xs uppercase tracking-wider", children: "By Model" }),
217
- /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
218
- sortedModels.slice(0, 5).map(([model, credits]) => {
219
- const modelPercent = usage.total > 0 ? credits / usage.total * 100 : 0;
220
- return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
221
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
222
- /* @__PURE__ */ jsx("span", { className: "truncate text-muted-foreground", children: model }),
223
- /* @__PURE__ */ jsx("span", { className: "ml-2 font-medium", children: formatCredits(credits) })
224
- ] }),
225
- /* @__PURE__ */ jsx("div", { className: "h-1.5 w-full overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx(
226
- "div",
227
- {
228
- className: cn(
229
- "h-full rounded-full transition-all",
230
- variant === "sandbox" && colors2.progress
231
- ),
232
- style: { width: `${modelPercent}%` }
233
- }
234
- ) })
235
- ] }, model);
236
- }),
237
- sortedModels.length > 5 && /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground text-xs", children: [
238
- "+",
239
- sortedModels.length - 5,
240
- " more models"
241
- ] }),
242
- sortedModels.length === 0 && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: "No usage this period" })
243
- ] })
244
- ] })
245
- ] })
246
- ] })
247
- ] });
248
- }
249
-
250
- // src/dashboard/pricing-page.tsx
251
- import { Check, Zap } from "lucide-react";
252
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
253
- function formatPrice(cents) {
254
- if (!Number.isFinite(cents) || cents < 0) return "$0";
255
- return cents % 100 === 0 ? `$${cents / 100}` : `$${(cents / 100).toFixed(2)}`;
256
- }
257
- function PricingPage({
258
- tiers,
259
- currentTierId,
260
- billingPeriod,
261
- onBillingPeriodChange,
262
- onSelectTier,
263
- loading = false,
264
- className
265
- }) {
266
- const tiersWithRecommended = tiers.map((tier, i) => ({
267
- ...tier,
268
- recommended: tier.recommended ?? (tiers.length === 3 && i === 1)
269
- }));
270
- return /* @__PURE__ */ jsxs2("div", { className: cn("w-full space-y-10", className), children: [
271
- /* @__PURE__ */ jsx2("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxs2("div", { className: "inline-flex items-center rounded-full border border-[var(--md3-outline-variant)] bg-surface-container-low p-1", children: [
272
- /* @__PURE__ */ jsx2(
273
- "button",
274
- {
275
- type: "button",
276
- onClick: () => onBillingPeriodChange("monthly"),
277
- className: cn(
278
- "rounded-full px-5 py-2 text-sm font-medium transition-all",
279
- billingPeriod === "monthly" ? "bg-surface-container-high text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
280
- ),
281
- children: "Monthly"
282
- }
283
- ),
284
- /* @__PURE__ */ jsxs2(
285
- "button",
286
- {
287
- type: "button",
288
- onClick: () => onBillingPeriodChange("yearly"),
289
- className: cn(
290
- "rounded-full px-5 py-2 text-sm font-medium transition-all",
291
- billingPeriod === "yearly" ? "bg-surface-container-high text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
292
- ),
293
- children: [
294
- "Yearly",
295
- /* @__PURE__ */ jsx2("span", { className: "ml-2 rounded-full bg-[var(--surface-success-bg)] px-2 py-0.5 text-[10px] font-bold text-[var(--surface-success-text)]", children: "Save 20%" })
296
- ]
297
- }
298
- )
299
- ] }) }),
300
- /* @__PURE__ */ jsx2("div", { className: "grid grid-cols-1 gap-6 lg:grid-cols-3 items-start", children: tiersWithRecommended.map((tier) => {
301
- const isCurrentTier = tier.id === currentTierId;
302
- const isRecommended = tier.recommended;
303
- const isFree = tier.monthlyPriceCents === 0;
304
- const price = billingPeriod === "yearly" && tier.yearlyPriceCents !== void 0 ? tier.yearlyPriceCents : tier.monthlyPriceCents;
305
- const displayPrice = billingPeriod === "yearly" ? Math.round(price / 12) : price;
306
- return /* @__PURE__ */ jsxs2(
307
- "div",
308
- {
309
- className: cn(
310
- "relative flex flex-col rounded-2xl border bg-surface-container transition-all",
311
- isRecommended ? "border-primary shadow-[var(--shadow-glow)] scale-[1.02] z-10" : "border-[var(--md3-outline-variant)] hover:border-primary/30"
312
- ),
313
- children: [
314
- isRecommended && /* @__PURE__ */ jsx2("div", { className: "absolute -top-4 left-1/2 -translate-x-1/2", children: /* @__PURE__ */ jsxs2("span", { className: "inline-flex items-center gap-1.5 rounded-full bg-primary px-4 py-1.5 text-xs font-bold text-primary-foreground shadow-sm", children: [
315
- /* @__PURE__ */ jsx2(Zap, { className: "h-3 w-3" }),
316
- "Most Popular"
317
- ] }) }),
318
- isCurrentTier && !isRecommended && /* @__PURE__ */ jsx2("div", { className: "absolute -top-4 left-1/2 -translate-x-1/2", children: /* @__PURE__ */ jsx2("span", { className: "inline-flex items-center rounded-full bg-surface-container-high border border-[var(--md3-outline-variant)] px-4 py-1.5 text-xs font-bold text-foreground", children: "Current Plan" }) }),
319
- /* @__PURE__ */ jsxs2("div", { className: cn("flex flex-col p-8", isRecommended && "pt-10"), children: [
320
- /* @__PURE__ */ jsxs2("div", { className: "mb-6", children: [
321
- /* @__PURE__ */ jsx2("h3", { className: "text-lg font-bold text-foreground", children: tier.name }),
322
- /* @__PURE__ */ jsx2("p", { className: "mt-1 text-sm text-muted-foreground", children: tier.description })
323
- ] }),
324
- /* @__PURE__ */ jsxs2("div", { className: "mb-8", children: [
325
- /* @__PURE__ */ jsxs2("div", { className: "flex items-baseline gap-1", children: [
326
- /* @__PURE__ */ jsx2("span", { className: cn("text-5xl font-extrabold tracking-tight", isRecommended ? "text-primary" : "text-foreground"), children: isFree ? "Free" : formatPrice(displayPrice) }),
327
- !isFree && /* @__PURE__ */ jsx2("span", { className: "text-muted-foreground text-sm font-medium", children: "/mo" })
328
- ] }),
329
- billingPeriod === "yearly" && tier.yearlyPriceCents !== void 0 && !isFree && /* @__PURE__ */ jsxs2("p", { className: "mt-1 text-xs text-muted-foreground", children: [
330
- formatPrice(tier.yearlyPriceCents),
331
- " billed annually"
332
- ] })
333
- ] }),
334
- /* @__PURE__ */ jsx2(
335
- "button",
336
- {
337
- type: "button",
338
- onClick: () => onSelectTier(tier.id),
339
- disabled: isCurrentTier || loading,
340
- className: cn(
341
- "w-full rounded-xl py-3 text-sm font-bold transition-all active:scale-[0.98] disabled:opacity-50",
342
- isRecommended ? "bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm" : isCurrentTier ? "bg-muted text-muted-foreground border border-[var(--md3-outline-variant)] cursor-default" : "bg-surface-container-high text-foreground border border-[var(--md3-outline-variant)] hover:border-primary/50 hover:bg-surface-container-highest"
343
- ),
344
- children: isCurrentTier ? "Current Plan" : isFree ? "Get Started" : "Subscribe"
345
- }
346
- ),
347
- /* @__PURE__ */ jsx2("div", { className: "my-8 border-t border-[var(--md3-outline-variant)]" }),
348
- /* @__PURE__ */ jsx2("ul", { className: "space-y-3.5 flex-1", children: tier.features.map((feature) => /* @__PURE__ */ jsxs2("li", { className: "flex items-start gap-3", children: [
349
- /* @__PURE__ */ jsx2("div", { className: cn(
350
- "mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full",
351
- isRecommended ? "bg-primary/10 text-primary" : "bg-surface-container-high text-muted-foreground"
352
- ), children: /* @__PURE__ */ jsx2(Check, { className: "h-3 w-3" }) }),
353
- /* @__PURE__ */ jsx2("span", { className: "text-sm text-foreground/80", children: feature })
354
- ] }, feature)) })
355
- ] })
356
- ]
357
- },
358
- tier.id
359
- );
360
- }) })
361
- ] });
362
- }
363
-
364
- // src/dashboard/usage-chart.tsx
365
- import * as React from "react";
366
- import { Card as Card2, CardContent as CardContent2, CardHeader as CardHeader2, CardTitle as CardTitle2 } from "@tangle-network/ui/primitives";
367
- import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
368
- var colors = {
369
- bar: "bg-[image:var(--accent-gradient-strong)]",
370
- barHover: "hover:brightness-110",
371
- text: "text-[var(--accent-text)]"
372
- };
373
- function formatDate2(dateStr) {
374
- const date = new Date(dateStr);
375
- return date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
376
- }
377
- function formatValue(value) {
378
- if (value >= 1e6) {
379
- return `${(value / 1e6).toFixed(1)}M`;
380
- }
381
- if (value >= 1e3) {
382
- return `${(value / 1e3).toFixed(1)}K`;
383
- }
384
- return value.toLocaleString();
385
- }
386
- function UsageChart({ data, title, unit, className }) {
387
- const maxValue = Math.max(...data.map((d) => d.value), 1);
388
- const total = data.reduce((sum, d) => sum + d.value, 0);
389
- const [hoveredIndex, setHoveredIndex] = React.useState(null);
390
- const isEmpty = data.length === 0 || total === 0;
391
- return /* @__PURE__ */ jsxs3(Card2, { className, children: [
392
- /* @__PURE__ */ jsxs3(CardHeader2, { className: "flex flex-row items-center justify-between gap-3 pb-2", children: [
393
- /* @__PURE__ */ jsx3(CardTitle2, { className: "min-w-0 truncate font-medium text-base", children: title }),
394
- /* @__PURE__ */ jsxs3("div", { className: "shrink-0 whitespace-nowrap text-right", children: [
395
- /* @__PURE__ */ jsx3("span", { className: cn("font-bold text-2xl", colors.text), children: formatValue(total) }),
396
- /* @__PURE__ */ jsx3("span", { className: "ml-1 text-muted-foreground text-sm", children: unit })
397
- ] })
398
- ] }),
399
- /* @__PURE__ */ jsx3(CardContent2, { children: isEmpty ? /* @__PURE__ */ jsxs3("div", { className: "flex h-48 flex-col items-center justify-center gap-1 text-center", children: [
400
- /* @__PURE__ */ jsxs3("p", { className: "font-medium text-sm", children: [
401
- "No ",
402
- unit,
403
- " recorded yet"
404
- ] }),
405
- /* @__PURE__ */ jsx3("p", { className: "text-muted-foreground text-xs", children: "Usage appears here once activity begins." })
406
- ] }) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
407
- /* @__PURE__ */ jsxs3("div", { className: "relative", children: [
408
- /* @__PURE__ */ jsxs3("div", { className: "absolute top-0 left-0 flex h-48 flex-col justify-between text-muted-foreground text-xs", children: [
409
- /* @__PURE__ */ jsx3("span", { children: formatValue(maxValue) }),
410
- /* @__PURE__ */ jsx3("span", { children: formatValue(Math.round(maxValue / 2)) }),
411
- /* @__PURE__ */ jsx3("span", { children: "0" })
412
- ] }),
413
- /* @__PURE__ */ jsx3("div", { className: "ml-10 flex h-48 items-end gap-1", children: data.map((point, index) => {
414
- const heightPercent = point.value / maxValue * 100;
415
- const isHovered = hoveredIndex === index;
416
- return (
417
- // biome-ignore lint/a11y/noStaticElementInteractions: chart bar uses hover for tooltip display
418
- /* @__PURE__ */ jsxs3(
419
- "div",
420
- {
421
- className: "group relative flex flex-1 flex-col items-center",
422
- onMouseEnter: () => setHoveredIndex(index),
423
- onMouseLeave: () => setHoveredIndex(null),
424
- children: [
425
- isHovered && /* @__PURE__ */ jsxs3("div", { className: "absolute -top-12 z-10 rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container-highest px-3 py-1.5 text-sm shadow-[0_8px_30px_rgba(0,0,0,0.45)] ring-1 ring-[#ffffff14]", children: [
426
- /* @__PURE__ */ jsxs3("p", { className: "font-medium", children: [
427
- formatValue(point.value),
428
- " ",
429
- unit
430
- ] }),
431
- /* @__PURE__ */ jsx3("p", { className: "text-muted-foreground text-xs", children: formatDate2(point.date) })
432
- ] }),
433
- /* @__PURE__ */ jsx3(
434
- "div",
435
- {
436
- className: cn(
437
- "min-h-[2px] w-full rounded-t-sm transition-all duration-200",
438
- colors.bar,
439
- colors.barHover,
440
- isHovered && "opacity-80"
441
- ),
442
- style: { height: `${Math.max(heightPercent, 1)}%` }
443
- }
444
- )
445
- ]
446
- },
447
- point.date
448
- )
449
- );
450
- }) }),
451
- /* @__PURE__ */ jsx3("div", { className: "mt-2 ml-10 flex gap-1", children: data.map((point, index) => /* @__PURE__ */ jsx3(
452
- "div",
453
- {
454
- className: cn(
455
- "flex-1 truncate text-center text-muted-foreground text-xs",
456
- hoveredIndex === index && colors.text
457
- ),
458
- children: data.length <= 7 || index % Math.ceil(data.length / 7) === 0 ? formatDate2(point.date) : ""
459
- },
460
- point.date
461
- )) })
462
- ] }),
463
- /* @__PURE__ */ jsxs3("div", { className: "mt-4 grid grid-cols-3 gap-4 border-[var(--md3-outline-variant)] border-t pt-4", children: [
464
- /* @__PURE__ */ jsxs3("div", { className: "text-center", children: [
465
- /* @__PURE__ */ jsx3("p", { className: "text-muted-foreground text-xs", children: "Average" }),
466
- /* @__PURE__ */ jsxs3("p", { className: "font-medium", children: [
467
- formatValue(Math.round(total / data.length)),
468
- " ",
469
- unit
470
- ] })
471
- ] }),
472
- /* @__PURE__ */ jsxs3("div", { className: "text-center", children: [
473
- /* @__PURE__ */ jsx3("p", { className: "text-muted-foreground text-xs", children: "Peak" }),
474
- /* @__PURE__ */ jsxs3("p", { className: "font-medium", children: [
475
- formatValue(maxValue),
476
- " ",
477
- unit
478
- ] })
479
- ] }),
480
- /* @__PURE__ */ jsxs3("div", { className: "text-center", children: [
481
- /* @__PURE__ */ jsx3("p", { className: "text-muted-foreground text-xs", children: "Total" }),
482
- /* @__PURE__ */ jsxs3("p", { className: cn("font-medium", colors.text), children: [
483
- formatValue(total),
484
- " ",
485
- unit
486
- ] })
487
- ] })
488
- ] })
489
- ] }) })
490
- ] });
491
- }
492
-
493
- // src/dashboard/template-card.tsx
494
- import { ArrowRight } from "lucide-react";
495
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
496
- function TemplateCard({ template, onUseTemplate, className }) {
497
- return /* @__PURE__ */ jsxs4(
498
- "div",
499
- {
500
- className: cn(
501
- "group relative flex flex-col justify-between rounded-xl border border-[var(--md3-outline-variant)] bg-surface-container p-6 transition-colors hover:border-[var(--border-accent)]",
502
- className
503
- ),
504
- children: [
505
- /* @__PURE__ */ jsxs4("div", { children: [
506
- /* @__PURE__ */ jsx4("div", { className: "mb-4 flex h-12 w-12 items-center justify-center rounded-xl bg-surface-container-high border border-[var(--md3-outline-variant)]", children: template.icon ?? /* @__PURE__ */ jsx4("span", { className: "text-lg font-bold text-primary", children: template.name.charAt(0).toUpperCase() }) }),
507
- /* @__PURE__ */ jsx4("h3", { className: "mb-1 text-base font-bold text-foreground", children: template.name }),
508
- /* @__PURE__ */ jsx4("p", { className: "text-sm text-muted-foreground leading-relaxed line-clamp-2", children: template.description }),
509
- template.tags && template.tags.length > 0 && /* @__PURE__ */ jsx4("div", { className: "mt-3 flex flex-wrap gap-1.5", children: template.tags.map((tag, i) => /* @__PURE__ */ jsx4(
510
- "span",
511
- {
512
- className: "rounded-full bg-surface-container-high px-2 py-0.5 text-[10px] font-medium text-muted-foreground",
513
- children: tag
514
- },
515
- `${tag}-${i}`
516
- )) })
517
- ] }),
518
- /* @__PURE__ */ jsxs4(
519
- "button",
520
- {
521
- type: "button",
522
- onClick: () => onUseTemplate(template.id),
523
- className: "mt-5 inline-flex w-full items-center justify-center gap-2 rounded-xl bg-primary/10 border border-primary/20 px-4 py-2.5 text-sm font-bold text-primary transition-colors hover:bg-primary hover:text-primary-foreground active:scale-[0.98]",
524
- children: [
525
- "Use Template",
526
- /* @__PURE__ */ jsx4(ArrowRight, { className: "h-4 w-4 transition-transform group-hover:translate-x-0.5" })
527
- ]
528
- }
529
- )
530
- ]
531
- }
532
- );
533
- }
534
-
535
- // src/dashboard/info-panel.tsx
536
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
537
- function InfoPanel({ label, title, description, className }) {
538
- return /* @__PURE__ */ jsxs5("div", { className: cn("rounded-lg bg-[var(--brand-strong)] p-5 text-[var(--brand-strong-text)] relative overflow-hidden", className), children: [
539
- /* @__PURE__ */ jsxs5("div", { className: "relative z-10", children: [
540
- /* @__PURE__ */ jsx5("p", { className: "text-[10px] font-bold uppercase tracking-widest text-[var(--brand-strong-text-dim)]", children: label }),
541
- /* @__PURE__ */ jsx5("h3", { className: "mt-1 text-lg font-bold", children: title }),
542
- /* @__PURE__ */ jsx5("p", { className: "mt-1 text-sm text-[var(--brand-strong-text-muted)]", children: description })
543
- ] }),
544
- /* @__PURE__ */ jsx5("div", { className: "absolute right-0 top-0 h-full w-1/3 bg-white/5 -skew-x-12 translate-x-12 pointer-events-none" })
545
- ] });
546
- }
547
-
548
- export {
549
- BillingDashboard,
550
- formatPrice,
551
- PricingPage,
552
- UsageChart,
553
- TemplateCard,
554
- InfoPanel
555
- };