@tangle-network/sandbox-ui 0.6.1 → 0.9.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.
- package/README.md +5 -6
- 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-WBQ7VULC.js → chunk-34A66VBG.js} +7 -7
- package/dist/{chunk-JP725R4W.js → chunk-34I7UFSX.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-6V4XVKFY.js → chunk-7YWFOGKQ.js} +344 -338
- package/dist/{chunk-DCPYTL4W.js → chunk-D4CZWJCD.js} +72 -148
- package/dist/{chunk-XTPAWK7L.js → chunk-DI3NZ5ZX.js} +15 -51
- 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-RKXIRRKQ.js → chunk-JLKYXLFN.js} +70 -66
- package/dist/{chunk-BRBTD7RH.js → chunk-MA7YKRUP.js} +28 -18
- package/dist/{chunk-TSE423UF.js → chunk-MKTSMWVD.js} +6 -6
- package/dist/{chunk-MJUDMVRU.js → chunk-MT5FJ3ZT.js} +17 -17
- package/dist/{chunk-565V6JTN.js → chunk-OHPW55EV.js} +60 -99
- package/dist/chunk-OKLQVY3Y.js +139 -0
- package/dist/{chunk-OVNLOE3Y.js → chunk-PLTZB5BC.js} +41 -41
- package/dist/{chunk-E2XT3G52.js → chunk-QC4BJEG6.js} +136 -137
- 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-YS66Q3RC.js → chunk-US6JKJKH.js} +2 -2
- package/dist/chunk-VX3XOUEB.js +63 -0
- package/dist/{chunk-TDYQBLL5.js → chunk-ZMNSRDMH.js} +6 -6
- package/dist/dashboard.d.ts +156 -4
- package/dist/dashboard.js +885 -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 +4787 -69
- 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 +114 -5
- package/dist/pages.js +1978 -365
- 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 +4787 -69
- 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 +289 -237
- 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-CsS6ydgm.d.ts} +16 -7
- package/dist/workspace.d.ts +2 -2
- package/dist/workspace.js +13 -13
- package/package.json +18 -3
- 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-MKTSMWVD.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 border-r border-border transition-[transform,width] duration-200 ease-in-out",
|
|
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-
|
|
197
|
-
isActive && "bg-[var(--accent-surface-strong)] text-[var(--accent-text)]
|
|
198
|
-
!isActive && "text-
|
|
195
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
|
|
196
|
+
isActive && "bg-[var(--accent-surface-strong)] text-[var(--accent-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",
|
|
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: "overflow-hidden rounded-full border border-border bg-card px-6 py-3 flex flex-wrap sm:flex-nowrap items-center justify-between gap-8 shadow-sm", 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 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",
|
|
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(--
|
|
636
|
+
className: "hidden md:flex items-center gap-2 bg-[var(--btn-primary-bg)] border border-[var(--border-accent)] text-[var(--btn-primary-text)] px-4 py-2 rounded-lg font-bold hover:bg-[var(--btn-primary-hover)] 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,21 +661,21 @@ 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
|
),
|
|
690
671
|
/* @__PURE__ */ jsx7(Sidebar, { className: cn("hidden lg:flex", sidebarClassName), children: sidebarContent }),
|
|
691
|
-
/* @__PURE__ */ jsx7(SidebarContent, { className: cn("pt-16 px-
|
|
692
|
-
/* @__PURE__ */ jsx7("main", { className: cn("pt-16 px-6 pb-8 min-h-screen lg:hidden", contentClassName), children }),
|
|
672
|
+
/* @__PURE__ */ jsx7(SidebarContent, { className: cn("pt-16 px-8 pb-8 hidden lg:block bg-background", contentClassName), children }),
|
|
673
|
+
/* @__PURE__ */ jsx7("main", { className: cn("pt-16 px-6 pb-8 min-h-screen lg:hidden bg-background", contentClassName), children }),
|
|
693
674
|
footer
|
|
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,188 @@ 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 flex flex-col justify-between overflow-hidden rounded-lg border bg-card p-5 transition-colors",
|
|
744
|
+
isRunning ? "border-[var(--status-running)]/30" : "border-border",
|
|
745
|
+
"hover:border-foreground/15",
|
|
746
|
+
className
|
|
747
|
+
), children: [
|
|
748
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-start justify-between", children: [
|
|
749
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
750
|
+
/* @__PURE__ */ jsxs8("h3", { className: "flex items-center gap-2 text-sm font-bold text-foreground", children: [
|
|
751
|
+
sandbox.name,
|
|
752
|
+
isRunning && /* @__PURE__ */ jsxs8("span", { className: "relative flex h-2 w-2", children: [
|
|
753
|
+
/* @__PURE__ */ jsx9("span", { className: "absolute inline-flex h-full w-full animate-pulse rounded-full bg-[var(--status-running)] opacity-75" }),
|
|
754
|
+
/* @__PURE__ */ jsx9("span", { className: "relative inline-flex h-1.5 w-1.5 rounded-full bg-[var(--status-running)]" })
|
|
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: "mt-0.5 font-mono text-[10px] tracking-wider text-muted-foreground uppercase", children: sandbox.nodeId || "Unknown Node" })
|
|
758
|
+
] }),
|
|
759
|
+
/* @__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-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground outline-none",
|
|
765
|
+
"aria-label": "Sandbox options",
|
|
766
|
+
children: /* @__PURE__ */ jsx9(MoreVertical, { className: "h-4 w-4" })
|
|
839
767
|
}
|
|
840
|
-
),
|
|
841
|
-
|
|
842
|
-
|
|
768
|
+
) }),
|
|
769
|
+
/* @__PURE__ */ jsxs8(DropdownMenuContent, { align: "end", className: "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
|
+
(onStop || onKeepAlive) && /* @__PURE__ */ jsx9(DropdownMenuSeparator, {}),
|
|
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
|
+
(onUsage || onHealth) && /* @__PURE__ */ jsx9(DropdownMenuSeparator, {}),
|
|
789
|
+
onFork && /* @__PURE__ */ jsxs8(Fragment5, { children: [
|
|
790
|
+
/* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onFork(sandbox.id), children: [
|
|
791
|
+
/* @__PURE__ */ jsx9(Copy, { className: "mr-2 h-4 w-4" }),
|
|
792
|
+
" Fork Sandbox"
|
|
793
|
+
] }),
|
|
794
|
+
/* @__PURE__ */ jsx9(DropdownMenuSeparator, {})
|
|
795
|
+
] })
|
|
796
|
+
] }),
|
|
797
|
+
isStopped && /* @__PURE__ */ jsxs8(Fragment5, { children: [
|
|
798
|
+
onResume && /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onResume(sandbox.id), children: [
|
|
799
|
+
/* @__PURE__ */ jsx9(Power, { className: "mr-2 h-4 w-4" }),
|
|
800
|
+
" Resume Sandbox"
|
|
801
|
+
] }),
|
|
802
|
+
onFork && /* @__PURE__ */ jsxs8(DropdownMenuItem, { onClick: () => onFork(sandbox.id), children: [
|
|
803
|
+
/* @__PURE__ */ jsx9(Copy, { className: "mr-2 h-4 w-4" }),
|
|
804
|
+
" Fork Sandbox"
|
|
805
|
+
] }),
|
|
806
|
+
(onResume || onFork) && /* @__PURE__ */ jsx9(DropdownMenuSeparator, {})
|
|
807
|
+
] }),
|
|
808
|
+
onDelete && /* @__PURE__ */ jsxs8(DropdownMenuItem, { className: "text-destructive focus:bg-destructive/10 focus:text-destructive", onClick: () => onDelete(sandbox.id), children: [
|
|
809
|
+
/* @__PURE__ */ jsx9(Trash2, { className: "mr-2 h-4 w-4" }),
|
|
810
|
+
" Delete Sandbox"
|
|
811
|
+
] })
|
|
812
|
+
] })
|
|
813
|
+
] })
|
|
814
|
+
] }),
|
|
815
|
+
/* @__PURE__ */ jsxs8("div", { className: "my-4", children: [
|
|
816
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3 rounded-md border border-border bg-muted/30 p-3", children: [
|
|
817
|
+
/* @__PURE__ */ jsx9("div", { className: cn("flex h-10 w-10 items-center justify-center rounded-md", isRunning ? "bg-[var(--surface-success-bg)]" : "bg-muted"), children: sandbox.imageIcon ? sandbox.imageIcon : sandbox.image?.includes("node") ? /* @__PURE__ */ jsx9(Code2, { className: cn("h-5 w-5", isRunning ? "text-[var(--surface-success-text)]" : "text-muted-foreground") }) : /* @__PURE__ */ jsx9(Terminal, { className: cn("h-5 w-5", isRunning ? "text-[var(--surface-success-text)]" : "text-muted-foreground") }) }),
|
|
818
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex flex-col", children: [
|
|
819
|
+
/* @__PURE__ */ jsx9("span", { className: "text-[10px] text-muted-foreground uppercase tracking-widest font-bold", children: "Environment" }),
|
|
820
|
+
/* @__PURE__ */ jsx9("span", { className: "text-xs font-medium text-foreground font-mono mt-0.5", children: sandbox.image || "Universal" })
|
|
821
|
+
] })
|
|
822
|
+
] }),
|
|
823
|
+
isTransitioning && /* @__PURE__ */ jsxs8("div", { className: "mt-3", children: [
|
|
824
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex justify-between text-xs text-muted-foreground font-medium mb-1", children: [
|
|
825
|
+
/* @__PURE__ */ jsx9("span", { children: sandbox.provisioningMessage || "Starting..." }),
|
|
826
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
827
|
+
sandbox.provisioningPercent || 0,
|
|
828
|
+
"%"
|
|
829
|
+
] })
|
|
830
|
+
] }),
|
|
831
|
+
/* @__PURE__ */ jsx9("div", { className: "h-1 w-full overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx9(
|
|
832
|
+
"div",
|
|
843
833
|
{
|
|
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"
|
|
834
|
+
className: "h-full bg-primary transition-all duration-500 rounded-full",
|
|
835
|
+
style: { width: `${sandbox.provisioningPercent || 5}%` }
|
|
848
836
|
}
|
|
837
|
+
) })
|
|
838
|
+
] })
|
|
839
|
+
] }),
|
|
840
|
+
/* @__PURE__ */ jsx9("div", { className: "border-t border-border pt-3", children: isRunning ? /* @__PURE__ */ jsxs8(
|
|
841
|
+
"button",
|
|
842
|
+
{
|
|
843
|
+
type: "button",
|
|
844
|
+
onClick: () => onOpenIDE?.(sandbox.id),
|
|
845
|
+
className: "flex w-full items-center justify-center gap-2 rounded-md bg-[var(--btn-primary-bg)] px-4 py-2 text-sm font-semibold text-[var(--btn-primary-text)] transition-colors hover:bg-[var(--btn-primary-hover)] active:scale-[0.97]",
|
|
846
|
+
children: [
|
|
847
|
+
/* @__PURE__ */ jsx9(Network, { className: "h-4 w-4" }),
|
|
848
|
+
"Connect Session"
|
|
849
|
+
]
|
|
850
|
+
}
|
|
851
|
+
) : /* @__PURE__ */ jsxs8(
|
|
852
|
+
"button",
|
|
853
|
+
{
|
|
854
|
+
type: "button",
|
|
855
|
+
onClick: () => onWake?.(sandbox.id),
|
|
856
|
+
disabled: isTransitioning,
|
|
857
|
+
className: cn(
|
|
858
|
+
"flex w-full items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-semibold transition-colors border",
|
|
859
|
+
isTransitioning ? "bg-muted text-muted-foreground cursor-not-allowed border-border" : "bg-card text-foreground hover:bg-muted border-border active:scale-[0.97]"
|
|
849
860
|
),
|
|
850
|
-
|
|
851
|
-
"
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
children: /* @__PURE__ */ jsx9(Trash2, { className: "h-3.5 w-3.5" })
|
|
858
|
-
}
|
|
859
|
-
)
|
|
860
|
-
]
|
|
861
|
-
}
|
|
862
|
-
);
|
|
861
|
+
children: [
|
|
862
|
+
/* @__PURE__ */ jsx9(Play, { className: "h-4 w-4" }),
|
|
863
|
+
isTransitioning ? "Starting..." : "Wake Sandbox"
|
|
864
|
+
]
|
|
865
|
+
}
|
|
866
|
+
) })
|
|
867
|
+
] });
|
|
863
868
|
}
|
|
864
869
|
function NewSandboxCard({ onClick, className }) {
|
|
865
870
|
return /* @__PURE__ */ jsxs8(
|
|
@@ -868,39 +873,40 @@ function NewSandboxCard({ onClick, className }) {
|
|
|
868
873
|
type: "button",
|
|
869
874
|
onClick,
|
|
870
875
|
className: cn(
|
|
871
|
-
"border-2 border-dashed border-
|
|
876
|
+
"border-2 border-dashed border-border rounded-lg p-5 flex flex-col items-center justify-center text-center cursor-pointer hover:border-foreground/20 hover:bg-muted/30 transition-colors w-full min-h-[160px]",
|
|
872
877
|
className
|
|
873
878
|
),
|
|
874
879
|
children: [
|
|
875
|
-
/* @__PURE__ */ jsx9("div", { className: "
|
|
876
|
-
/* @__PURE__ */ jsx9("
|
|
877
|
-
/* @__PURE__ */ jsx9("
|
|
880
|
+
/* @__PURE__ */ jsx9("div", { className: "flex h-12 w-12 items-center justify-center rounded-lg bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx9(Plus2, { className: "h-6 w-6" }) }),
|
|
881
|
+
/* @__PURE__ */ jsx9("span", { className: "mt-4 text-sm font-semibold text-foreground", children: "New Sandbox" }),
|
|
882
|
+
/* @__PURE__ */ jsx9("span", { className: "mt-1 text-xs text-muted-foreground", children: "Deploy a new isolated environment" })
|
|
878
883
|
]
|
|
879
884
|
}
|
|
880
885
|
);
|
|
881
886
|
}
|
|
882
887
|
|
|
883
888
|
// src/dashboard/sandbox-table.tsx
|
|
884
|
-
import { Terminal as Terminal2, Code2, Key, Trash2 as Trash22, RefreshCw
|
|
885
|
-
import { Fragment as
|
|
889
|
+
import { Terminal as Terminal2, Code2 as Code22, Key, Trash2 as Trash22, RefreshCw, ChevronLeft, ChevronRight } from "lucide-react";
|
|
890
|
+
import { Fragment as Fragment6, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
886
891
|
var statusColors = {
|
|
887
892
|
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
|
-
|
|
893
|
+
hibernating: { dot: "bg-muted-foreground", text: "text-muted-foreground", bar: "bg-muted-foreground" },
|
|
894
|
+
provisioning: { dot: "bg-primary animate-pulse", text: "text-primary", bar: "bg-primary" },
|
|
895
|
+
creating: { dot: "bg-primary animate-pulse", text: "text-primary", bar: "bg-primary" },
|
|
896
|
+
stopped: { dot: "bg-muted-foreground", text: "text-foreground", bar: "bg-muted-foreground" },
|
|
891
897
|
failed: { dot: "bg-[var(--code-error)]", text: "text-[var(--code-error)]", bar: "bg-[var(--code-error)]" },
|
|
892
|
-
archived: { dot: "bg-
|
|
898
|
+
archived: { dot: "bg-border", text: "text-muted-foreground", bar: "bg-border" }
|
|
893
899
|
};
|
|
894
900
|
function MiniMeter({ label, percent, className }) {
|
|
895
901
|
return /* @__PURE__ */ jsxs9("div", { className: cn("space-y-1", className), children: [
|
|
896
|
-
/* @__PURE__ */ jsxs9("div", { className: "flex justify-between text-[10px] font-mono text-
|
|
902
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex justify-between text-[10px] font-mono text-muted-foreground", children: [
|
|
897
903
|
/* @__PURE__ */ jsx10("span", { className: "font-bold", children: label }),
|
|
898
|
-
/* @__PURE__ */ jsxs9("span", { className: "text-
|
|
904
|
+
/* @__PURE__ */ jsxs9("span", { className: "text-primary", children: [
|
|
899
905
|
percent,
|
|
900
906
|
"%"
|
|
901
907
|
] })
|
|
902
908
|
] }),
|
|
903
|
-
/* @__PURE__ */ jsx10("div", { className: "h-1.5 w-full bg-
|
|
909
|
+
/* @__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
910
|
] });
|
|
905
911
|
}
|
|
906
912
|
function SandboxTable({
|
|
@@ -920,56 +926,56 @@ function SandboxTable({
|
|
|
920
926
|
const totalCount = total ?? sandboxes.length;
|
|
921
927
|
const totalPages = Math.ceil(totalCount / pageSize);
|
|
922
928
|
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-
|
|
929
|
+
/* @__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: [
|
|
930
|
+
/* @__PURE__ */ jsx10("thead", { children: /* @__PURE__ */ jsxs9("tr", { className: "bg-background border-b border-border", children: [
|
|
931
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Status" }),
|
|
932
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Sandbox Name" }),
|
|
933
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Environment" }),
|
|
934
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Resources" }),
|
|
935
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider text-right", children: "Actions" })
|
|
930
936
|
] }) }),
|
|
931
|
-
/* @__PURE__ */ jsx10("tbody", { className: "divide-y divide-
|
|
937
|
+
/* @__PURE__ */ jsx10("tbody", { className: "divide-y divide-border", children: sandboxes.map((sb) => {
|
|
932
938
|
const sc = statusColors[sb.status] ?? statusColors.stopped;
|
|
933
939
|
const isActive = sb.status === "running";
|
|
934
940
|
const isHibernating = sb.status === "hibernating";
|
|
935
941
|
const isProvisioning = sb.status === "provisioning";
|
|
936
|
-
return /* @__PURE__ */ jsxs9("tr", { className: "hover:bg-
|
|
942
|
+
return /* @__PURE__ */ jsxs9("tr", { className: "hover:bg-muted/50 transition-colors group relative", children: [
|
|
937
943
|
/* @__PURE__ */ jsx10("td", { className: "px-6 py-5 whitespace-nowrap", children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
938
944
|
/* @__PURE__ */ jsx10("span", { className: cn("flex h-2.5 w-2.5 rounded-full", sc.dot) }),
|
|
939
945
|
/* @__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
946
|
] }) }),
|
|
941
947
|
/* @__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-
|
|
948
|
+
/* @__PURE__ */ jsx10("span", { className: "text-sm font-bold text-foreground group-hover:text-primary transition-colors", children: sb.name }),
|
|
949
|
+
sb.nodeId && /* @__PURE__ */ jsx10("span", { className: "text-[10px] font-mono text-muted-foreground", children: sb.nodeId })
|
|
944
950
|
] }) }),
|
|
945
951
|
/* @__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-
|
|
952
|
+
sb.imageIcon && /* @__PURE__ */ jsx10("div", { className: "w-8 h-8 rounded-lg bg-muted/50 flex items-center justify-center", children: sb.imageIcon }),
|
|
953
|
+
sb.image && /* @__PURE__ */ jsx10("span", { className: "text-xs font-bold text-foreground", children: sb.image })
|
|
948
954
|
] }) }),
|
|
949
955
|
/* @__PURE__ */ jsx10("td", { className: "px-6 py-5", children: isActive ? /* @__PURE__ */ jsxs9("div", { className: "space-y-3 w-48", children: [
|
|
950
956
|
/* @__PURE__ */ jsx10(MiniMeter, { label: "CPU", percent: sb.cpuPercent ?? 0 }),
|
|
951
957
|
/* @__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(
|
|
958
|
+
] }) : isProvisioning ? /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 text-primary italic text-[10px] font-bold", children: [
|
|
959
|
+
/* @__PURE__ */ jsx10(RefreshCw, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
954
960
|
sb.provisioningMessage ?? "Allocating nodes..."
|
|
955
961
|
] }) : isHibernating ? /* @__PURE__ */ jsxs9("div", { className: "space-y-3 w-48 opacity-30", children: [
|
|
956
962
|
/* @__PURE__ */ jsx10(MiniMeter, { label: "CPU", percent: 0 }),
|
|
957
963
|
/* @__PURE__ */ jsx10(MiniMeter, { label: "RAM", percent: 0 })
|
|
958
964
|
] }) : null }),
|
|
959
965
|
/* @__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-
|
|
966
|
+
isActive && /* @__PURE__ */ jsxs9(Fragment6, { children: [
|
|
967
|
+
/* @__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" }) }),
|
|
968
|
+
/* @__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" }) }),
|
|
969
|
+
/* @__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
970
|
] }),
|
|
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-
|
|
971
|
+
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" }),
|
|
972
|
+
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" }) }),
|
|
973
|
+
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
974
|
] }) })
|
|
969
975
|
] }, sb.id);
|
|
970
976
|
}) })
|
|
971
977
|
] }) }) }),
|
|
972
|
-
totalPages > 1 && /* @__PURE__ */ jsxs9("div", { className: "mt-6 flex flex-col md:flex-row justify-between items-center text-
|
|
978
|
+
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
979
|
/* @__PURE__ */ jsxs9("p", { children: [
|
|
974
980
|
"Showing ",
|
|
975
981
|
sandboxes.length,
|
|
@@ -978,7 +984,7 @@ function SandboxTable({
|
|
|
978
984
|
" active sandboxes"
|
|
979
985
|
] }),
|
|
980
986
|
/* @__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-
|
|
987
|
+
/* @__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
988
|
Array.from({ length: Math.min(totalPages, 5) }, (_, i) => i + 1).map((p) => /* @__PURE__ */ jsx10(
|
|
983
989
|
"button",
|
|
984
990
|
{
|
|
@@ -986,13 +992,13 @@ function SandboxTable({
|
|
|
986
992
|
onClick: () => onPageChange?.(p),
|
|
987
993
|
className: cn(
|
|
988
994
|
"px-3 py-1 rounded-lg transition-colors",
|
|
989
|
-
p === page ? "bg-[var(--accent-surface-soft)] text-
|
|
995
|
+
p === page ? "bg-[var(--accent-surface-soft)] text-primary border border-border" : "hover:bg-muted/50"
|
|
990
996
|
),
|
|
991
997
|
children: p
|
|
992
998
|
},
|
|
993
999
|
p
|
|
994
1000
|
)),
|
|
995
|
-
/* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onPageChange?.(page + 1), disabled: page >= totalPages, className: "p-2 rounded-lg border border-
|
|
1001
|
+
/* @__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
1002
|
] })
|
|
997
1003
|
] })
|
|
998
1004
|
] });
|
|
@@ -1012,26 +1018,26 @@ function BackendSelector({
|
|
|
1012
1018
|
}) {
|
|
1013
1019
|
const current = backends.find((b) => b.type === selected);
|
|
1014
1020
|
return /* @__PURE__ */ jsxs10("div", { className: cn("space-y-1.5", className), children: [
|
|
1015
|
-
label && /* @__PURE__ */ jsx11("label", { className: "block text-xs font-medium text-
|
|
1021
|
+
label && /* @__PURE__ */ jsx11("label", { className: "block text-xs font-medium text-muted-foreground uppercase tracking-[0.06em]", children: label }),
|
|
1016
1022
|
/* @__PURE__ */ jsxs10(Select.Root, { value: selected, onValueChange: onChange, children: [
|
|
1017
1023
|
/* @__PURE__ */ jsxs10(
|
|
1018
1024
|
Select.Trigger,
|
|
1019
1025
|
{
|
|
1020
1026
|
className: cn(
|
|
1021
1027
|
"flex w-full items-center justify-between gap-2 rounded-[var(--radius-md)]",
|
|
1022
|
-
"border border-
|
|
1028
|
+
"border border-border bg-card",
|
|
1023
1029
|
"px-3 py-2.5 text-sm text-left",
|
|
1024
1030
|
"transition-colors duration-[var(--transition-fast)]",
|
|
1025
|
-
"hover:border-
|
|
1026
|
-
"focus:outline-none focus:border-
|
|
1027
|
-
"data-[state=open]:border-
|
|
1031
|
+
"hover:border-primary/20 hover:bg-accent/30",
|
|
1032
|
+
"focus:outline-none focus:border-primary/30",
|
|
1033
|
+
"data-[state=open]:border-primary/30 data-[state=open]:bg-accent/30"
|
|
1028
1034
|
),
|
|
1029
1035
|
children: [
|
|
1030
1036
|
/* @__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-
|
|
1037
|
+
/* @__PURE__ */ jsx11("span", { className: "font-medium text-foreground", children: current.label }),
|
|
1038
|
+
current.description && /* @__PURE__ */ jsx11("span", { className: "ml-2 text-xs text-muted-foreground", children: current.description })
|
|
1039
|
+
] }) : /* @__PURE__ */ jsx11("span", { className: "text-muted-foreground", children: placeholder }) }),
|
|
1040
|
+
/* @__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
1041
|
]
|
|
1036
1042
|
}
|
|
1037
1043
|
),
|
|
@@ -1042,8 +1048,8 @@ function BackendSelector({
|
|
|
1042
1048
|
sideOffset: 4,
|
|
1043
1049
|
className: cn(
|
|
1044
1050
|
"z-50 w-[var(--radix-select-trigger-width)] overflow-hidden",
|
|
1045
|
-
"rounded-[var(--radius-md)] border border-
|
|
1046
|
-
"bg-
|
|
1051
|
+
"rounded-[var(--radius-md)] border border-border",
|
|
1052
|
+
"bg-card shadow-[var(--shadow-dropdown)]",
|
|
1047
1053
|
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
1048
1054
|
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
1049
1055
|
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
@@ -1057,12 +1063,12 @@ function BackendSelector({
|
|
|
1057
1063
|
"relative flex cursor-pointer select-none flex-col rounded-[var(--radius-sm)]",
|
|
1058
1064
|
"px-3 py-2.5 text-sm outline-none",
|
|
1059
1065
|
"transition-colors duration-[var(--transition-fast)]",
|
|
1060
|
-
"hover:bg-
|
|
1066
|
+
"hover:bg-accent/50 focus:bg-accent/50",
|
|
1061
1067
|
"data-[state=checked]:bg-[var(--accent-surface-soft)] data-[state=checked]:text-[var(--brand-primary)]"
|
|
1062
1068
|
),
|
|
1063
1069
|
children: [
|
|
1064
1070
|
/* @__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-
|
|
1071
|
+
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
1072
|
]
|
|
1067
1073
|
},
|
|
1068
1074
|
backend.type
|
|
@@ -1075,7 +1081,7 @@ function BackendSelector({
|
|
|
1075
1081
|
|
|
1076
1082
|
// src/dashboard/profile-selector.tsx
|
|
1077
1083
|
import { Check as Check2, ChevronDown as ChevronDown2, Plus as Plus3, Settings } from "lucide-react";
|
|
1078
|
-
import { Fragment as
|
|
1084
|
+
import { Fragment as Fragment7, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1079
1085
|
function ProfileSelector({
|
|
1080
1086
|
profiles,
|
|
1081
1087
|
selectedId,
|
|
@@ -1109,7 +1115,7 @@ function ProfileSelector({
|
|
|
1109
1115
|
]
|
|
1110
1116
|
}
|
|
1111
1117
|
),
|
|
1112
|
-
builtinProfiles.length > 0 && /* @__PURE__ */ jsxs11(
|
|
1118
|
+
builtinProfiles.length > 0 && /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
1113
1119
|
/* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
|
|
1114
1120
|
/* @__PURE__ */ jsx12(DropdownMenuLabel, { children: "Built-in Profiles" }),
|
|
1115
1121
|
builtinProfiles.map((profile) => /* @__PURE__ */ jsxs11(
|
|
@@ -1134,7 +1140,7 @@ function ProfileSelector({
|
|
|
1134
1140
|
profile.id
|
|
1135
1141
|
))
|
|
1136
1142
|
] }),
|
|
1137
|
-
customProfiles.length > 0 && /* @__PURE__ */ jsxs11(
|
|
1143
|
+
customProfiles.length > 0 && /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
1138
1144
|
/* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
|
|
1139
1145
|
/* @__PURE__ */ jsx12(DropdownMenuLabel, { children: "Custom Profiles" }),
|
|
1140
1146
|
customProfiles.map((profile) => /* @__PURE__ */ jsxs11(
|
|
@@ -1171,7 +1177,7 @@ function ProfileSelector({
|
|
|
1171
1177
|
profile.id
|
|
1172
1178
|
))
|
|
1173
1179
|
] }),
|
|
1174
|
-
(onCreateClick || onManageClick) && /* @__PURE__ */ jsxs11(
|
|
1180
|
+
(onCreateClick || onManageClick) && /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
1175
1181
|
/* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
|
|
1176
1182
|
onCreateClick && /* @__PURE__ */ jsxs11(
|
|
1177
1183
|
DropdownMenuItem,
|
|
@@ -1269,17 +1275,17 @@ function ProfileComparison({
|
|
|
1269
1275
|
import {
|
|
1270
1276
|
Check as Check3,
|
|
1271
1277
|
CheckCircle2,
|
|
1272
|
-
Clock,
|
|
1273
|
-
ExternalLink
|
|
1278
|
+
Clock as Clock2,
|
|
1279
|
+
ExternalLink,
|
|
1274
1280
|
Loader2,
|
|
1275
1281
|
Timer,
|
|
1276
1282
|
X,
|
|
1277
1283
|
XCircle
|
|
1278
1284
|
} from "lucide-react";
|
|
1279
|
-
import { Fragment as
|
|
1280
|
-
var
|
|
1285
|
+
import { Fragment as Fragment8, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1286
|
+
var statusConfig = {
|
|
1281
1287
|
pending: {
|
|
1282
|
-
icon:
|
|
1288
|
+
icon: Clock2,
|
|
1283
1289
|
color: "text-[var(--surface-warning-text)]",
|
|
1284
1290
|
bg: "bg-[var(--surface-warning-bg)]",
|
|
1285
1291
|
border: "border-[var(--surface-warning-border)]",
|
|
@@ -1288,9 +1294,9 @@ var statusConfig2 = {
|
|
|
1288
1294
|
},
|
|
1289
1295
|
running: {
|
|
1290
1296
|
icon: Loader2,
|
|
1291
|
-
color: "text-
|
|
1297
|
+
color: "text-primary",
|
|
1292
1298
|
bg: "bg-[var(--accent-surface-soft)]",
|
|
1293
|
-
border: "border-
|
|
1299
|
+
border: "border-border",
|
|
1294
1300
|
label: "Running",
|
|
1295
1301
|
animate: true
|
|
1296
1302
|
},
|
|
@@ -1361,13 +1367,13 @@ function VariantList({
|
|
|
1361
1367
|
className
|
|
1362
1368
|
}) {
|
|
1363
1369
|
return /* @__PURE__ */ jsx13("div", { className: `space-y-2 ${className || ""}`, children: variants.map((variant) => {
|
|
1364
|
-
const status =
|
|
1370
|
+
const status = statusConfig[variant.status];
|
|
1365
1371
|
const StatusIcon = status.icon;
|
|
1366
1372
|
const isSelected = variant.id === selectedId;
|
|
1367
1373
|
return /* @__PURE__ */ jsxs12(
|
|
1368
1374
|
"div",
|
|
1369
1375
|
{
|
|
1370
|
-
className: `cursor-pointer rounded-lg border px-3 py-2.5 transition-colors ${isSelected ? "border-
|
|
1376
|
+
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
1377
|
onClick: () => onSelect?.(variant.id),
|
|
1372
1378
|
children: [
|
|
1373
1379
|
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
|
|
@@ -1380,13 +1386,13 @@ function VariantList({
|
|
|
1380
1386
|
),
|
|
1381
1387
|
status.label
|
|
1382
1388
|
] }),
|
|
1383
|
-
/* @__PURE__ */ jsx13("span", { className: "truncate text-sm font-medium text-
|
|
1384
|
-
variant.sublabel && /* @__PURE__ */ jsxs12("span", { className: "shrink-0 text-xs text-
|
|
1389
|
+
/* @__PURE__ */ jsx13("span", { className: "truncate text-sm font-medium text-foreground", children: variant.label }),
|
|
1390
|
+
variant.sublabel && /* @__PURE__ */ jsxs12("span", { className: "shrink-0 text-xs text-muted-foreground", children: [
|
|
1385
1391
|
"(",
|
|
1386
1392
|
variant.sublabel,
|
|
1387
1393
|
")"
|
|
1388
1394
|
] }),
|
|
1389
|
-
variant.durationMs && /* @__PURE__ */ jsxs12("span", { className: "flex shrink-0 items-center gap-1 text-xs text-
|
|
1395
|
+
variant.durationMs && /* @__PURE__ */ jsxs12("span", { className: "flex shrink-0 items-center gap-1 text-xs text-muted-foreground", children: [
|
|
1390
1396
|
/* @__PURE__ */ jsx13(Timer, { className: "h-3 w-3" }),
|
|
1391
1397
|
(variant.durationMs / 1e3).toFixed(1),
|
|
1392
1398
|
"s"
|
|
@@ -1399,7 +1405,7 @@ function VariantList({
|
|
|
1399
1405
|
children: outcomeConfig[variant.outcome].label
|
|
1400
1406
|
}
|
|
1401
1407
|
),
|
|
1402
|
-
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */ jsxs12(
|
|
1408
|
+
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */ jsxs12(Fragment8, { children: [
|
|
1403
1409
|
/* @__PURE__ */ jsxs12(
|
|
1404
1410
|
Button,
|
|
1405
1411
|
{
|
|
@@ -1440,18 +1446,18 @@ function VariantList({
|
|
|
1440
1446
|
{
|
|
1441
1447
|
variant: "ghost",
|
|
1442
1448
|
size: "sm",
|
|
1443
|
-
className: "h-7 w-7 p-0 text-
|
|
1449
|
+
className: "h-7 w-7 p-0 text-muted-foreground hover:text-foreground",
|
|
1444
1450
|
onClick: (e) => {
|
|
1445
1451
|
e.stopPropagation();
|
|
1446
1452
|
window.open(variant.detailsUrl, "_blank");
|
|
1447
1453
|
},
|
|
1448
|
-
children: /* @__PURE__ */ jsx13(
|
|
1454
|
+
children: /* @__PURE__ */ jsx13(ExternalLink, { className: "h-3.5 w-3.5" })
|
|
1449
1455
|
}
|
|
1450
1456
|
)
|
|
1451
1457
|
] })
|
|
1452
1458
|
] }),
|
|
1453
1459
|
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-
|
|
1460
|
+
variant.summary && /* @__PURE__ */ jsx13("p", { className: "mt-1.5 line-clamp-2 text-xs text-muted-foreground", children: variant.summary })
|
|
1455
1461
|
]
|
|
1456
1462
|
},
|
|
1457
1463
|
variant.id
|