@tangle-network/sandbox-ui 0.6.1 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth.d.ts +10 -6
- package/dist/auth.js +3 -3
- package/dist/{chat-container-Cg-GwyiK.d.ts → chat-container-f4yEs6KN.d.ts} +9 -1
- package/dist/chat.d.ts +12 -2
- package/dist/chat.js +10 -10
- package/dist/{chunk-TSE423UF.js → chunk-2QZ6G7NM.js} +6 -6
- package/dist/{chunk-WBQ7VULC.js → chunk-34A66VBG.js} +7 -7
- package/dist/{chunk-JP725R4W.js → chunk-34I7UFSX.js} +2 -2
- package/dist/{chunk-YS66Q3RC.js → chunk-3CJ2SOEI.js} +2 -2
- package/dist/{chunk-CNWVHQFY.js → chunk-54SQQMMM.js} +6 -24
- package/dist/{chunk-DLCFZDGX.js → chunk-5UM2XMEJ.js} +39 -14
- package/dist/{chunk-YYGECNZZ.js → chunk-66EZOYZR.js} +3 -3
- package/dist/chunk-7U2Z23NE.js +49 -0
- package/dist/{chunk-RKXIRRKQ.js → chunk-BUOQTBTO.js} +70 -66
- package/dist/{chunk-DCPYTL4W.js → chunk-D4CZWJCD.js} +72 -148
- package/dist/{chunk-MXRQ4MJE.js → chunk-DXMIEK4K.js} +34 -23
- package/dist/{chunk-ZMWWE5RF.js → chunk-EXSOPXIY.js} +141 -123
- package/dist/{chunk-GW4GRAWJ.js → chunk-GSZA3TSY.js} +18 -12
- package/dist/{chunk-W4LM3QYZ.js → chunk-HB5Y37YU.js} +8 -8
- package/dist/{chunk-E2XT3G52.js → chunk-HFMAXUHV.js} +136 -137
- package/dist/{chunk-BRBTD7RH.js → chunk-MA7YKRUP.js} +28 -18
- package/dist/{chunk-MJUDMVRU.js → chunk-MT5FJ3ZT.js} +17 -17
- package/dist/chunk-OKLQVY3Y.js +139 -0
- package/dist/{chunk-KH5UDAJ2.js → chunk-QDH5GEGY.js} +58 -54
- package/dist/{chunk-33W2TLUL.js → chunk-QID2OOMG.js} +12 -3
- package/dist/{chunk-FJSVPBKY.js → chunk-S7OXQTST.js} +17 -3
- package/dist/chunk-T7HMZEVO.js +216 -0
- package/dist/{chunk-FNYJFCGU.js → chunk-U6QTHMY6.js} +145 -256
- package/dist/{chunk-565V6JTN.js → chunk-UXQMIR3D.js} +60 -99
- package/dist/{chunk-XTPAWK7L.js → chunk-VOUV7GGB.js} +25 -47
- package/dist/{chunk-OVNLOE3Y.js → chunk-WXK43R62.js} +41 -41
- package/dist/{chunk-6V4XVKFY.js → chunk-XXDFEF72.js} +340 -335
- package/dist/{chunk-TDYQBLL5.js → chunk-ZMNSRDMH.js} +6 -6
- package/dist/dashboard.d.ts +135 -3
- package/dist/dashboard.js +848 -8
- package/dist/{document-editor-pane-DWWUTTTZ.js → document-editor-pane-TLPVRBBU.js} +3 -3
- package/dist/editor.d.ts +9 -8
- package/dist/editor.js +3 -3
- package/dist/files.js +3 -3
- package/dist/globals.css +5304 -68
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +7 -7
- package/dist/index.d.ts +4 -4
- package/dist/index.js +28 -28
- package/dist/markdown.js +1 -1
- package/dist/openui.js +5 -5
- package/dist/pages.d.ts +47 -3
- package/dist/pages.js +911 -357
- package/dist/primitives.d.ts +5 -2
- package/dist/primitives.js +10 -10
- package/dist/run.js +4 -4
- package/dist/sdk-hooks.d.ts +2 -3
- package/dist/sdk-hooks.js +5 -5
- package/dist/styles.css +5304 -68
- package/dist/template-card-BAtvcAkU.d.ts +18 -0
- package/dist/terminal.d.ts +3 -1
- package/dist/terminal.js +66 -32
- package/dist/tokens.css +701 -40
- package/dist/{usage-chart-XCoB_7Xu.d.ts → usage-chart-SSiOgeQI.d.ts} +3 -1
- package/dist/{use-pty-session-COzVkhtc.d.ts → use-pty-session-0AOuwXgq.d.ts} +2 -0
- package/dist/{index-BT_-ecpc.d.ts → variant-list-C8wx2TqF.d.ts} +17 -8
- package/dist/workspace.d.ts +1 -1
- package/dist/workspace.js +13 -13
- package/package.json +3 -1
- package/tailwind.config.cjs +3 -2
- package/dist/chunk-3HW53XTH.js +0 -228
- package/dist/chunk-OKCIKTXQ.js +0 -63
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Logo
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-OKLQVY3Y.js";
|
|
4
4
|
import {
|
|
5
5
|
Avatar,
|
|
6
6
|
AvatarFallback,
|
|
@@ -11,16 +11,16 @@ import {
|
|
|
11
11
|
DropdownMenuLabel,
|
|
12
12
|
DropdownMenuSeparator,
|
|
13
13
|
DropdownMenuTrigger
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-34A66VBG.js";
|
|
15
15
|
import {
|
|
16
16
|
Skeleton
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-66EZOYZR.js";
|
|
18
18
|
import {
|
|
19
19
|
Badge
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-ZMNSRDMH.js";
|
|
21
21
|
import {
|
|
22
22
|
Button
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-2QZ6G7NM.js";
|
|
24
24
|
import {
|
|
25
25
|
cn
|
|
26
26
|
} from "./chunk-RQHJBTEU.js";
|
|
@@ -42,9 +42,17 @@ function readStorage(key, fallback) {
|
|
|
42
42
|
return fallback;
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
+
function writeStorage(key, value) {
|
|
46
|
+
if (typeof window === "undefined") return;
|
|
47
|
+
try {
|
|
48
|
+
localStorage.setItem(key, value);
|
|
49
|
+
} catch {
|
|
50
|
+
}
|
|
51
|
+
}
|
|
45
52
|
function SidebarProvider({
|
|
46
53
|
defaultPanelOpen = true,
|
|
47
54
|
defaultMode = "projects",
|
|
55
|
+
hasPanels = true,
|
|
48
56
|
children
|
|
49
57
|
}) {
|
|
50
58
|
const [panelOpen, setPanelOpenState] = React.useState(
|
|
@@ -56,48 +64,38 @@ function SidebarProvider({
|
|
|
56
64
|
const [hidden, setHidden] = React.useState(false);
|
|
57
65
|
const setPanelOpen = React.useCallback((open) => {
|
|
58
66
|
setPanelOpenState(open);
|
|
59
|
-
|
|
67
|
+
writeStorage(PANEL_OPEN_KEY, String(open));
|
|
60
68
|
}, []);
|
|
61
69
|
const togglePanel = React.useCallback(() => {
|
|
62
70
|
setPanelOpenState((prev) => {
|
|
63
71
|
const next = !prev;
|
|
64
|
-
|
|
72
|
+
writeStorage(PANEL_OPEN_KEY, String(next));
|
|
65
73
|
return next;
|
|
66
74
|
});
|
|
67
75
|
}, []);
|
|
68
76
|
const setMode = React.useCallback((m) => {
|
|
69
77
|
setModeState(m);
|
|
70
|
-
|
|
71
|
-
}, []);
|
|
72
|
-
const switchMode = React.useCallback((m) => {
|
|
73
|
-
setPanelOpenState((prevOpen) => {
|
|
74
|
-
setModeState((prevMode) => {
|
|
75
|
-
if (prevOpen && prevMode === m) {
|
|
76
|
-
localStorage.setItem(PANEL_OPEN_KEY, "false");
|
|
77
|
-
return prevMode;
|
|
78
|
-
}
|
|
79
|
-
localStorage.setItem(PANEL_OPEN_KEY, "true");
|
|
80
|
-
localStorage.setItem(SIDEBAR_MODE_KEY, m);
|
|
81
|
-
return m;
|
|
82
|
-
});
|
|
83
|
-
return void 0;
|
|
84
|
-
});
|
|
78
|
+
writeStorage(SIDEBAR_MODE_KEY, m);
|
|
85
79
|
}, []);
|
|
86
80
|
const switchModeStable = React.useCallback((m) => {
|
|
87
81
|
setModeState((prevMode) => {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
82
|
+
if (prevMode === m) {
|
|
83
|
+
setPanelOpenState((prevOpen) => {
|
|
84
|
+
const next = !prevOpen;
|
|
85
|
+
writeStorage(PANEL_OPEN_KEY, String(next));
|
|
86
|
+
return next;
|
|
87
|
+
});
|
|
88
|
+
return prevMode;
|
|
89
|
+
}
|
|
90
|
+
setPanelOpenState(() => {
|
|
91
|
+
writeStorage(PANEL_OPEN_KEY, "true");
|
|
94
92
|
return true;
|
|
95
93
|
});
|
|
96
|
-
|
|
94
|
+
writeStorage(SIDEBAR_MODE_KEY, m);
|
|
97
95
|
return m;
|
|
98
96
|
});
|
|
99
97
|
}, []);
|
|
100
|
-
const contentMargin = hidden ? 0 : panelOpen ? SIDEBAR_TOTAL_WIDTH : SIDEBAR_RAIL_WIDTH;
|
|
98
|
+
const contentMargin = hidden ? 0 : panelOpen && hasPanels ? SIDEBAR_TOTAL_WIDTH : SIDEBAR_RAIL_WIDTH;
|
|
101
99
|
const value = React.useMemo(
|
|
102
100
|
() => ({
|
|
103
101
|
panelOpen,
|
|
@@ -108,9 +106,10 @@ function SidebarProvider({
|
|
|
108
106
|
switchMode: switchModeStable,
|
|
109
107
|
hidden,
|
|
110
108
|
setHidden,
|
|
111
|
-
contentMargin
|
|
109
|
+
contentMargin,
|
|
110
|
+
hasPanels
|
|
112
111
|
}),
|
|
113
|
-
[panelOpen, setPanelOpen, togglePanel, mode, setMode, switchModeStable, hidden, setHidden, contentMargin]
|
|
112
|
+
[panelOpen, setPanelOpen, togglePanel, mode, setMode, switchModeStable, hidden, setHidden, contentMargin, hasPanels]
|
|
114
113
|
);
|
|
115
114
|
return /* @__PURE__ */ jsx(SidebarContext.Provider, { value, children });
|
|
116
115
|
}
|
|
@@ -151,27 +150,27 @@ function LogOutIcon({ className }) {
|
|
|
151
150
|
/* @__PURE__ */ jsx2("line", { x1: "21", x2: "9", y1: "12", y2: "12" })
|
|
152
151
|
] });
|
|
153
152
|
}
|
|
154
|
-
function Sidebar({ children, className }) {
|
|
155
|
-
const { panelOpen, hidden } = useSidebar();
|
|
153
|
+
function Sidebar({ children, className, style }) {
|
|
154
|
+
const { panelOpen, hidden, hasPanels } = useSidebar();
|
|
156
155
|
return /* @__PURE__ */ jsx2(
|
|
157
156
|
"div",
|
|
158
157
|
{
|
|
159
158
|
"data-sidebar": "true",
|
|
160
159
|
className: cn(
|
|
161
|
-
"fixed inset-y-0 left-0 z-40 flex bg-
|
|
160
|
+
"fixed inset-y-0 left-0 z-40 flex bg-card/80 backdrop-blur-3xl border-r border-border transition-[transform,width] duration-200 ease-in-out shadow-sm",
|
|
162
161
|
hidden && "-translate-x-full",
|
|
163
162
|
className
|
|
164
163
|
),
|
|
165
|
-
style: { width: panelOpen ? SIDEBAR_TOTAL_WIDTH : SIDEBAR_RAIL_WIDTH },
|
|
164
|
+
style: { width: panelOpen && hasPanels ? SIDEBAR_TOTAL_WIDTH : SIDEBAR_RAIL_WIDTH, ...style },
|
|
166
165
|
children
|
|
167
166
|
}
|
|
168
167
|
);
|
|
169
168
|
}
|
|
170
169
|
function SidebarRail({ children, className }) {
|
|
171
|
-
return /* @__PURE__ */ jsx2("div", { className: cn("flex flex-col h-full w-16 shrink-0 bg-
|
|
170
|
+
return /* @__PURE__ */ jsx2("div", { className: cn("flex flex-col h-full w-16 shrink-0 bg-transparent", className), children });
|
|
172
171
|
}
|
|
173
172
|
function SidebarRailHeader({ children, className }) {
|
|
174
|
-
return /* @__PURE__ */ jsx2("div", { className: cn("flex h-14 items-center justify-center border-b border-
|
|
173
|
+
return /* @__PURE__ */ jsx2("div", { className: cn("flex h-14 items-center justify-center border-b border-border", className), children });
|
|
175
174
|
}
|
|
176
175
|
function SidebarRailNav({ children, className }) {
|
|
177
176
|
return /* @__PURE__ */ jsx2("nav", { className: cn("flex flex-col items-center gap-1 py-3 flex-1", className), children });
|
|
@@ -180,7 +179,7 @@ function SidebarRailFooter({ children, className }) {
|
|
|
180
179
|
return /* @__PURE__ */ jsx2("div", { className: cn("flex flex-col items-center gap-1 pb-3", className), children });
|
|
181
180
|
}
|
|
182
181
|
function RailSeparator({ className }) {
|
|
183
|
-
return /* @__PURE__ */ jsx2("div", { className: cn("my-2 h-px w-10 bg-[var(--
|
|
182
|
+
return /* @__PURE__ */ jsx2("div", { className: cn("my-2 h-px w-10 bg-[var(--md3-outline-variant)]", className) });
|
|
184
183
|
}
|
|
185
184
|
function RailButton({ icon: Icon2, label, isActive, badge, onClick, className }) {
|
|
186
185
|
return /* @__PURE__ */ jsxs(
|
|
@@ -190,21 +189,17 @@ function RailButton({ icon: Icon2, label, isActive, badge, onClick, className })
|
|
|
190
189
|
onClick,
|
|
191
190
|
title: label,
|
|
192
191
|
className: cn(
|
|
193
|
-
"group relative flex
|
|
192
|
+
"group relative flex items-center justify-center w-11 h-11 rounded-xl transition-all duration-200",
|
|
194
193
|
"hover:bg-[var(--accent-surface-soft)] hover:text-[var(--accent-text)]",
|
|
195
194
|
"active:scale-95",
|
|
196
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-
|
|
195
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
|
|
197
196
|
isActive && "bg-[var(--accent-surface-strong)] text-[var(--accent-text)] shadow-[0_0_12px_-2px_rgba(130,99,255,0.3)]",
|
|
198
|
-
!isActive && "text-
|
|
197
|
+
!isActive && "text-muted-foreground",
|
|
199
198
|
className
|
|
200
199
|
),
|
|
201
200
|
children: [
|
|
202
|
-
/* @__PURE__ */ jsx2(Icon2, { className: "h-
|
|
203
|
-
/* @__PURE__ */ jsx2("span", { className:
|
|
204
|
-
"text-[9px] leading-none font-medium tracking-tight truncate max-w-[44px]",
|
|
205
|
-
isActive ? "text-[var(--accent-text)]" : "text-[var(--text-dim)] group-hover:text-[var(--accent-text)]"
|
|
206
|
-
), children: label }),
|
|
207
|
-
badge !== void 0 && badge > 0 && /* @__PURE__ */ jsx2("span", { className: "absolute -top-0.5 -right-0.5 flex h-3.5 min-w-3.5 items-center justify-center rounded-full bg-[var(--brand-primary)] text-[8px] font-medium text-white px-0.5", children: badge > 99 ? "99+" : badge })
|
|
201
|
+
/* @__PURE__ */ jsx2(Icon2, { className: "h-5 w-5" }),
|
|
202
|
+
badge !== void 0 && badge > 0 && /* @__PURE__ */ jsx2("span", { className: "absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-primary text-[9px] font-bold text-[var(--md3-on-primary)] px-1 shadow-sm", children: badge > 99 ? "99+" : badge })
|
|
208
203
|
]
|
|
209
204
|
}
|
|
210
205
|
);
|
|
@@ -229,7 +224,7 @@ function SidebarPanel({ children, className }) {
|
|
|
229
224
|
"div",
|
|
230
225
|
{
|
|
231
226
|
className: cn(
|
|
232
|
-
"transition-[opacity] duration-150 h-full overflow-hidden border-l border-
|
|
227
|
+
"transition-[opacity] duration-150 h-full overflow-hidden border-l border-border bg-card/50 backdrop-blur-xl",
|
|
233
228
|
panelOpen ? "w-[260px] opacity-100" : "w-0 opacity-0 pointer-events-none",
|
|
234
229
|
className
|
|
235
230
|
),
|
|
@@ -238,7 +233,7 @@ function SidebarPanel({ children, className }) {
|
|
|
238
233
|
);
|
|
239
234
|
}
|
|
240
235
|
function SidebarPanelHeader({ children, title, className }) {
|
|
241
|
-
return /* @__PURE__ */ jsx2("div", { className: cn("flex h-14 items-center px-4 border-b border-
|
|
236
|
+
return /* @__PURE__ */ jsx2("div", { className: cn("flex h-14 items-center px-4 border-b border-border shrink-0", className), children: children ?? /* @__PURE__ */ jsx2("h2", { className: "text-sm font-semibold text-foreground", children: title }) });
|
|
242
237
|
}
|
|
243
238
|
function SidebarPanelContent({ children, className }) {
|
|
244
239
|
return /* @__PURE__ */ jsx2("div", { className: cn("flex-1 overflow-y-auto px-2 py-2", className), children });
|
|
@@ -272,7 +267,7 @@ function ProfileAvatar({
|
|
|
272
267
|
type: "button",
|
|
273
268
|
className: cn(
|
|
274
269
|
"flex items-center justify-center w-12 h-12 rounded-lg transition-colors hover:bg-[var(--accent-surface-soft)]",
|
|
275
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-
|
|
270
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
|
|
276
271
|
className
|
|
277
272
|
),
|
|
278
273
|
"aria-label": "User menu",
|
|
@@ -321,42 +316,28 @@ function ProfileAvatar({
|
|
|
321
316
|
}
|
|
322
317
|
|
|
323
318
|
// src/dashboard/cluster-status-bar.tsx
|
|
324
|
-
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
319
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
325
320
|
function ClusterStatusBar({ items, latency, className }) {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
{
|
|
329
|
-
className:
|
|
330
|
-
|
|
331
|
-
className
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
" ",
|
|
347
|
-
/* @__PURE__ */ jsx3("span", { className: "text-[var(--text-secondary)]", children: latency })
|
|
348
|
-
] }),
|
|
349
|
-
/* @__PURE__ */ jsxs2("div", { className: "flex gap-0.5 h-3 items-end", children: [
|
|
350
|
-
/* @__PURE__ */ jsx3("div", { className: "w-0.5 h-1 bg-[var(--brand-cool)]" }),
|
|
351
|
-
/* @__PURE__ */ jsx3("div", { className: "w-0.5 h-2 bg-[var(--brand-cool)]" }),
|
|
352
|
-
/* @__PURE__ */ jsx3("div", { className: "w-0.5 h-1.5 bg-[var(--brand-cool)]" }),
|
|
353
|
-
/* @__PURE__ */ jsx3("div", { className: "w-0.5 h-3 bg-[var(--brand-cool)]" }),
|
|
354
|
-
/* @__PURE__ */ jsx3("div", { className: "w-0.5 h-2.5 bg-[var(--brand-cool)]" })
|
|
355
|
-
] })
|
|
356
|
-
] })
|
|
357
|
-
]
|
|
358
|
-
}
|
|
359
|
-
);
|
|
321
|
+
if (!items?.length) return null;
|
|
322
|
+
return /* @__PURE__ */ jsx3("div", { className: cn("fixed bottom-6 left-1/2 -translate-x-1/2 z-40 w-max max-w-[90vw] animate-in slide-in-from-bottom flex justify-center", className), children: /* @__PURE__ */ jsxs2("div", { className: "glass-panel-heavy overflow-hidden rounded-full px-6 py-3 flex flex-wrap sm:flex-nowrap items-center justify-between gap-8 border-primary/20 shadow-sm backdrop-blur-2xl", children: [
|
|
323
|
+
/* @__PURE__ */ jsx3("div", { className: "flex items-center gap-6", children: items.map((item, i) => /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
|
|
324
|
+
/* @__PURE__ */ jsx3("span", { className: "text-[var(--md3-primary)] [&_svg]:h-[18px] [&_svg]:w-[18px]", children: item.icon }),
|
|
325
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex flex-col", children: [
|
|
326
|
+
/* @__PURE__ */ jsx3("span", { className: "text-[10px] text-[var(--md3-on-surface-variant)] uppercase tracking-wider font-bold", children: item.label }),
|
|
327
|
+
/* @__PURE__ */ jsx3("span", { className: cn("text-xs font-bold text-foreground", item.valueClass), children: item.value })
|
|
328
|
+
] })
|
|
329
|
+
] }, i)) }),
|
|
330
|
+
latency && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
331
|
+
/* @__PURE__ */ jsx3("div", { className: "h-6 w-px bg-border" }),
|
|
332
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-3", children: [
|
|
333
|
+
/* @__PURE__ */ jsxs2("div", { className: "relative flex h-2.5 w-2.5 items-center justify-center", children: [
|
|
334
|
+
/* @__PURE__ */ jsx3("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-green-400 opacity-75" }),
|
|
335
|
+
/* @__PURE__ */ jsx3("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-green-500" })
|
|
336
|
+
] }),
|
|
337
|
+
/* @__PURE__ */ jsx3("span", { className: "text-xs font-mono text-green-400 font-bold", children: latency })
|
|
338
|
+
] })
|
|
339
|
+
] })
|
|
340
|
+
] }) });
|
|
360
341
|
}
|
|
361
342
|
|
|
362
343
|
// src/dashboard/credit-balance.tsx
|
|
@@ -370,24 +351,24 @@ function CreditBalance({
|
|
|
370
351
|
className
|
|
371
352
|
}) {
|
|
372
353
|
const [topUpValue, setTopUpValue] = React2.useState("50.00");
|
|
373
|
-
return /* @__PURE__ */ jsxs3("div", { className: cn("bg-
|
|
354
|
+
return /* @__PURE__ */ jsxs3("div", { className: cn("bg-card p-5 rounded-xl flex flex-col justify-between border border-border", className), children: [
|
|
374
355
|
/* @__PURE__ */ jsxs3("div", { children: [
|
|
375
|
-
/* @__PURE__ */ jsx4("h3", { className: "text-sm font-semibold text-
|
|
376
|
-
/* @__PURE__ */ jsxs3("div", { className: "text-4xl font-extrabold text-
|
|
356
|
+
/* @__PURE__ */ jsx4("h3", { className: "text-sm font-semibold text-muted-foreground uppercase tracking-widest mb-2", children: "Available Credits" }),
|
|
357
|
+
/* @__PURE__ */ jsxs3("div", { className: "text-4xl font-extrabold text-primary tracking-tighter mb-2", children: [
|
|
377
358
|
"$",
|
|
378
359
|
amount.toFixed(2)
|
|
379
360
|
] }),
|
|
380
|
-
/* @__PURE__ */ jsx4("p", { className: "text-sm text-
|
|
361
|
+
/* @__PURE__ */ jsx4("p", { className: "text-sm text-muted-foreground leading-relaxed", children: description })
|
|
381
362
|
] }),
|
|
382
363
|
onTopUp && /* @__PURE__ */ jsxs3("div", { className: "space-y-2.5 mt-5", children: [
|
|
383
|
-
/* @__PURE__ */ jsxs3("div", { className: "bg-
|
|
364
|
+
/* @__PURE__ */ jsxs3("div", { className: "bg-card border border-border p-1 rounded-lg flex items-center", children: [
|
|
384
365
|
/* @__PURE__ */ jsx4(
|
|
385
366
|
"input",
|
|
386
367
|
{
|
|
387
368
|
type: "text",
|
|
388
369
|
value: `$${topUpValue}`,
|
|
389
370
|
onChange: (e) => setTopUpValue(e.target.value.replace(/[^0-9.]/g, "")),
|
|
390
|
-
className: "bg-transparent border-none text-
|
|
371
|
+
className: "bg-transparent border-none text-foreground font-mono text-lg w-full focus:ring-0 px-4 outline-none"
|
|
391
372
|
}
|
|
392
373
|
),
|
|
393
374
|
/* @__PURE__ */ jsx4(
|
|
@@ -395,7 +376,7 @@ function CreditBalance({
|
|
|
395
376
|
{
|
|
396
377
|
type: "button",
|
|
397
378
|
onClick: () => onTopUp(Number.parseFloat(topUpValue)),
|
|
398
|
-
className: "bg-[var(--accent-surface-soft)] border border-
|
|
379
|
+
className: "bg-[var(--accent-surface-soft)] border border-border text-[var(--accent-text)] px-6 py-3 rounded-md font-bold text-xs uppercase tracking-widest active:scale-95 transition-transform hover:bg-[var(--accent-surface-strong)]",
|
|
399
380
|
children: "Top Up"
|
|
400
381
|
}
|
|
401
382
|
)
|
|
@@ -408,7 +389,7 @@ function CreditBalance({
|
|
|
408
389
|
setTopUpValue(String(qa));
|
|
409
390
|
onTopUp(qa);
|
|
410
391
|
},
|
|
411
|
-
className: "flex-1 py-2 text-[10px] font-mono text-
|
|
392
|
+
className: "flex-1 py-2 text-[10px] font-mono text-muted-foreground border border-border rounded-md hover:bg-muted/50 hover:text-foreground transition-colors uppercase",
|
|
412
393
|
children: [
|
|
413
394
|
"+$",
|
|
414
395
|
qa
|
|
@@ -424,39 +405,39 @@ function CreditBalance({
|
|
|
424
405
|
import { Download, FileText } from "lucide-react";
|
|
425
406
|
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
426
407
|
var statusStyle = {
|
|
427
|
-
paid: "bg-[var(--accent-surface-soft)] text-
|
|
408
|
+
paid: "bg-[var(--accent-surface-soft)] text-primary border border-border",
|
|
428
409
|
pending: "bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)] border border-[var(--surface-warning-border)]",
|
|
429
410
|
failed: "bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)] border border-[var(--surface-danger-border)]"
|
|
430
411
|
};
|
|
431
412
|
function InvoiceTable({ invoices, onExportAll, onLoadMore, onViewInvoice, hasMore, className }) {
|
|
432
413
|
return /* @__PURE__ */ jsxs4("section", { className, children: [
|
|
433
414
|
/* @__PURE__ */ jsxs4("div", { className: "flex justify-between items-center mb-6 px-2", children: [
|
|
434
|
-
/* @__PURE__ */ jsx5("h2", { className: "text-2xl font-bold text-
|
|
435
|
-
onExportAll && /* @__PURE__ */ jsxs4("button", { type: "button", onClick: onExportAll, className: "text-[10px] font-mono text-
|
|
415
|
+
/* @__PURE__ */ jsx5("h2", { className: "text-2xl font-bold text-foreground tracking-tight", children: "Invoice History" }),
|
|
416
|
+
onExportAll && /* @__PURE__ */ jsxs4("button", { type: "button", onClick: onExportAll, className: "text-[10px] font-mono text-primary uppercase tracking-widest flex items-center gap-2 hover:underline", children: [
|
|
436
417
|
/* @__PURE__ */ jsx5(Download, { className: "h-3.5 w-3.5" }),
|
|
437
418
|
"Export All"
|
|
438
419
|
] })
|
|
439
420
|
] }),
|
|
440
|
-
/* @__PURE__ */ jsx5("div", { className: "bg-
|
|
441
|
-
/* @__PURE__ */ jsx5("thead", { children: /* @__PURE__ */ jsxs4("tr", { className: "bg-
|
|
442
|
-
/* @__PURE__ */ jsx5("th", { className: "px-6 py-4 font-mono text-[10px] text-
|
|
443
|
-
/* @__PURE__ */ jsx5("th", { className: "px-6 py-4 font-mono text-[10px] text-
|
|
444
|
-
/* @__PURE__ */ jsx5("th", { className: "px-6 py-4 font-mono text-[10px] text-
|
|
445
|
-
/* @__PURE__ */ jsx5("th", { className: "px-6 py-4 font-mono text-[10px] text-
|
|
446
|
-
/* @__PURE__ */ jsx5("th", { className: "px-6 py-4 font-mono text-[10px] text-
|
|
421
|
+
/* @__PURE__ */ jsx5("div", { className: "bg-card rounded-xl overflow-hidden border border-border", children: /* @__PURE__ */ jsxs4("table", { className: "w-full text-left border-collapse", children: [
|
|
422
|
+
/* @__PURE__ */ jsx5("thead", { children: /* @__PURE__ */ jsxs4("tr", { className: "bg-background border-b border-border", children: [
|
|
423
|
+
/* @__PURE__ */ jsx5("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Invoice ID" }),
|
|
424
|
+
/* @__PURE__ */ jsx5("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Date" }),
|
|
425
|
+
/* @__PURE__ */ jsx5("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Amount" }),
|
|
426
|
+
/* @__PURE__ */ jsx5("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Status" }),
|
|
427
|
+
/* @__PURE__ */ jsx5("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest text-right", children: "Action" })
|
|
447
428
|
] }) }),
|
|
448
|
-
/* @__PURE__ */ jsx5("tbody", { className: "divide-y divide-
|
|
449
|
-
/* @__PURE__ */ jsx5("td", { className: "px-6 py-5 font-mono text-xs text-
|
|
450
|
-
/* @__PURE__ */ jsx5("td", { className: "px-6 py-5 text-sm text-
|
|
451
|
-
/* @__PURE__ */ jsxs4("td", { className: "px-6 py-5 text-sm font-bold text-
|
|
429
|
+
/* @__PURE__ */ jsx5("tbody", { className: "divide-y divide-border", children: invoices.map((inv) => /* @__PURE__ */ jsxs4("tr", { className: "hover:bg-muted/50 transition-colors", children: [
|
|
430
|
+
/* @__PURE__ */ jsx5("td", { className: "px-6 py-5 font-mono text-xs text-foreground", children: inv.id }),
|
|
431
|
+
/* @__PURE__ */ jsx5("td", { className: "px-6 py-5 text-sm text-foreground", children: inv.date }),
|
|
432
|
+
/* @__PURE__ */ jsxs4("td", { className: "px-6 py-5 text-sm font-bold text-foreground", children: [
|
|
452
433
|
"$",
|
|
453
434
|
inv.amount.toFixed(2)
|
|
454
435
|
] }),
|
|
455
436
|
/* @__PURE__ */ jsx5("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsx5("span", { className: cn("px-2 py-1 text-[10px] font-mono rounded uppercase", statusStyle[inv.status] ?? statusStyle.paid), children: inv.status }) }),
|
|
456
|
-
/* @__PURE__ */ jsx5("td", { className: "px-6 py-5 text-right", children: /* @__PURE__ */ jsx5("button", { type: "button", onClick: () => onViewInvoice?.(inv.id), className: "text-
|
|
437
|
+
/* @__PURE__ */ jsx5("td", { className: "px-6 py-5 text-right", children: /* @__PURE__ */ jsx5("button", { type: "button", onClick: () => onViewInvoice?.(inv.id), className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ jsx5(FileText, { className: "h-4 w-4" }) }) })
|
|
457
438
|
] }, inv.id)) })
|
|
458
439
|
] }) }),
|
|
459
|
-
hasMore && onLoadMore && /* @__PURE__ */ jsx5("div", { className: "mt-6 flex justify-center", children: /* @__PURE__ */ jsx5("button", { type: "button", onClick: onLoadMore, className: "px-8 py-2 text-[10px] font-mono text-
|
|
440
|
+
hasMore && onLoadMore && /* @__PURE__ */ jsx5("div", { className: "mt-6 flex justify-center", children: /* @__PURE__ */ jsx5("button", { type: "button", onClick: onLoadMore, className: "px-8 py-2 text-[10px] font-mono text-muted-foreground border border-border rounded-full hover:bg-muted/50 transition-colors uppercase tracking-widest", children: "Load More History" }) })
|
|
460
441
|
] });
|
|
461
442
|
}
|
|
462
443
|
|
|
@@ -465,29 +446,29 @@ import { Check } from "lucide-react";
|
|
|
465
446
|
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
466
447
|
function PlanCards({ plans, className }) {
|
|
467
448
|
return /* @__PURE__ */ jsxs5("section", { className, children: [
|
|
468
|
-
/* @__PURE__ */ jsx6("h2", { className: "text-2xl font-bold text-
|
|
449
|
+
/* @__PURE__ */ jsx6("h2", { className: "text-2xl font-bold text-foreground tracking-tight mb-5 px-2", children: "Subscription Plans" }),
|
|
469
450
|
/* @__PURE__ */ jsx6("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-6", children: plans.map((plan) => /* @__PURE__ */ jsxs5(
|
|
470
451
|
"div",
|
|
471
452
|
{
|
|
472
453
|
className: cn(
|
|
473
454
|
"p-5 rounded-xl transition-all relative overflow-hidden border",
|
|
474
|
-
plan.popular ? "bg-
|
|
455
|
+
plan.popular ? "bg-muted/50 border-border" : "bg-card border-border hover:bg-muted/50 hover:border-primary/20"
|
|
475
456
|
),
|
|
476
457
|
children: [
|
|
477
|
-
plan.popular && /* @__PURE__ */ jsx6("div", { className: "absolute top-0 right-0 bg-[var(--accent-surface-soft)] border-l border-b border-
|
|
458
|
+
plan.popular && /* @__PURE__ */ jsx6("div", { className: "absolute top-0 right-0 bg-[var(--accent-surface-soft)] border-l border-b border-border px-4 py-1 text-[10px] font-bold text-[var(--accent-text)] uppercase tracking-widest rounded-bl-lg", children: "Popular" }),
|
|
478
459
|
/* @__PURE__ */ jsxs5("div", { className: "mb-4", children: [
|
|
479
|
-
/* @__PURE__ */ jsx6("div", { className: cn("text-xs font-mono uppercase tracking-widest mb-2", plan.popular ? "text-
|
|
480
|
-
/* @__PURE__ */ jsxs5("div", { className: "text-3xl font-bold text-
|
|
460
|
+
/* @__PURE__ */ jsx6("div", { className: cn("text-xs font-mono uppercase tracking-widest mb-2", plan.popular ? "text-primary" : "text-muted-foreground"), children: plan.name }),
|
|
461
|
+
/* @__PURE__ */ jsxs5("div", { className: "text-3xl font-bold text-foreground", children: [
|
|
481
462
|
"$",
|
|
482
463
|
plan.price,
|
|
483
|
-
/* @__PURE__ */ jsxs5("span", { className: "text-sm font-normal text-
|
|
464
|
+
/* @__PURE__ */ jsxs5("span", { className: "text-sm font-normal text-muted-foreground tracking-normal", children: [
|
|
484
465
|
"/",
|
|
485
466
|
plan.period ?? "mo"
|
|
486
467
|
] })
|
|
487
468
|
] })
|
|
488
469
|
] }),
|
|
489
|
-
/* @__PURE__ */ jsx6("ul", { className: "space-y-2 mb-5 text-sm text-
|
|
490
|
-
/* @__PURE__ */ jsx6(Check, { className: "h-3.5 w-3.5 text-
|
|
470
|
+
/* @__PURE__ */ jsx6("ul", { className: "space-y-2 mb-5 text-sm text-muted-foreground", children: plan.features.map((f, i) => /* @__PURE__ */ jsxs5("li", { className: "flex items-center gap-2", children: [
|
|
471
|
+
/* @__PURE__ */ jsx6(Check, { className: "h-3.5 w-3.5 text-primary shrink-0" }),
|
|
491
472
|
f.text
|
|
492
473
|
] }, i)) }),
|
|
493
474
|
/* @__PURE__ */ jsx6(
|
|
@@ -497,7 +478,7 @@ function PlanCards({ plans, className }) {
|
|
|
497
478
|
onClick: () => plan.onSelect?.(plan.id),
|
|
498
479
|
className: cn(
|
|
499
480
|
"w-full py-3 rounded-lg text-xs font-bold uppercase tracking-widest transition-all border",
|
|
500
|
-
plan.current ? "border-
|
|
481
|
+
plan.current ? "border-border text-muted-foreground hover:border-primary/20 hover:text-foreground" : plan.popular ? "bg-[var(--accent-surface-soft)] border-border text-[var(--accent-text)] hover:bg-[var(--accent-surface-strong)] active:scale-95 transition-transform" : "border-border text-foreground hover:border-primary/20 hover:text-primary"
|
|
501
482
|
),
|
|
502
483
|
children: plan.ctaLabel ?? (plan.current ? "Current Plan" : "Upgrade Now")
|
|
503
484
|
}
|
|
@@ -512,7 +493,7 @@ function PlanCards({ plans, className }) {
|
|
|
512
493
|
// src/dashboard/dashboard-layout.tsx
|
|
513
494
|
import * as React3 from "react";
|
|
514
495
|
import { Plus, Bell } from "lucide-react";
|
|
515
|
-
import { Fragment as
|
|
496
|
+
import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
516
497
|
function SettingsIconSmall({ className }) {
|
|
517
498
|
return /* @__PURE__ */ jsxs6("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
|
|
518
499
|
/* @__PURE__ */ jsx7("title", { children: "Settings" }),
|
|
@@ -569,13 +550,13 @@ function DashboardLayoutInner({
|
|
|
569
550
|
}) {
|
|
570
551
|
const Link = LinkComponent;
|
|
571
552
|
const [mobileMenuOpen, setMobileMenuOpen] = React3.useState(false);
|
|
572
|
-
const { contentMargin, hidden, mode } = useSidebar();
|
|
553
|
+
const { contentMargin, hidden, mode, hasPanels, panelOpen } = useSidebar();
|
|
573
554
|
const modeSet = React3.useMemo(() => new Set(modeItems), [modeItems]);
|
|
574
555
|
const sidebarUser = user ? { email: user.email, name: user.name, tier: user.tier, avatarUrl: user.avatarUrl } : void 0;
|
|
575
556
|
const activePanel = panels.find((p) => p.mode === mode);
|
|
576
|
-
const sidebarContent = /* @__PURE__ */ jsxs6(
|
|
557
|
+
const sidebarContent = /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
577
558
|
/* @__PURE__ */ jsxs6(SidebarRail, { children: [
|
|
578
|
-
/* @__PURE__ */ jsx7(SidebarRailHeader, { children: /* @__PURE__ */ jsx7(Link, { href: "/", to: "/", className: "p-1 rounded-md transition-colors hover:bg-
|
|
559
|
+
/* @__PURE__ */ jsx7(SidebarRailHeader, { children: /* @__PURE__ */ jsx7(Link, { href: "/", to: "/", className: "p-1 rounded-md transition-colors hover:bg-muted/50", children: /* @__PURE__ */ jsx7(Logo, { variant, size: "sm", iconOnly: true }) }) }),
|
|
579
560
|
/* @__PURE__ */ jsx7(SidebarRailNav, { children: navItems.map((item, i) => {
|
|
580
561
|
const isMode = modeSet.has(item.id);
|
|
581
562
|
const prevIsMode = i > 0 && modeSet.has(navItems[i - 1].id);
|
|
@@ -623,11 +604,11 @@ function DashboardLayoutInner({
|
|
|
623
604
|
/* @__PURE__ */ jsx7(SidebarPanelContent, { children: activePanel?.content })
|
|
624
605
|
] })
|
|
625
606
|
] });
|
|
626
|
-
return /* @__PURE__ */ jsxs6("div", { className: cn("min-h-screen bg-
|
|
607
|
+
return /* @__PURE__ */ jsxs6("div", { className: cn("min-h-screen bg-background text-foreground", className), children: [
|
|
627
608
|
/* @__PURE__ */ jsxs6(
|
|
628
609
|
"nav",
|
|
629
610
|
{
|
|
630
|
-
className: "fixed top-0 z-50 bg-
|
|
611
|
+
className: "fixed top-0 z-50 bg-card/80 backdrop-blur-3xl border-b border-border flex justify-between items-center px-8 h-14 font-sans text-[13px] tracking-tight transition-[left,width] duration-200 ease-in-out shadow-sm",
|
|
631
612
|
style: {
|
|
632
613
|
left: hidden ? 0 : contentMargin,
|
|
633
614
|
width: hidden ? "100%" : `calc(100% - ${contentMargin}px)`
|
|
@@ -640,7 +621,7 @@ function DashboardLayoutInner({
|
|
|
640
621
|
to: link.href,
|
|
641
622
|
className: cn(
|
|
642
623
|
"transition-all duration-300 px-2 py-1 rounded",
|
|
643
|
-
activeTopNavHref === link.href ? "text-
|
|
624
|
+
activeTopNavHref === link.href ? "text-foreground border-b-2 border-primary pb-1" : "text-muted-foreground hover:text-foreground hover:bg-muted/50"
|
|
644
625
|
),
|
|
645
626
|
children: link.label
|
|
646
627
|
},
|
|
@@ -652,21 +633,21 @@ function DashboardLayoutInner({
|
|
|
652
633
|
{
|
|
653
634
|
type: "button",
|
|
654
635
|
onClick: onNewSandbox,
|
|
655
|
-
className: "hidden md:flex items-center gap-2 bg-[var(--accent-surface-soft)] border border-
|
|
636
|
+
className: "hidden md:flex items-center gap-2 bg-[var(--accent-surface-soft)] border border-border text-[var(--accent-text)] px-4 py-2 rounded-lg font-bold hover:bg-[var(--accent-surface-strong)] transition-all active:scale-95 text-xs",
|
|
656
637
|
children: [
|
|
657
638
|
/* @__PURE__ */ jsx7(Plus, { className: "h-3.5 w-3.5" }),
|
|
658
639
|
"New Sandbox"
|
|
659
640
|
]
|
|
660
641
|
}
|
|
661
642
|
),
|
|
662
|
-
/* @__PURE__ */ jsx7("button", { type: "button", className: "text-
|
|
643
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: "text-muted-foreground hover:text-foreground transition-colors p-2 rounded-lg hover:bg-muted/50", children: /* @__PURE__ */ jsx7(Bell, { className: "h-4 w-4" }) })
|
|
663
644
|
] }),
|
|
664
645
|
/* @__PURE__ */ jsx7(
|
|
665
646
|
"button",
|
|
666
647
|
{
|
|
667
648
|
type: "button",
|
|
668
649
|
onClick: () => setMobileMenuOpen(!mobileMenuOpen),
|
|
669
|
-
className: "rounded-md p-2 hover:bg-
|
|
650
|
+
className: "rounded-md p-2 hover:bg-muted/50 lg:hidden",
|
|
670
651
|
"aria-label": mobileMenuOpen ? "Close menu" : "Open menu",
|
|
671
652
|
"aria-expanded": mobileMenuOpen,
|
|
672
653
|
children: mobileMenuOpen ? /* @__PURE__ */ jsx7(XIcon, { className: "h-6 w-6" }) : /* @__PURE__ */ jsx7(MenuIcon, { className: "h-6 w-6" })
|
|
@@ -680,10 +661,10 @@ function DashboardLayoutInner({
|
|
|
680
661
|
"aside",
|
|
681
662
|
{
|
|
682
663
|
className: cn(
|
|
683
|
-
"fixed top-14 bottom-0 left-0 z-30 flex bg-
|
|
664
|
+
"fixed top-14 bottom-0 left-0 z-30 flex bg-background transition-transform duration-200 lg:hidden",
|
|
684
665
|
mobileMenuOpen ? "translate-x-0" : "-translate-x-full"
|
|
685
666
|
),
|
|
686
|
-
style: { width: SIDEBAR_TOTAL_WIDTH },
|
|
667
|
+
style: { width: panelOpen && hasPanels ? SIDEBAR_TOTAL_WIDTH : SIDEBAR_RAIL_WIDTH },
|
|
687
668
|
children: sidebarContent
|
|
688
669
|
}
|
|
689
670
|
),
|
|
@@ -694,7 +675,7 @@ function DashboardLayoutInner({
|
|
|
694
675
|
] });
|
|
695
676
|
}
|
|
696
677
|
function DashboardLayout({ defaultPanelOpen, defaultMode, ...props }) {
|
|
697
|
-
return /* @__PURE__ */ jsx7(SidebarProvider, { defaultPanelOpen, defaultMode, children: /* @__PURE__ */ jsx7(DashboardLayoutInner, { ...props }) });
|
|
678
|
+
return /* @__PURE__ */ jsx7(SidebarProvider, { defaultPanelOpen, defaultMode, hasPanels: (props.panels?.length ?? 0) > 0, children: /* @__PURE__ */ jsx7(DashboardLayoutInner, { defaultPanelOpen, defaultMode, ...props }) });
|
|
698
679
|
}
|
|
699
680
|
|
|
700
681
|
// src/dashboard/resource-meter.tsx
|
|
@@ -702,164 +683,186 @@ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
|
702
683
|
function getBarColor(percent) {
|
|
703
684
|
if (percent >= 90) return "bg-[var(--code-error)]";
|
|
704
685
|
if (percent >= 70) return "bg-[var(--surface-warning-text)]";
|
|
705
|
-
return "bg-
|
|
686
|
+
return "bg-primary";
|
|
706
687
|
}
|
|
707
688
|
function ResourceMeter({ label, value, max = 100, unit, icon, className }) {
|
|
708
689
|
const percent = max > 0 ? Math.min(value / max * 100, 100) : 0;
|
|
709
690
|
const barColor = getBarColor(percent);
|
|
710
691
|
return /* @__PURE__ */ jsxs7("div", { className: cn("flex items-center gap-3", className), children: [
|
|
711
|
-
/* @__PURE__ */ jsxs7("span", { className: "flex shrink-0 items-center gap-1 text-[10px] font-mono text-
|
|
692
|
+
/* @__PURE__ */ jsxs7("span", { className: "flex shrink-0 items-center gap-1 text-[10px] font-mono text-muted-foreground uppercase tracking-wide", children: [
|
|
712
693
|
icon,
|
|
713
694
|
label
|
|
714
695
|
] }),
|
|
715
|
-
/* @__PURE__ */ jsx8("div", { className: "h-1.5 min-w-0 flex-1 bg-
|
|
696
|
+
/* @__PURE__ */ jsx8("div", { className: "h-1.5 min-w-0 flex-1 bg-card rounded-full overflow-hidden", children: /* @__PURE__ */ jsx8(
|
|
716
697
|
"div",
|
|
717
698
|
{
|
|
718
699
|
className: cn("h-full rounded-full transition-all duration-500", barColor),
|
|
719
700
|
style: { width: `${percent}%` }
|
|
720
701
|
}
|
|
721
702
|
) }),
|
|
722
|
-
/* @__PURE__ */ jsx8("span", { className: "shrink-0 text-[10px] font-mono tabular-nums text-
|
|
703
|
+
/* @__PURE__ */ jsx8("span", { className: "shrink-0 text-[10px] font-mono tabular-nums text-muted-foreground", children: unit ? `${value}${unit}/${max}${unit}` : `${Math.round(percent)}%` })
|
|
723
704
|
] });
|
|
724
705
|
}
|
|
725
706
|
|
|
726
707
|
// src/dashboard/sandbox-card.tsx
|
|
727
|
-
import {
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
708
|
+
import {
|
|
709
|
+
MoreVertical,
|
|
710
|
+
PowerOff,
|
|
711
|
+
Power,
|
|
712
|
+
Copy,
|
|
713
|
+
Clock,
|
|
714
|
+
Activity,
|
|
715
|
+
BarChart2,
|
|
716
|
+
Trash2,
|
|
717
|
+
Terminal,
|
|
718
|
+
Code2,
|
|
719
|
+
Network,
|
|
720
|
+
Play,
|
|
721
|
+
Plus as Plus2
|
|
722
|
+
} from "lucide-react";
|
|
723
|
+
import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
724
|
+
function SandboxCard({
|
|
725
|
+
sandbox,
|
|
726
|
+
onOpenIDE,
|
|
727
|
+
onOpenTerminal,
|
|
728
|
+
onWake,
|
|
729
|
+
onRestore,
|
|
730
|
+
onDelete,
|
|
731
|
+
onStop,
|
|
732
|
+
onResume,
|
|
733
|
+
onFork,
|
|
734
|
+
onKeepAlive,
|
|
735
|
+
onUsage,
|
|
736
|
+
onHealth,
|
|
737
|
+
className
|
|
738
|
+
}) {
|
|
739
|
+
const isRunning = sandbox.status === "running";
|
|
740
|
+
const isTransitioning = sandbox.status === "provisioning" || sandbox.status === "creating";
|
|
741
|
+
const isStopped = !isRunning && !isTransitioning;
|
|
742
|
+
return /* @__PURE__ */ jsxs8("div", { className: cn(
|
|
743
|
+
"group relative glass-panel flex flex-col justify-between overflow-hidden rounded-3xl p-6 transition-all duration-500 hover:-translate-y-1 hover:shadow-2xl hover:shadow-[var(--md3-primary)]/10",
|
|
744
|
+
isRunning ? "border-[var(--md3-primary)]/30 glow-primary" : "border-border",
|
|
745
|
+
className
|
|
746
|
+
), children: [
|
|
747
|
+
isRunning && /* @__PURE__ */ jsx9("div", { className: "absolute -top-20 -right-20 h-40 w-40 rounded-full bg-[var(--md3-primary)]/20 blur-[60px] pointer-events-none" }),
|
|
748
|
+
/* @__PURE__ */ jsxs8("div", { className: "relative z-10 flex items-start justify-between", children: [
|
|
749
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
750
|
+
/* @__PURE__ */ jsxs8("h3", { className: "flex items-center gap-2 font-headline text-xl font-bold tracking-tight text-foreground", children: [
|
|
751
|
+
sandbox.name,
|
|
752
|
+
isRunning && /* @__PURE__ */ jsxs8("span", { className: "relative flex h-2.5 w-2.5", children: [
|
|
753
|
+
/* @__PURE__ */ jsx9("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-green-400 opacity-75" }),
|
|
754
|
+
/* @__PURE__ */ jsx9("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-green-500" })
|
|
767
755
|
] })
|
|
768
|
-
] }) }),
|
|
769
|
-
isProvisioning ? /* @__PURE__ */ jsxs8("div", { className: "mb-5 mt-2", children: [
|
|
770
|
-
/* @__PURE__ */ jsxs8("p", { className: "text-[10px] font-bold font-mono text-[var(--brand-cool)] mb-2 uppercase tracking-widest flex items-center gap-2 animate-pulse", children: [
|
|
771
|
-
/* @__PURE__ */ jsx9(RefreshCw, { className: "h-3 w-3 animate-spin" }),
|
|
772
|
-
sandbox.provisioningMessage ?? "Initializing..."
|
|
773
|
-
] }),
|
|
774
|
-
/* @__PURE__ */ jsx9("div", { className: "h-1.5 w-full bg-[var(--depth-1)] rounded-full overflow-hidden", children: /* @__PURE__ */ jsx9(
|
|
775
|
-
"div",
|
|
776
|
-
{
|
|
777
|
-
className: "h-full bg-[var(--brand-cool)] transition-all duration-500",
|
|
778
|
-
style: { width: `${sandbox.provisioningPercent ?? 50}%` }
|
|
779
|
-
}
|
|
780
|
-
) })
|
|
781
|
-
] }) : !isArchived ? /* @__PURE__ */ jsxs8("div", { className: cn("space-y-4 mb-5", !isActive && "opacity-35"), children: [
|
|
782
|
-
/* @__PURE__ */ jsx9(ResourceMeter, { label: "CPU", icon: /* @__PURE__ */ jsx9(Cpu, { className: "h-3 w-3" }), value: sandbox.cpuPercent ?? 0 }),
|
|
783
|
-
/* @__PURE__ */ jsx9(
|
|
784
|
-
ResourceMeter,
|
|
785
|
-
{
|
|
786
|
-
label: "RAM",
|
|
787
|
-
icon: /* @__PURE__ */ jsx9(Database, { className: "h-3 w-3" }),
|
|
788
|
-
value: sandbox.ramUsed ?? 0,
|
|
789
|
-
max: sandbox.ramTotal ?? 1,
|
|
790
|
-
unit: "GB"
|
|
791
|
-
}
|
|
792
|
-
)
|
|
793
|
-
] }) : /* @__PURE__ */ jsx9("div", { className: "mb-4", children: sandbox.archivedAt && /* @__PURE__ */ jsx9("p", { className: "text-[var(--text-muted)] font-mono text-[10px]", children: sandbox.archivedAt }) }),
|
|
794
|
-
isActive && /* @__PURE__ */ jsxs8("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
795
|
-
/* @__PURE__ */ jsxs8(
|
|
796
|
-
"button",
|
|
797
|
-
{
|
|
798
|
-
type: "button",
|
|
799
|
-
onClick: () => onOpenIDE?.(sandbox.id),
|
|
800
|
-
className: "flex items-center justify-center gap-2 py-2 bg-[var(--accent-surface-soft)] hover:bg-[var(--accent-surface-strong)] text-[var(--accent-text)] rounded-lg transition-all text-xs font-semibold border border-[var(--border-accent)]",
|
|
801
|
-
children: [
|
|
802
|
-
/* @__PURE__ */ jsx9(ExternalLink, { className: "h-3.5 w-3.5" }),
|
|
803
|
-
"Open IDE"
|
|
804
|
-
]
|
|
805
|
-
}
|
|
806
|
-
),
|
|
807
|
-
/* @__PURE__ */ jsxs8(
|
|
808
|
-
"button",
|
|
809
|
-
{
|
|
810
|
-
type: "button",
|
|
811
|
-
onClick: () => onOpenTerminal?.(sandbox.id),
|
|
812
|
-
className: "flex items-center justify-center gap-2 py-2 bg-[var(--depth-3)] hover:bg-[var(--depth-4)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] rounded-lg transition-all text-xs font-semibold border border-[var(--border-subtle)]",
|
|
813
|
-
children: [
|
|
814
|
-
/* @__PURE__ */ jsx9(Terminal, { className: "h-3.5 w-3.5" }),
|
|
815
|
-
"Terminal"
|
|
816
|
-
]
|
|
817
|
-
}
|
|
818
|
-
)
|
|
819
756
|
] }),
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
onClick: () => onWake?.(sandbox.id),
|
|
825
|
-
className: "w-full flex items-center justify-center gap-2 py-2.5 bg-[var(--accent-surface-soft)] text-[var(--brand-cool)] hover:bg-[var(--accent-surface-strong)] rounded-lg transition-all text-xs font-bold border border-[var(--border-accent)]",
|
|
826
|
-
children: [
|
|
827
|
-
/* @__PURE__ */ jsx9(Power, { className: "h-3.5 w-3.5" }),
|
|
828
|
-
"Wake Sandbox"
|
|
829
|
-
]
|
|
830
|
-
}
|
|
831
|
-
),
|
|
832
|
-
isProvisioning && /* @__PURE__ */ jsx9(
|
|
757
|
+
/* @__PURE__ */ jsx9("p", { className: "font-mono text-[10px] tracking-wider text-[var(--md3-on-surface-variant)] mt-1 uppercase font-bold", children: sandbox.nodeId || "Unknown Node" })
|
|
758
|
+
] }),
|
|
759
|
+
/* @__PURE__ */ jsx9("div", { className: "flex items-center gap-1 z-50", children: /* @__PURE__ */ jsxs8(DropdownMenu, { children: [
|
|
760
|
+
/* @__PURE__ */ jsx9(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx9(
|
|
833
761
|
"button",
|
|
834
762
|
{
|
|
835
763
|
type: "button",
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
children: "
|
|
764
|
+
className: "rounded-full flex items-center justify-center p-2 text-[var(--md3-on-surface-variant)] transition-colors hover:bg-muted hover:text-foreground shrink-0 outline-none",
|
|
765
|
+
"aria-label": "Sandbox options",
|
|
766
|
+
children: /* @__PURE__ */ jsx9(MoreVertical, { className: "h-5 w-5" })
|
|
839
767
|
}
|
|
840
|
-
),
|
|
841
|
-
|
|
842
|
-
|
|
768
|
+
) }),
|
|
769
|
+
/* @__PURE__ */ jsxs8(DropdownMenuContent, { align: "end", className: "glass-panel-heavy border-[var(--md3-outline-variant)] min-w-[180px]", children: [
|
|
770
|
+
isRunning && /* @__PURE__ */ jsxs8(Fragment5, { children: [
|
|
771
|
+
onStop && /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onStop(sandbox.id), children: [
|
|
772
|
+
/* @__PURE__ */ jsx9(PowerOff, { className: "mr-2 h-4 w-4" }),
|
|
773
|
+
" Stop Sandbox"
|
|
774
|
+
] }),
|
|
775
|
+
onKeepAlive && /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onKeepAlive(sandbox.id), children: [
|
|
776
|
+
/* @__PURE__ */ jsx9(Clock, { className: "mr-2 h-4 w-4" }),
|
|
777
|
+
" Keep Alive"
|
|
778
|
+
] }),
|
|
779
|
+
/* @__PURE__ */ jsx9(DropdownMenuSeparator, { className: "bg-[var(--md3-outline-variant)]" }),
|
|
780
|
+
onUsage && /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onUsage(sandbox.id), children: [
|
|
781
|
+
/* @__PURE__ */ jsx9(BarChart2, { className: "mr-2 h-4 w-4" }),
|
|
782
|
+
" View Usage"
|
|
783
|
+
] }),
|
|
784
|
+
onHealth && /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onHealth(sandbox.id), children: [
|
|
785
|
+
/* @__PURE__ */ jsx9(Activity, { className: "mr-2 h-4 w-4" }),
|
|
786
|
+
" Health Check"
|
|
787
|
+
] }),
|
|
788
|
+
/* @__PURE__ */ jsx9(DropdownMenuSeparator, { className: "bg-[var(--md3-outline-variant)]" }),
|
|
789
|
+
onFork && /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onFork(sandbox.id), children: [
|
|
790
|
+
/* @__PURE__ */ jsx9(Copy, { className: "mr-2 h-4 w-4" }),
|
|
791
|
+
" Fork Sandbox"
|
|
792
|
+
] }),
|
|
793
|
+
/* @__PURE__ */ jsx9(DropdownMenuSeparator, { className: "bg-[var(--md3-outline-variant)]" })
|
|
794
|
+
] }),
|
|
795
|
+
isStopped && /* @__PURE__ */ jsxs8(Fragment5, { children: [
|
|
796
|
+
onResume && /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onResume(sandbox.id), children: [
|
|
797
|
+
/* @__PURE__ */ jsx9(Power, { className: "mr-2 h-4 w-4" }),
|
|
798
|
+
" Resume Sandbox"
|
|
799
|
+
] }),
|
|
800
|
+
onFork && /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onFork(sandbox.id), children: [
|
|
801
|
+
/* @__PURE__ */ jsx9(Copy, { className: "mr-2 h-4 w-4" }),
|
|
802
|
+
" Fork Sandbox"
|
|
803
|
+
] }),
|
|
804
|
+
/* @__PURE__ */ jsx9(DropdownMenuSeparator, { className: "bg-[var(--md3-outline-variant)]" })
|
|
805
|
+
] }),
|
|
806
|
+
onDelete && /* @__PURE__ */ jsxs8(DropdownMenuItem, { className: "text-red-400 focus:bg-red-500/10 focus:text-red-300", onClick: () => onDelete(sandbox.id), children: [
|
|
807
|
+
/* @__PURE__ */ jsx9(Trash2, { className: "mr-2 h-4 w-4" }),
|
|
808
|
+
" Delete Sandbox"
|
|
809
|
+
] })
|
|
810
|
+
] })
|
|
811
|
+
] }) })
|
|
812
|
+
] }),
|
|
813
|
+
/* @__PURE__ */ jsxs8("div", { className: "relative z-10 my-8", children: [
|
|
814
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3 bg-muted/50 border border-border rounded-2xl p-4", children: [
|
|
815
|
+
/* @__PURE__ */ jsx9("div", { className: cn("flex h-12 w-12 items-center justify-center rounded-xl", isRunning ? "bg-[var(--md3-primary)]/20" : "bg-white/5"), children: sandbox.imageIcon ? sandbox.imageIcon : sandbox.image?.includes("node") ? /* @__PURE__ */ jsx9(Code2, { className: cn("h-6 w-6", isRunning ? "text-[var(--md3-primary)]" : "text-[var(--md3-on-surface-variant)]") }) : /* @__PURE__ */ jsx9(Terminal, { className: cn("h-6 w-6", isRunning ? "text-[var(--md3-primary)]" : "text-[var(--md3-on-surface-variant)]") }) }),
|
|
816
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex flex-col", children: [
|
|
817
|
+
/* @__PURE__ */ jsx9("span", { className: "text-[10px] text-[var(--md3-on-surface-variant)] uppercase tracking-widest font-bold", children: "Environment" }),
|
|
818
|
+
/* @__PURE__ */ jsx9("span", { className: "text-sm font-medium text-foreground font-mono mt-0.5", children: sandbox.image || "Universal" })
|
|
819
|
+
] })
|
|
820
|
+
] }),
|
|
821
|
+
isTransitioning && /* @__PURE__ */ jsxs8("div", { className: "mt-4 animate-in", children: [
|
|
822
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex justify-between text-xs text-[var(--md3-primary)] font-medium mb-1", children: [
|
|
823
|
+
/* @__PURE__ */ jsx9("span", { children: sandbox.provisioningMessage || "Starting..." }),
|
|
824
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
825
|
+
sandbox.provisioningPercent || 0,
|
|
826
|
+
"%"
|
|
827
|
+
] })
|
|
828
|
+
] }),
|
|
829
|
+
/* @__PURE__ */ jsx9("div", { className: "h-1.5 w-full overflow-hidden rounded-full bg-white/10", children: /* @__PURE__ */ jsx9(
|
|
830
|
+
"div",
|
|
843
831
|
{
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
className: "w-full py-2 bg-[var(--depth-3)] hover:bg-[var(--depth-4)] text-[var(--text-muted)] hover:text-[var(--text-primary)] rounded-lg transition-all text-xs font-semibold border border-[var(--border-subtle)]",
|
|
847
|
-
children: "Restore Sandbox"
|
|
832
|
+
className: "h-full bg-gradient-to-r from-[var(--md3-primary)] to-[#ada3ff] transition-all duration-500 rounded-full",
|
|
833
|
+
style: { width: `${sandbox.provisioningPercent || 5}%` }
|
|
848
834
|
}
|
|
835
|
+
) })
|
|
836
|
+
] })
|
|
837
|
+
] }),
|
|
838
|
+
/* @__PURE__ */ jsx9("div", { className: "relative z-10 flex items-center gap-3 border-t border-[var(--md3-outline-variant)] pt-4", children: isRunning ? /* @__PURE__ */ jsxs8(
|
|
839
|
+
"button",
|
|
840
|
+
{
|
|
841
|
+
type: "button",
|
|
842
|
+
onClick: () => onOpenIDE?.(sandbox.id),
|
|
843
|
+
className: "flex w-full items-center justify-center gap-2 rounded-xl bg-[var(--md3-primary)]/20 px-4 py-2.5 font-bold text-sm text-[var(--md3-primary)] shadow-[0_0_15px_rgba(173,163,255,0.1)] transition-all hover:bg-[var(--md3-primary)] hover:text-primary-foreground hover:shadow-[var(--shadow-glow)] active:scale-95 border border-[var(--md3-primary)]/30",
|
|
844
|
+
children: [
|
|
845
|
+
/* @__PURE__ */ jsx9(Network, { className: "h-4 w-4" }),
|
|
846
|
+
"Connect Session"
|
|
847
|
+
]
|
|
848
|
+
}
|
|
849
|
+
) : /* @__PURE__ */ jsxs8(
|
|
850
|
+
"button",
|
|
851
|
+
{
|
|
852
|
+
type: "button",
|
|
853
|
+
onClick: () => onWake?.(sandbox.id),
|
|
854
|
+
disabled: isTransitioning,
|
|
855
|
+
className: cn(
|
|
856
|
+
"flex flex-1 items-center justify-center gap-2 rounded-xl px-4 py-2.5 font-bold text-sm transition-all border",
|
|
857
|
+
isTransitioning ? "bg-muted/30 text-[var(--md3-on-surface-variant)] cursor-not-allowed border-border" : "bg-[var(--md3-primary)]/10 text-[var(--md3-primary)] hover:bg-[var(--md3-primary)] hover:text-foreground shadow-[0_0_15px_rgba(173,163,255,0.1)] hover:shadow-[0_0_20px_rgba(173,163,255,0.4)] active:scale-95 border-[var(--md3-primary)]/30"
|
|
849
858
|
),
|
|
850
|
-
|
|
851
|
-
"
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
children: /* @__PURE__ */ jsx9(Trash2, { className: "h-3.5 w-3.5" })
|
|
858
|
-
}
|
|
859
|
-
)
|
|
860
|
-
]
|
|
861
|
-
}
|
|
862
|
-
);
|
|
859
|
+
children: [
|
|
860
|
+
/* @__PURE__ */ jsx9(Play, { className: "h-4 w-4" }),
|
|
861
|
+
isTransitioning ? "Starting..." : "Wake Sandbox"
|
|
862
|
+
]
|
|
863
|
+
}
|
|
864
|
+
) })
|
|
865
|
+
] });
|
|
863
866
|
}
|
|
864
867
|
function NewSandboxCard({ onClick, className }) {
|
|
865
868
|
return /* @__PURE__ */ jsxs8(
|
|
@@ -868,39 +871,41 @@ function NewSandboxCard({ onClick, className }) {
|
|
|
868
871
|
type: "button",
|
|
869
872
|
onClick,
|
|
870
873
|
className: cn(
|
|
871
|
-
"border-2 border-dashed border-
|
|
874
|
+
"relative border-2 border-dashed border-border rounded-xl p-5 flex flex-col items-center justify-center text-center group cursor-pointer hover:border-[var(--border-accent)] hover:bg-[var(--accent-surface-soft)] transition-all duration-300 w-full min-h-[160px]",
|
|
872
875
|
className
|
|
873
876
|
),
|
|
874
877
|
children: [
|
|
875
|
-
/* @__PURE__ */ jsx9("div", { className: "
|
|
876
|
-
/* @__PURE__ */ jsx9("
|
|
877
|
-
/* @__PURE__ */ jsx9("
|
|
878
|
+
/* @__PURE__ */ jsx9("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_center,rgba(155,140,255,0.1)_0,transparent_100%)] opacity-0 transition-opacity duration-300 group-hover:opacity-100" }),
|
|
879
|
+
/* @__PURE__ */ jsx9("div", { className: "flex h-16 w-16 items-center justify-center rounded-3xl bg-[var(--md3-primary)]/20 text-[var(--md3-primary)] shadow-[0_0_20px_rgba(155,140,255,0.2)] transition-transform duration-300 group-hover:scale-110 group-hover:shadow-[0_0_30px_rgba(155,140,255,0.4)]", children: /* @__PURE__ */ jsx9(Plus2, { className: "h-8 w-8" }) }),
|
|
880
|
+
/* @__PURE__ */ jsx9("span", { className: "mt-6 font-headline text-xl font-bold text-foreground tracking-tight", children: "New Sandbox" }),
|
|
881
|
+
/* @__PURE__ */ jsx9("span", { className: "mt-2 text-sm text-[var(--md3-primary)] font-medium", children: "Deploy a new isolated environment" })
|
|
878
882
|
]
|
|
879
883
|
}
|
|
880
884
|
);
|
|
881
885
|
}
|
|
882
886
|
|
|
883
887
|
// src/dashboard/sandbox-table.tsx
|
|
884
|
-
import { Terminal as Terminal2, Code2, Key, Trash2 as Trash22, RefreshCw
|
|
885
|
-
import { Fragment as
|
|
888
|
+
import { Terminal as Terminal2, Code2 as Code22, Key, Trash2 as Trash22, RefreshCw, ChevronLeft, ChevronRight } from "lucide-react";
|
|
889
|
+
import { Fragment as Fragment6, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
886
890
|
var statusColors = {
|
|
887
891
|
running: { dot: "bg-[var(--code-success)] animate-pulse", text: "text-[var(--code-success)]", bar: "bg-[var(--code-success)]" },
|
|
888
|
-
hibernating: { dot: "bg-
|
|
889
|
-
provisioning: { dot: "bg-
|
|
890
|
-
|
|
892
|
+
hibernating: { dot: "bg-muted-foreground", text: "text-muted-foreground", bar: "bg-muted-foreground" },
|
|
893
|
+
provisioning: { dot: "bg-primary animate-pulse", text: "text-primary", bar: "bg-primary" },
|
|
894
|
+
creating: { dot: "bg-primary animate-pulse", text: "text-primary", bar: "bg-primary" },
|
|
895
|
+
stopped: { dot: "bg-muted-foreground", text: "text-foreground", bar: "bg-muted-foreground" },
|
|
891
896
|
failed: { dot: "bg-[var(--code-error)]", text: "text-[var(--code-error)]", bar: "bg-[var(--code-error)]" },
|
|
892
|
-
archived: { dot: "bg-
|
|
897
|
+
archived: { dot: "bg-border", text: "text-muted-foreground", bar: "bg-border" }
|
|
893
898
|
};
|
|
894
899
|
function MiniMeter({ label, percent, className }) {
|
|
895
900
|
return /* @__PURE__ */ jsxs9("div", { className: cn("space-y-1", className), children: [
|
|
896
|
-
/* @__PURE__ */ jsxs9("div", { className: "flex justify-between text-[10px] font-mono text-
|
|
901
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex justify-between text-[10px] font-mono text-muted-foreground", children: [
|
|
897
902
|
/* @__PURE__ */ jsx10("span", { className: "font-bold", children: label }),
|
|
898
|
-
/* @__PURE__ */ jsxs9("span", { className: "text-
|
|
903
|
+
/* @__PURE__ */ jsxs9("span", { className: "text-primary", children: [
|
|
899
904
|
percent,
|
|
900
905
|
"%"
|
|
901
906
|
] })
|
|
902
907
|
] }),
|
|
903
|
-
/* @__PURE__ */ jsx10("div", { className: "h-1.5 w-full bg-
|
|
908
|
+
/* @__PURE__ */ jsx10("div", { className: "h-1.5 w-full bg-background rounded-full overflow-hidden", children: /* @__PURE__ */ jsx10("div", { className: "h-full bg-primary rounded-full", style: { width: `${percent}%` } }) })
|
|
904
909
|
] });
|
|
905
910
|
}
|
|
906
911
|
function SandboxTable({
|
|
@@ -920,56 +925,56 @@ function SandboxTable({
|
|
|
920
925
|
const totalCount = total ?? sandboxes.length;
|
|
921
926
|
const totalPages = Math.ceil(totalCount / pageSize);
|
|
922
927
|
return /* @__PURE__ */ jsxs9("div", { className: cn("w-full", className), children: [
|
|
923
|
-
/* @__PURE__ */ jsx10("div", { className: "w-full bg-
|
|
924
|
-
/* @__PURE__ */ jsx10("thead", { children: /* @__PURE__ */ jsxs9("tr", { className: "bg-
|
|
925
|
-
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-
|
|
926
|
-
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-
|
|
927
|
-
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-
|
|
928
|
-
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-
|
|
929
|
-
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-
|
|
928
|
+
/* @__PURE__ */ jsx10("div", { className: "w-full bg-card rounded-2xl overflow-hidden border border-border", children: /* @__PURE__ */ jsx10("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs9("table", { className: "w-full text-left border-collapse", children: [
|
|
929
|
+
/* @__PURE__ */ jsx10("thead", { children: /* @__PURE__ */ jsxs9("tr", { className: "bg-background border-b border-border", children: [
|
|
930
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Status" }),
|
|
931
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Sandbox Name" }),
|
|
932
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Environment" }),
|
|
933
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Resources" }),
|
|
934
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider text-right", children: "Actions" })
|
|
930
935
|
] }) }),
|
|
931
|
-
/* @__PURE__ */ jsx10("tbody", { className: "divide-y divide-
|
|
936
|
+
/* @__PURE__ */ jsx10("tbody", { className: "divide-y divide-border", children: sandboxes.map((sb) => {
|
|
932
937
|
const sc = statusColors[sb.status] ?? statusColors.stopped;
|
|
933
938
|
const isActive = sb.status === "running";
|
|
934
939
|
const isHibernating = sb.status === "hibernating";
|
|
935
940
|
const isProvisioning = sb.status === "provisioning";
|
|
936
|
-
return /* @__PURE__ */ jsxs9("tr", { className: "hover:bg-
|
|
941
|
+
return /* @__PURE__ */ jsxs9("tr", { className: "hover:bg-muted/50 transition-colors group relative", children: [
|
|
937
942
|
/* @__PURE__ */ jsx10("td", { className: "px-6 py-5 whitespace-nowrap", children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
938
943
|
/* @__PURE__ */ jsx10("span", { className: cn("flex h-2.5 w-2.5 rounded-full", sc.dot) }),
|
|
939
944
|
/* @__PURE__ */ jsx10("span", { className: cn("text-xs font-bold uppercase tracking-wide", sc.text), children: sb.status.charAt(0).toUpperCase() + sb.status.slice(1) })
|
|
940
945
|
] }) }),
|
|
941
946
|
/* @__PURE__ */ jsx10("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsxs9("div", { className: "flex flex-col", children: [
|
|
942
|
-
/* @__PURE__ */ jsx10("span", { className: "text-sm font-bold text-
|
|
943
|
-
sb.nodeId && /* @__PURE__ */ jsx10("span", { className: "text-[10px] font-mono text-
|
|
947
|
+
/* @__PURE__ */ jsx10("span", { className: "text-sm font-bold text-foreground group-hover:text-primary transition-colors", children: sb.name }),
|
|
948
|
+
sb.nodeId && /* @__PURE__ */ jsx10("span", { className: "text-[10px] font-mono text-muted-foreground", children: sb.nodeId })
|
|
944
949
|
] }) }),
|
|
945
950
|
/* @__PURE__ */ jsx10("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3", children: [
|
|
946
|
-
sb.imageIcon && /* @__PURE__ */ jsx10("div", { className: "w-8 h-8 rounded-lg bg-
|
|
947
|
-
sb.image && /* @__PURE__ */ jsx10("span", { className: "text-xs font-bold text-
|
|
951
|
+
sb.imageIcon && /* @__PURE__ */ jsx10("div", { className: "w-8 h-8 rounded-lg bg-muted/50 flex items-center justify-center", children: sb.imageIcon }),
|
|
952
|
+
sb.image && /* @__PURE__ */ jsx10("span", { className: "text-xs font-bold text-foreground", children: sb.image })
|
|
948
953
|
] }) }),
|
|
949
954
|
/* @__PURE__ */ jsx10("td", { className: "px-6 py-5", children: isActive ? /* @__PURE__ */ jsxs9("div", { className: "space-y-3 w-48", children: [
|
|
950
955
|
/* @__PURE__ */ jsx10(MiniMeter, { label: "CPU", percent: sb.cpuPercent ?? 0 }),
|
|
951
956
|
/* @__PURE__ */ jsx10(MiniMeter, { label: "RAM", percent: sb.ramTotal ? Math.round((sb.ramUsed ?? 0) / sb.ramTotal * 100) : 0 })
|
|
952
|
-
] }) : isProvisioning ? /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 text-
|
|
953
|
-
/* @__PURE__ */ jsx10(
|
|
957
|
+
] }) : isProvisioning ? /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 text-primary italic text-[10px] font-bold", children: [
|
|
958
|
+
/* @__PURE__ */ jsx10(RefreshCw, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
954
959
|
sb.provisioningMessage ?? "Allocating nodes..."
|
|
955
960
|
] }) : isHibernating ? /* @__PURE__ */ jsxs9("div", { className: "space-y-3 w-48 opacity-30", children: [
|
|
956
961
|
/* @__PURE__ */ jsx10(MiniMeter, { label: "CPU", percent: 0 }),
|
|
957
962
|
/* @__PURE__ */ jsx10(MiniMeter, { label: "RAM", percent: 0 })
|
|
958
963
|
] }) : null }),
|
|
959
964
|
/* @__PURE__ */ jsx10("td", { className: "px-6 py-5 text-right", children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-end gap-1", children: [
|
|
960
|
-
isActive && /* @__PURE__ */ jsxs9(
|
|
961
|
-
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onOpenIDE?.(sb.id), className: "p-2 rounded-lg hover:bg-
|
|
962
|
-
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onOpenTerminal?.(sb.id), className: "p-2 rounded-lg hover:bg-
|
|
963
|
-
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onSSH?.(sb.id), className: "p-2 rounded-lg hover:bg-
|
|
965
|
+
isActive && /* @__PURE__ */ jsxs9(Fragment6, { children: [
|
|
966
|
+
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onOpenIDE?.(sb.id), className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "Open IDE", children: /* @__PURE__ */ jsx10(Code22, { className: "h-4 w-4" }) }),
|
|
967
|
+
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onOpenTerminal?.(sb.id), className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "Terminal", children: /* @__PURE__ */ jsx10(Terminal2, { className: "h-4 w-4" }) }),
|
|
968
|
+
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onSSH?.(sb.id), className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "SSH", children: /* @__PURE__ */ jsx10(Key, { className: "h-4 w-4" }) })
|
|
964
969
|
] }),
|
|
965
|
-
isHibernating && /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onWake?.(sb.id), className: "px-3 py-1.5 rounded-lg border border-
|
|
966
|
-
onMore && /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onMore(sb.id), className: "p-2 rounded-lg hover:bg-
|
|
967
|
-
onDelete && /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onDelete(sb.id), className: "p-2 rounded-lg hover:bg-[var(--surface-danger-bg)] text-
|
|
970
|
+
isHibernating && /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onWake?.(sb.id), className: "px-3 py-1.5 rounded-lg border border-border text-primary text-[10px] font-bold uppercase tracking-wider hover:bg-[var(--accent-surface-soft)] active:scale-95 transition-all", children: "Wake Up" }),
|
|
971
|
+
onMore && /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onMore(sb.id), className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", children: /* @__PURE__ */ jsx10(Code22, { className: "h-4 w-4" }) }),
|
|
972
|
+
onDelete && /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onDelete(sb.id), className: "p-2 rounded-lg hover:bg-[var(--surface-danger-bg)] text-muted-foreground hover:text-[var(--surface-danger-text)] transition-all active:scale-90", title: "Delete", children: /* @__PURE__ */ jsx10(Trash22, { className: "h-4 w-4" }) })
|
|
968
973
|
] }) })
|
|
969
974
|
] }, sb.id);
|
|
970
975
|
}) })
|
|
971
976
|
] }) }) }),
|
|
972
|
-
totalPages > 1 && /* @__PURE__ */ jsxs9("div", { className: "mt-6 flex flex-col md:flex-row justify-between items-center text-
|
|
977
|
+
totalPages > 1 && /* @__PURE__ */ jsxs9("div", { className: "mt-6 flex flex-col md:flex-row justify-between items-center text-muted-foreground text-xs font-medium gap-4", children: [
|
|
973
978
|
/* @__PURE__ */ jsxs9("p", { children: [
|
|
974
979
|
"Showing ",
|
|
975
980
|
sandboxes.length,
|
|
@@ -978,7 +983,7 @@ function SandboxTable({
|
|
|
978
983
|
" active sandboxes"
|
|
979
984
|
] }),
|
|
980
985
|
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
981
|
-
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onPageChange?.(page - 1), disabled: page <= 1, className: "p-2 rounded-lg border border-
|
|
986
|
+
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onPageChange?.(page - 1), disabled: page <= 1, className: "p-2 rounded-lg border border-border hover:bg-muted/50 transition-colors disabled:opacity-30", children: /* @__PURE__ */ jsx10(ChevronLeft, { className: "h-4 w-4" }) }),
|
|
982
987
|
Array.from({ length: Math.min(totalPages, 5) }, (_, i) => i + 1).map((p) => /* @__PURE__ */ jsx10(
|
|
983
988
|
"button",
|
|
984
989
|
{
|
|
@@ -986,13 +991,13 @@ function SandboxTable({
|
|
|
986
991
|
onClick: () => onPageChange?.(p),
|
|
987
992
|
className: cn(
|
|
988
993
|
"px-3 py-1 rounded-lg transition-colors",
|
|
989
|
-
p === page ? "bg-[var(--accent-surface-soft)] text-
|
|
994
|
+
p === page ? "bg-[var(--accent-surface-soft)] text-primary border border-border" : "hover:bg-muted/50"
|
|
990
995
|
),
|
|
991
996
|
children: p
|
|
992
997
|
},
|
|
993
998
|
p
|
|
994
999
|
)),
|
|
995
|
-
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onPageChange?.(page + 1), disabled: page >= totalPages, className: "p-2 rounded-lg border border-
|
|
1000
|
+
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onPageChange?.(page + 1), disabled: page >= totalPages, className: "p-2 rounded-lg border border-border hover:bg-muted/50 transition-colors disabled:opacity-30", children: /* @__PURE__ */ jsx10(ChevronRight, { className: "h-4 w-4" }) })
|
|
996
1001
|
] })
|
|
997
1002
|
] })
|
|
998
1003
|
] });
|
|
@@ -1012,26 +1017,26 @@ function BackendSelector({
|
|
|
1012
1017
|
}) {
|
|
1013
1018
|
const current = backends.find((b) => b.type === selected);
|
|
1014
1019
|
return /* @__PURE__ */ jsxs10("div", { className: cn("space-y-1.5", className), children: [
|
|
1015
|
-
label && /* @__PURE__ */ jsx11("label", { className: "block text-xs font-medium text-
|
|
1020
|
+
label && /* @__PURE__ */ jsx11("label", { className: "block text-xs font-medium text-muted-foreground uppercase tracking-[0.06em]", children: label }),
|
|
1016
1021
|
/* @__PURE__ */ jsxs10(Select.Root, { value: selected, onValueChange: onChange, children: [
|
|
1017
1022
|
/* @__PURE__ */ jsxs10(
|
|
1018
1023
|
Select.Trigger,
|
|
1019
1024
|
{
|
|
1020
1025
|
className: cn(
|
|
1021
1026
|
"flex w-full items-center justify-between gap-2 rounded-[var(--radius-md)]",
|
|
1022
|
-
"border border-
|
|
1027
|
+
"border border-border bg-card",
|
|
1023
1028
|
"px-3 py-2.5 text-sm text-left",
|
|
1024
1029
|
"transition-colors duration-[var(--transition-fast)]",
|
|
1025
|
-
"hover:border-
|
|
1026
|
-
"focus:outline-none focus:border-
|
|
1027
|
-
"data-[state=open]:border-
|
|
1030
|
+
"hover:border-primary/20 hover:bg-accent/30",
|
|
1031
|
+
"focus:outline-none focus:border-primary/30",
|
|
1032
|
+
"data-[state=open]:border-primary/30 data-[state=open]:bg-accent/30"
|
|
1028
1033
|
),
|
|
1029
1034
|
children: [
|
|
1030
1035
|
/* @__PURE__ */ jsx11("div", { className: "min-w-0 flex-1", children: current ? /* @__PURE__ */ jsxs10("div", { children: [
|
|
1031
|
-
/* @__PURE__ */ jsx11("span", { className: "font-medium text-
|
|
1032
|
-
current.description && /* @__PURE__ */ jsx11("span", { className: "ml-2 text-xs text-
|
|
1033
|
-
] }) : /* @__PURE__ */ jsx11("span", { className: "text-
|
|
1034
|
-
/* @__PURE__ */ jsx11(Select.Icon, { asChild: true, children: /* @__PURE__ */ jsx11(ChevronDown, { className: "h-4 w-4 shrink-0 text-
|
|
1036
|
+
/* @__PURE__ */ jsx11("span", { className: "font-medium text-foreground", children: current.label }),
|
|
1037
|
+
current.description && /* @__PURE__ */ jsx11("span", { className: "ml-2 text-xs text-muted-foreground", children: current.description })
|
|
1038
|
+
] }) : /* @__PURE__ */ jsx11("span", { className: "text-muted-foreground", children: placeholder }) }),
|
|
1039
|
+
/* @__PURE__ */ jsx11(Select.Icon, { asChild: true, children: /* @__PURE__ */ jsx11(ChevronDown, { className: "h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-[var(--transition-fast)] data-[state=open]:rotate-180" }) })
|
|
1035
1040
|
]
|
|
1036
1041
|
}
|
|
1037
1042
|
),
|
|
@@ -1042,8 +1047,8 @@ function BackendSelector({
|
|
|
1042
1047
|
sideOffset: 4,
|
|
1043
1048
|
className: cn(
|
|
1044
1049
|
"z-50 w-[var(--radix-select-trigger-width)] overflow-hidden",
|
|
1045
|
-
"rounded-[var(--radius-md)] border border-
|
|
1046
|
-
"bg-
|
|
1050
|
+
"rounded-[var(--radius-md)] border border-border",
|
|
1051
|
+
"bg-card shadow-[var(--shadow-dropdown)]",
|
|
1047
1052
|
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
1048
1053
|
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
1049
1054
|
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
@@ -1057,12 +1062,12 @@ function BackendSelector({
|
|
|
1057
1062
|
"relative flex cursor-pointer select-none flex-col rounded-[var(--radius-sm)]",
|
|
1058
1063
|
"px-3 py-2.5 text-sm outline-none",
|
|
1059
1064
|
"transition-colors duration-[var(--transition-fast)]",
|
|
1060
|
-
"hover:bg-
|
|
1065
|
+
"hover:bg-accent/50 focus:bg-accent/50",
|
|
1061
1066
|
"data-[state=checked]:bg-[var(--accent-surface-soft)] data-[state=checked]:text-[var(--brand-primary)]"
|
|
1062
1067
|
),
|
|
1063
1068
|
children: [
|
|
1064
1069
|
/* @__PURE__ */ jsx11(Select.ItemText, { children: /* @__PURE__ */ jsx11("span", { className: "font-medium", children: backend.label }) }),
|
|
1065
|
-
backend.description && /* @__PURE__ */ jsx11("span", { className: "mt-0.5 text-xs text-
|
|
1070
|
+
backend.description && /* @__PURE__ */ jsx11("span", { className: "mt-0.5 text-xs text-muted-foreground data-[state=checked]:text-[var(--accent-text)]", children: backend.description })
|
|
1066
1071
|
]
|
|
1067
1072
|
},
|
|
1068
1073
|
backend.type
|
|
@@ -1075,7 +1080,7 @@ function BackendSelector({
|
|
|
1075
1080
|
|
|
1076
1081
|
// src/dashboard/profile-selector.tsx
|
|
1077
1082
|
import { Check as Check2, ChevronDown as ChevronDown2, Plus as Plus3, Settings } from "lucide-react";
|
|
1078
|
-
import { Fragment as
|
|
1083
|
+
import { Fragment as Fragment7, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1079
1084
|
function ProfileSelector({
|
|
1080
1085
|
profiles,
|
|
1081
1086
|
selectedId,
|
|
@@ -1109,7 +1114,7 @@ function ProfileSelector({
|
|
|
1109
1114
|
]
|
|
1110
1115
|
}
|
|
1111
1116
|
),
|
|
1112
|
-
builtinProfiles.length > 0 && /* @__PURE__ */ jsxs11(
|
|
1117
|
+
builtinProfiles.length > 0 && /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
1113
1118
|
/* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
|
|
1114
1119
|
/* @__PURE__ */ jsx12(DropdownMenuLabel, { children: "Built-in Profiles" }),
|
|
1115
1120
|
builtinProfiles.map((profile) => /* @__PURE__ */ jsxs11(
|
|
@@ -1134,7 +1139,7 @@ function ProfileSelector({
|
|
|
1134
1139
|
profile.id
|
|
1135
1140
|
))
|
|
1136
1141
|
] }),
|
|
1137
|
-
customProfiles.length > 0 && /* @__PURE__ */ jsxs11(
|
|
1142
|
+
customProfiles.length > 0 && /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
1138
1143
|
/* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
|
|
1139
1144
|
/* @__PURE__ */ jsx12(DropdownMenuLabel, { children: "Custom Profiles" }),
|
|
1140
1145
|
customProfiles.map((profile) => /* @__PURE__ */ jsxs11(
|
|
@@ -1171,7 +1176,7 @@ function ProfileSelector({
|
|
|
1171
1176
|
profile.id
|
|
1172
1177
|
))
|
|
1173
1178
|
] }),
|
|
1174
|
-
(onCreateClick || onManageClick) && /* @__PURE__ */ jsxs11(
|
|
1179
|
+
(onCreateClick || onManageClick) && /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
1175
1180
|
/* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
|
|
1176
1181
|
onCreateClick && /* @__PURE__ */ jsxs11(
|
|
1177
1182
|
DropdownMenuItem,
|
|
@@ -1269,17 +1274,17 @@ function ProfileComparison({
|
|
|
1269
1274
|
import {
|
|
1270
1275
|
Check as Check3,
|
|
1271
1276
|
CheckCircle2,
|
|
1272
|
-
Clock,
|
|
1273
|
-
ExternalLink
|
|
1277
|
+
Clock as Clock2,
|
|
1278
|
+
ExternalLink,
|
|
1274
1279
|
Loader2,
|
|
1275
1280
|
Timer,
|
|
1276
1281
|
X,
|
|
1277
1282
|
XCircle
|
|
1278
1283
|
} from "lucide-react";
|
|
1279
|
-
import { Fragment as
|
|
1280
|
-
var
|
|
1284
|
+
import { Fragment as Fragment8, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1285
|
+
var statusConfig = {
|
|
1281
1286
|
pending: {
|
|
1282
|
-
icon:
|
|
1287
|
+
icon: Clock2,
|
|
1283
1288
|
color: "text-[var(--surface-warning-text)]",
|
|
1284
1289
|
bg: "bg-[var(--surface-warning-bg)]",
|
|
1285
1290
|
border: "border-[var(--surface-warning-border)]",
|
|
@@ -1288,9 +1293,9 @@ var statusConfig2 = {
|
|
|
1288
1293
|
},
|
|
1289
1294
|
running: {
|
|
1290
1295
|
icon: Loader2,
|
|
1291
|
-
color: "text-
|
|
1296
|
+
color: "text-primary",
|
|
1292
1297
|
bg: "bg-[var(--accent-surface-soft)]",
|
|
1293
|
-
border: "border-
|
|
1298
|
+
border: "border-border",
|
|
1294
1299
|
label: "Running",
|
|
1295
1300
|
animate: true
|
|
1296
1301
|
},
|
|
@@ -1361,13 +1366,13 @@ function VariantList({
|
|
|
1361
1366
|
className
|
|
1362
1367
|
}) {
|
|
1363
1368
|
return /* @__PURE__ */ jsx13("div", { className: `space-y-2 ${className || ""}`, children: variants.map((variant) => {
|
|
1364
|
-
const status =
|
|
1369
|
+
const status = statusConfig[variant.status];
|
|
1365
1370
|
const StatusIcon = status.icon;
|
|
1366
1371
|
const isSelected = variant.id === selectedId;
|
|
1367
1372
|
return /* @__PURE__ */ jsxs12(
|
|
1368
1373
|
"div",
|
|
1369
1374
|
{
|
|
1370
|
-
className: `cursor-pointer rounded-lg border px-3 py-2.5 transition-colors ${isSelected ? "border-
|
|
1375
|
+
className: `cursor-pointer rounded-lg border px-3 py-2.5 transition-colors ${isSelected ? "border-primary/30 bg-[var(--accent-surface-soft)]" : "border-border bg-card hover:border-primary/20 hover:bg-muted/50"}`,
|
|
1371
1376
|
onClick: () => onSelect?.(variant.id),
|
|
1372
1377
|
children: [
|
|
1373
1378
|
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
|
|
@@ -1380,13 +1385,13 @@ function VariantList({
|
|
|
1380
1385
|
),
|
|
1381
1386
|
status.label
|
|
1382
1387
|
] }),
|
|
1383
|
-
/* @__PURE__ */ jsx13("span", { className: "truncate text-sm font-medium text-
|
|
1384
|
-
variant.sublabel && /* @__PURE__ */ jsxs12("span", { className: "shrink-0 text-xs text-
|
|
1388
|
+
/* @__PURE__ */ jsx13("span", { className: "truncate text-sm font-medium text-foreground", children: variant.label }),
|
|
1389
|
+
variant.sublabel && /* @__PURE__ */ jsxs12("span", { className: "shrink-0 text-xs text-muted-foreground", children: [
|
|
1385
1390
|
"(",
|
|
1386
1391
|
variant.sublabel,
|
|
1387
1392
|
")"
|
|
1388
1393
|
] }),
|
|
1389
|
-
variant.durationMs && /* @__PURE__ */ jsxs12("span", { className: "flex shrink-0 items-center gap-1 text-xs text-
|
|
1394
|
+
variant.durationMs && /* @__PURE__ */ jsxs12("span", { className: "flex shrink-0 items-center gap-1 text-xs text-muted-foreground", children: [
|
|
1390
1395
|
/* @__PURE__ */ jsx13(Timer, { className: "h-3 w-3" }),
|
|
1391
1396
|
(variant.durationMs / 1e3).toFixed(1),
|
|
1392
1397
|
"s"
|
|
@@ -1399,7 +1404,7 @@ function VariantList({
|
|
|
1399
1404
|
children: outcomeConfig[variant.outcome].label
|
|
1400
1405
|
}
|
|
1401
1406
|
),
|
|
1402
|
-
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */ jsxs12(
|
|
1407
|
+
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */ jsxs12(Fragment8, { children: [
|
|
1403
1408
|
/* @__PURE__ */ jsxs12(
|
|
1404
1409
|
Button,
|
|
1405
1410
|
{
|
|
@@ -1440,18 +1445,18 @@ function VariantList({
|
|
|
1440
1445
|
{
|
|
1441
1446
|
variant: "ghost",
|
|
1442
1447
|
size: "sm",
|
|
1443
|
-
className: "h-7 w-7 p-0 text-
|
|
1448
|
+
className: "h-7 w-7 p-0 text-muted-foreground hover:text-foreground",
|
|
1444
1449
|
onClick: (e) => {
|
|
1445
1450
|
e.stopPropagation();
|
|
1446
1451
|
window.open(variant.detailsUrl, "_blank");
|
|
1447
1452
|
},
|
|
1448
|
-
children: /* @__PURE__ */ jsx13(
|
|
1453
|
+
children: /* @__PURE__ */ jsx13(ExternalLink, { className: "h-3.5 w-3.5" })
|
|
1449
1454
|
}
|
|
1450
1455
|
)
|
|
1451
1456
|
] })
|
|
1452
1457
|
] }),
|
|
1453
1458
|
variant.error && /* @__PURE__ */ jsx13("p", { className: "mt-1.5 text-xs text-[var(--surface-danger-text)]", children: variant.error }),
|
|
1454
|
-
variant.summary && /* @__PURE__ */ jsx13("p", { className: "mt-1.5 line-clamp-2 text-xs text-
|
|
1459
|
+
variant.summary && /* @__PURE__ */ jsx13("p", { className: "mt-1.5 line-clamp-2 text-xs text-muted-foreground", children: variant.summary })
|
|
1455
1460
|
]
|
|
1456
1461
|
},
|
|
1457
1462
|
variant.id
|