@tangle-network/sandbox-ui 0.2.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 (70) hide show
  1. package/README.md +68 -0
  2. package/dist/auth.d.ts +57 -0
  3. package/dist/auth.js +14 -0
  4. package/dist/branding-DCi5VEik.d.ts +13 -0
  5. package/dist/button-BidTtuRS.d.ts +15 -0
  6. package/dist/chat.d.ts +121 -0
  7. package/dist/chat.js +25 -0
  8. package/dist/chunk-2UHPE5T7.js +201 -0
  9. package/dist/chunk-4EIWPJMJ.js +545 -0
  10. package/dist/chunk-6MQIDUPA.js +502 -0
  11. package/dist/chunk-B26TQ7SA.js +47 -0
  12. package/dist/chunk-E6FS7R4X.js +109 -0
  13. package/dist/chunk-GRYHFH5O.js +110 -0
  14. package/dist/chunk-HMND7JPA.js +868 -0
  15. package/dist/chunk-HRMUF35V.js +19 -0
  16. package/dist/chunk-HYEAX3DC.js +822 -0
  17. package/dist/chunk-KMXV7DDX.js +174 -0
  18. package/dist/chunk-KYY2X6LY.js +318 -0
  19. package/dist/chunk-L6ZDH5F4.js +334 -0
  20. package/dist/chunk-LTFK464G.js +103 -0
  21. package/dist/chunk-M34OA6PQ.js +233 -0
  22. package/dist/chunk-M6VLC32S.js +219 -0
  23. package/dist/chunk-MCGKDCOR.js +173 -0
  24. package/dist/chunk-NI2EI43H.js +294 -0
  25. package/dist/chunk-OU4TRNQZ.js +173 -0
  26. package/dist/chunk-QD4QE5P5.js +40 -0
  27. package/dist/chunk-QSQBDR3N.js +180 -0
  28. package/dist/chunk-RQHJBTEU.js +10 -0
  29. package/dist/chunk-U62G5TS7.js +472 -0
  30. package/dist/chunk-ZOL2TR5M.js +475 -0
  31. package/dist/dashboard.d.ts +111 -0
  32. package/dist/dashboard.js +26 -0
  33. package/dist/editor.d.ts +196 -0
  34. package/dist/editor.js +713 -0
  35. package/dist/expanded-tool-detail-OkXGqTHe.d.ts +52 -0
  36. package/dist/files.d.ts +66 -0
  37. package/dist/files.js +11 -0
  38. package/dist/hooks.d.ts +22 -0
  39. package/dist/hooks.js +107 -0
  40. package/dist/index.d.ts +107 -0
  41. package/dist/index.js +551 -0
  42. package/dist/markdown.d.ts +55 -0
  43. package/dist/markdown.js +17 -0
  44. package/dist/pages.d.ts +89 -0
  45. package/dist/pages.js +1181 -0
  46. package/dist/parts-CyGkM6Fp.d.ts +50 -0
  47. package/dist/primitives.d.ts +189 -0
  48. package/dist/primitives.js +161 -0
  49. package/dist/run-CtFZ6s-D.d.ts +41 -0
  50. package/dist/run.d.ts +14 -0
  51. package/dist/run.js +29 -0
  52. package/dist/sidecar-CFU2W9j1.d.ts +8 -0
  53. package/dist/stores.d.ts +28 -0
  54. package/dist/stores.js +49 -0
  55. package/dist/terminal.d.ts +44 -0
  56. package/dist/terminal.js +160 -0
  57. package/dist/tool-call-feed-D5Ume-Pt.d.ts +66 -0
  58. package/dist/tool-display-BvsVW_Ur.d.ts +32 -0
  59. package/dist/types.d.ts +6 -0
  60. package/dist/types.js +0 -0
  61. package/dist/usage-chart-DINgSVL5.d.ts +60 -0
  62. package/dist/use-sidecar-auth-Bb0-w3lX.d.ts +339 -0
  63. package/dist/utils.d.ts +28 -0
  64. package/dist/utils.js +28 -0
  65. package/dist/workspace.d.ts +113 -0
  66. package/dist/workspace.js +15 -0
  67. package/package.json +174 -0
  68. package/src/styles/globals.css +230 -0
  69. package/src/styles/tokens.css +73 -0
  70. package/tailwind.config.cjs +99 -0
@@ -0,0 +1,545 @@
1
+ import {
2
+ Badge,
3
+ Card,
4
+ CardContent,
5
+ CardDescription,
6
+ CardFooter,
7
+ CardHeader,
8
+ CardTitle,
9
+ Progress
10
+ } from "./chunk-2UHPE5T7.js";
11
+ import {
12
+ Button
13
+ } from "./chunk-E6FS7R4X.js";
14
+ import {
15
+ cn
16
+ } from "./chunk-RQHJBTEU.js";
17
+
18
+ // src/dashboard/billing-dashboard.tsx
19
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
20
+ var variantColors = {
21
+ sandbox: {
22
+ accent: "text-purple-400",
23
+ accentBg: "bg-purple-500/10",
24
+ border: "border-purple-500/20"
25
+ }
26
+ };
27
+ function formatCredits(value) {
28
+ if (value >= 1e6) {
29
+ return `${(value / 1e6).toFixed(1)}M`;
30
+ }
31
+ if (value >= 1e3) {
32
+ return `${(value / 1e3).toFixed(1)}K`;
33
+ }
34
+ return value.toLocaleString();
35
+ }
36
+ function formatDate(dateStr) {
37
+ const date = new Date(dateStr);
38
+ return date.toLocaleDateString("en-US", {
39
+ month: "long",
40
+ day: "numeric",
41
+ year: "numeric"
42
+ });
43
+ }
44
+ function getStatusBadgeVariant(status) {
45
+ switch (status.toLowerCase()) {
46
+ case "active":
47
+ return "success";
48
+ case "trialing":
49
+ case "past_due":
50
+ return "warning";
51
+ case "canceled":
52
+ case "unpaid":
53
+ return "error";
54
+ default:
55
+ return "secondary";
56
+ }
57
+ }
58
+ function CreditCardIcon({ className }) {
59
+ return /* @__PURE__ */ jsxs(
60
+ "svg",
61
+ {
62
+ xmlns: "http://www.w3.org/2000/svg",
63
+ viewBox: "0 0 24 24",
64
+ fill: "none",
65
+ stroke: "currentColor",
66
+ strokeWidth: "2",
67
+ strokeLinecap: "round",
68
+ strokeLinejoin: "round",
69
+ className: cn("h-5 w-5", className),
70
+ children: [
71
+ /* @__PURE__ */ jsx("title", { children: "Credit card icon" }),
72
+ /* @__PURE__ */ jsx("rect", { width: "20", height: "14", x: "2", y: "5", rx: "2" }),
73
+ /* @__PURE__ */ jsx("line", { x1: "2", x2: "22", y1: "10", y2: "10" })
74
+ ]
75
+ }
76
+ );
77
+ }
78
+ function CoinsIcon({ className }) {
79
+ return /* @__PURE__ */ jsxs(
80
+ "svg",
81
+ {
82
+ xmlns: "http://www.w3.org/2000/svg",
83
+ viewBox: "0 0 24 24",
84
+ fill: "none",
85
+ stroke: "currentColor",
86
+ strokeWidth: "2",
87
+ strokeLinecap: "round",
88
+ strokeLinejoin: "round",
89
+ className: cn("h-5 w-5", className),
90
+ children: [
91
+ /* @__PURE__ */ jsx("title", { children: "Coins icon" }),
92
+ /* @__PURE__ */ jsx("circle", { cx: "8", cy: "8", r: "6" }),
93
+ /* @__PURE__ */ jsx("path", { d: "M18.09 10.37A6 6 0 1 1 10.34 18" }),
94
+ /* @__PURE__ */ jsx("path", { d: "M7 6h1v4" }),
95
+ /* @__PURE__ */ jsx("path", { d: "m16.71 13.88.7.71-2.82 2.82" })
96
+ ]
97
+ }
98
+ );
99
+ }
100
+ function ChartIcon({ className }) {
101
+ return /* @__PURE__ */ jsxs(
102
+ "svg",
103
+ {
104
+ xmlns: "http://www.w3.org/2000/svg",
105
+ viewBox: "0 0 24 24",
106
+ fill: "none",
107
+ stroke: "currentColor",
108
+ strokeWidth: "2",
109
+ strokeLinecap: "round",
110
+ strokeLinejoin: "round",
111
+ className: cn("h-5 w-5", className),
112
+ children: [
113
+ /* @__PURE__ */ jsx("title", { children: "Chart icon" }),
114
+ /* @__PURE__ */ jsx("path", { d: "M3 3v18h18" }),
115
+ /* @__PURE__ */ jsx("path", { d: "m19 9-5 5-4-4-3 3" })
116
+ ]
117
+ }
118
+ );
119
+ }
120
+ function BillingDashboard({
121
+ subscription,
122
+ balance,
123
+ usage,
124
+ onManageSubscription,
125
+ onAddCredits,
126
+ variant = "sandbox"
127
+ }) {
128
+ const colors = 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: "grid gap-6 lg:grid-cols-3", children: [
135
+ /* @__PURE__ */ jsxs(Card, { variant, className: "lg:col-span-1", 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: colors.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", colors.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: "lg:col-span-1", children: [
177
+ /* @__PURE__ */ jsxs(CardHeader, { children: [
178
+ /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center gap-2 text-base", children: [
179
+ /* @__PURE__ */ jsx(CoinsIcon, { className: colors.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", colors.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: "lg:col-span-1", children: [
203
+ /* @__PURE__ */ jsxs(CardHeader, { children: [
204
+ /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center gap-2 text-base", children: [
205
+ /* @__PURE__ */ jsx(ChartIcon, { className: colors.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", colors.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" && "bg-purple-500"
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 { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
252
+ var variantColors2 = {
253
+ sandbox: {
254
+ accent: "text-purple-400",
255
+ border: "border-purple-500",
256
+ bg: "bg-purple-500/10",
257
+ ring: "ring-purple-500/50"
258
+ }
259
+ };
260
+ function formatPrice(cents) {
261
+ return (cents / 100).toLocaleString("en-US", {
262
+ style: "currency",
263
+ currency: "USD",
264
+ minimumFractionDigits: 0,
265
+ maximumFractionDigits: 0
266
+ });
267
+ }
268
+ function CheckIcon({ className }) {
269
+ return /* @__PURE__ */ jsxs2(
270
+ "svg",
271
+ {
272
+ xmlns: "http://www.w3.org/2000/svg",
273
+ viewBox: "0 0 20 20",
274
+ fill: "currentColor",
275
+ className: cn("h-5 w-5", className),
276
+ children: [
277
+ /* @__PURE__ */ jsx2("title", { children: "Check icon" }),
278
+ /* @__PURE__ */ jsx2(
279
+ "path",
280
+ {
281
+ fillRule: "evenodd",
282
+ d: "M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z",
283
+ clipRule: "evenodd"
284
+ }
285
+ )
286
+ ]
287
+ }
288
+ );
289
+ }
290
+ function PricingPage({
291
+ tiers,
292
+ currentTierId,
293
+ billingPeriod,
294
+ onBillingPeriodChange,
295
+ onSelectTier,
296
+ variant = "sandbox",
297
+ loading = false
298
+ }) {
299
+ const colors = variantColors2[variant];
300
+ return /* @__PURE__ */ jsxs2("div", { className: "w-full space-y-8", children: [
301
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-center gap-4", children: [
302
+ /* @__PURE__ */ jsx2(
303
+ "button",
304
+ {
305
+ type: "button",
306
+ onClick: () => onBillingPeriodChange("monthly"),
307
+ className: cn(
308
+ "rounded-lg px-4 py-2 font-medium text-sm transition-all",
309
+ billingPeriod === "monthly" ? cn("bg-muted text-foreground", colors.ring, "ring-2") : "text-muted-foreground hover:text-foreground"
310
+ ),
311
+ children: "Monthly"
312
+ }
313
+ ),
314
+ /* @__PURE__ */ jsxs2(
315
+ "button",
316
+ {
317
+ type: "button",
318
+ onClick: () => onBillingPeriodChange("yearly"),
319
+ className: cn(
320
+ "rounded-lg px-4 py-2 font-medium text-sm transition-all",
321
+ billingPeriod === "yearly" ? cn("bg-muted text-foreground", colors.ring, "ring-2") : "text-muted-foreground hover:text-foreground"
322
+ ),
323
+ children: [
324
+ "Yearly",
325
+ /* @__PURE__ */ jsx2("span", { className: cn("ml-2 text-xs", colors.accent), children: "Save 20%" })
326
+ ]
327
+ }
328
+ )
329
+ ] }),
330
+ /* @__PURE__ */ jsx2("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3", children: tiers.map((tier) => {
331
+ const isCurrentTier = tier.id === currentTierId;
332
+ const price = billingPeriod === "yearly" && tier.yearlyPriceCents !== void 0 ? tier.yearlyPriceCents : tier.monthlyPriceCents;
333
+ const displayPrice = billingPeriod === "yearly" ? Math.round(price / 12) : price;
334
+ return /* @__PURE__ */ jsxs2(
335
+ Card,
336
+ {
337
+ variant,
338
+ className: cn(
339
+ "relative flex flex-col",
340
+ tier.recommended && cn(colors.border, "border-2 ring-2", colors.ring),
341
+ isCurrentTier && "ring-2 ring-offset-2 ring-offset-background",
342
+ isCurrentTier && colors.ring
343
+ ),
344
+ children: [
345
+ tier.recommended && /* @__PURE__ */ jsx2("div", { className: "absolute -top-3 left-1/2 -translate-x-1/2", children: /* @__PURE__ */ jsx2(Badge, { variant, children: "Recommended" }) }),
346
+ isCurrentTier && /* @__PURE__ */ jsx2("div", { className: "absolute -top-3 right-4", children: /* @__PURE__ */ jsx2(Badge, { variant: "secondary", children: "Current Plan" }) }),
347
+ /* @__PURE__ */ jsxs2(CardHeader, { className: "text-center", children: [
348
+ /* @__PURE__ */ jsx2(CardTitle, { className: "text-xl", children: tier.name }),
349
+ /* @__PURE__ */ jsx2(CardDescription, { children: tier.description })
350
+ ] }),
351
+ /* @__PURE__ */ jsxs2(CardContent, { className: "flex-1 space-y-6", children: [
352
+ /* @__PURE__ */ jsxs2("div", { className: "text-center", children: [
353
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-baseline justify-center gap-1", children: [
354
+ /* @__PURE__ */ jsx2("span", { className: cn("font-bold text-4xl", colors.accent), children: formatPrice(displayPrice) }),
355
+ /* @__PURE__ */ jsx2("span", { className: "text-muted-foreground", children: "/mo" })
356
+ ] }),
357
+ billingPeriod === "yearly" && tier.yearlyPriceCents !== void 0 && /* @__PURE__ */ jsxs2("p", { className: "mt-1 text-muted-foreground text-sm", children: [
358
+ formatPrice(tier.yearlyPriceCents),
359
+ " billed annually"
360
+ ] })
361
+ ] }),
362
+ tier.creditsPerMonth !== void 0 && /* @__PURE__ */ jsxs2("div", { className: cn("rounded-lg p-3 text-center", colors.bg), children: [
363
+ /* @__PURE__ */ jsx2("span", { className: cn("font-semibold", colors.accent), children: tier.creditsPerMonth.toLocaleString() }),
364
+ /* @__PURE__ */ jsxs2("span", { className: "text-muted-foreground text-sm", children: [
365
+ " ",
366
+ "credits/month"
367
+ ] })
368
+ ] }),
369
+ /* @__PURE__ */ jsx2("ul", { className: "space-y-3", children: tier.features.map((feature) => /* @__PURE__ */ jsxs2("li", { className: "flex items-start gap-3", children: [
370
+ /* @__PURE__ */ jsx2(
371
+ CheckIcon,
372
+ {
373
+ className: cn("mt-0.5 shrink-0", colors.accent)
374
+ }
375
+ ),
376
+ /* @__PURE__ */ jsx2("span", { className: "text-muted-foreground text-sm", children: feature })
377
+ ] }, feature)) })
378
+ ] }),
379
+ /* @__PURE__ */ jsx2(CardFooter, { children: /* @__PURE__ */ jsx2(
380
+ Button,
381
+ {
382
+ variant: isCurrentTier ? "outline" : variant,
383
+ className: "w-full",
384
+ disabled: isCurrentTier || loading,
385
+ loading,
386
+ onClick: () => onSelectTier(tier.id),
387
+ children: isCurrentTier ? "Current Plan" : currentTierId ? "Upgrade" : "Subscribe"
388
+ }
389
+ ) })
390
+ ]
391
+ },
392
+ tier.id
393
+ );
394
+ }) })
395
+ ] });
396
+ }
397
+
398
+ // src/dashboard/usage-chart.tsx
399
+ import * as React from "react";
400
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
401
+ var variantColors3 = {
402
+ agentrun: {
403
+ bar: "bg-gradient-to-t from-blue-600 to-blue-400",
404
+ barHover: "hover:from-blue-500 hover:to-blue-300",
405
+ text: "text-blue-400"
406
+ },
407
+ automateai: {
408
+ bar: "bg-gradient-to-t from-violet-600 to-violet-400",
409
+ barHover: "hover:from-violet-500 hover:to-violet-300",
410
+ text: "text-violet-400"
411
+ },
412
+ tradingbots: {
413
+ bar: "bg-gradient-to-t from-green-600 to-green-400",
414
+ barHover: "hover:from-green-500 hover:to-green-300",
415
+ text: "text-green-400"
416
+ },
417
+ sandbox: {
418
+ bar: "bg-gradient-to-t from-purple-600 to-purple-400",
419
+ barHover: "hover:from-purple-500 hover:to-purple-300",
420
+ text: "text-purple-400"
421
+ }
422
+ };
423
+ function formatDate2(dateStr) {
424
+ const date = new Date(dateStr);
425
+ return date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
426
+ }
427
+ function formatValue(value) {
428
+ if (value >= 1e6) {
429
+ return `${(value / 1e6).toFixed(1)}M`;
430
+ }
431
+ if (value >= 1e3) {
432
+ return `${(value / 1e3).toFixed(1)}K`;
433
+ }
434
+ return value.toLocaleString();
435
+ }
436
+ function UsageChart({
437
+ data,
438
+ title,
439
+ unit,
440
+ variant = "agentrun"
441
+ }) {
442
+ const colors = variantColors3[variant];
443
+ const maxValue = Math.max(...data.map((d) => d.value), 1);
444
+ const total = data.reduce((sum, d) => sum + d.value, 0);
445
+ const [hoveredIndex, setHoveredIndex] = React.useState(null);
446
+ return /* @__PURE__ */ jsxs3(Card, { children: [
447
+ /* @__PURE__ */ jsxs3(CardHeader, { className: "flex flex-row items-center justify-between pb-2", children: [
448
+ /* @__PURE__ */ jsx3(CardTitle, { className: "font-medium text-base", children: title }),
449
+ /* @__PURE__ */ jsxs3("div", { className: "text-right", children: [
450
+ /* @__PURE__ */ jsx3("span", { className: cn("font-bold text-2xl", colors.text), children: formatValue(total) }),
451
+ /* @__PURE__ */ jsx3("span", { className: "ml-1 text-muted-foreground text-sm", children: unit })
452
+ ] })
453
+ ] }),
454
+ /* @__PURE__ */ jsxs3(CardContent, { children: [
455
+ /* @__PURE__ */ jsxs3("div", { className: "relative", children: [
456
+ /* @__PURE__ */ jsxs3("div", { className: "absolute top-0 left-0 flex h-48 flex-col justify-between text-muted-foreground text-xs", children: [
457
+ /* @__PURE__ */ jsx3("span", { children: formatValue(maxValue) }),
458
+ /* @__PURE__ */ jsx3("span", { children: formatValue(Math.round(maxValue / 2)) }),
459
+ /* @__PURE__ */ jsx3("span", { children: "0" })
460
+ ] }),
461
+ /* @__PURE__ */ jsx3("div", { className: "ml-10 flex h-48 items-end gap-1", children: data.map((point, index) => {
462
+ const heightPercent = point.value / maxValue * 100;
463
+ const isHovered = hoveredIndex === index;
464
+ return (
465
+ // biome-ignore lint/a11y/noStaticElementInteractions: chart bar uses hover for tooltip display
466
+ /* @__PURE__ */ jsxs3(
467
+ "div",
468
+ {
469
+ className: "group relative flex flex-1 flex-col items-center",
470
+ onMouseEnter: () => setHoveredIndex(index),
471
+ onMouseLeave: () => setHoveredIndex(null),
472
+ children: [
473
+ isHovered && /* @__PURE__ */ jsxs3("div", { className: "absolute -top-12 z-10 rounded-lg bg-popover px-3 py-1.5 text-sm shadow-lg", children: [
474
+ /* @__PURE__ */ jsxs3("p", { className: "font-medium", children: [
475
+ formatValue(point.value),
476
+ " ",
477
+ unit
478
+ ] }),
479
+ /* @__PURE__ */ jsx3("p", { className: "text-muted-foreground text-xs", children: formatDate2(point.date) })
480
+ ] }),
481
+ /* @__PURE__ */ jsx3(
482
+ "div",
483
+ {
484
+ className: cn(
485
+ "min-h-[2px] w-full rounded-t-sm transition-all duration-200",
486
+ colors.bar,
487
+ colors.barHover,
488
+ isHovered && "opacity-80"
489
+ ),
490
+ style: { height: `${Math.max(heightPercent, 1)}%` }
491
+ }
492
+ )
493
+ ]
494
+ },
495
+ point.date
496
+ )
497
+ );
498
+ }) }),
499
+ /* @__PURE__ */ jsx3("div", { className: "mt-2 ml-10 flex gap-1", children: data.map((point, index) => /* @__PURE__ */ jsx3(
500
+ "div",
501
+ {
502
+ className: cn(
503
+ "flex-1 truncate text-center text-muted-foreground text-xs",
504
+ hoveredIndex === index && colors.text
505
+ ),
506
+ children: data.length <= 7 || index % Math.ceil(data.length / 7) === 0 ? formatDate2(point.date) : ""
507
+ },
508
+ point.date
509
+ )) })
510
+ ] }),
511
+ /* @__PURE__ */ jsxs3("div", { className: "mt-4 grid grid-cols-3 gap-4 border-border border-t pt-4", children: [
512
+ /* @__PURE__ */ jsxs3("div", { className: "text-center", children: [
513
+ /* @__PURE__ */ jsx3("p", { className: "text-muted-foreground text-xs", children: "Average" }),
514
+ /* @__PURE__ */ jsxs3("p", { className: "font-medium", children: [
515
+ formatValue(Math.round(total / data.length)),
516
+ " ",
517
+ unit
518
+ ] })
519
+ ] }),
520
+ /* @__PURE__ */ jsxs3("div", { className: "text-center", children: [
521
+ /* @__PURE__ */ jsx3("p", { className: "text-muted-foreground text-xs", children: "Peak" }),
522
+ /* @__PURE__ */ jsxs3("p", { className: "font-medium", children: [
523
+ formatValue(maxValue),
524
+ " ",
525
+ unit
526
+ ] })
527
+ ] }),
528
+ /* @__PURE__ */ jsxs3("div", { className: "text-center", children: [
529
+ /* @__PURE__ */ jsx3("p", { className: "text-muted-foreground text-xs", children: "Total" }),
530
+ /* @__PURE__ */ jsxs3("p", { className: cn("font-medium", colors.text), children: [
531
+ formatValue(total),
532
+ " ",
533
+ unit
534
+ ] })
535
+ ] })
536
+ ] })
537
+ ] })
538
+ ] });
539
+ }
540
+
541
+ export {
542
+ BillingDashboard,
543
+ PricingPage,
544
+ UsageChart
545
+ };