@tangle-network/sandbox-ui 0.31.0 → 0.32.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/dist/chat.js +3 -3
- package/dist/{chunk-DNZ4DTNA.js → chunk-2XNT74ZX.js} +2 -2
- package/dist/{chunk-AUFV7766.js → chunk-6NDOA4SB.js} +11 -8
- package/dist/{chunk-SXAMR3TV.js → chunk-CI6RWXWY.js} +767 -741
- package/dist/{chunk-BJFWPP5T.js → chunk-E267TDZP.js} +12 -12
- package/dist/{chunk-ELGN7DPS.js → chunk-JC7GMQK7.js} +1 -1
- package/dist/{chunk-6NQBODYV.js → chunk-NMR2CTGP.js} +6 -6
- package/dist/dashboard.d.ts +23 -1
- package/dist/dashboard.js +6 -4
- package/dist/globals.css +90 -55
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -6
- package/dist/pages.js +14 -14
- package/dist/styles.css +90 -55
- package/dist/workspace.js +1 -1
- package/package.json +1 -1
|
@@ -134,8 +134,32 @@ function useSidebar() {
|
|
|
134
134
|
return ctx;
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
// src/dashboard/
|
|
137
|
+
// src/dashboard/rail-tooltip.tsx
|
|
138
138
|
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
139
|
+
function RailTooltip({ label, children, disabled, className }) {
|
|
140
|
+
if (disabled) return /* @__PURE__ */ jsx2(Fragment, { children });
|
|
141
|
+
return /* @__PURE__ */ jsxs("span", { className: cn("group/tip relative flex", className), children: [
|
|
142
|
+
children,
|
|
143
|
+
/* @__PURE__ */ jsx2(
|
|
144
|
+
"span",
|
|
145
|
+
{
|
|
146
|
+
role: "tooltip",
|
|
147
|
+
"aria-hidden": "true",
|
|
148
|
+
className: cn(
|
|
149
|
+
"pointer-events-none absolute left-full top-1/2 z-50 ml-2 -translate-y-1/2 translate-x-1 whitespace-nowrap",
|
|
150
|
+
"rounded-md border border-border bg-popover px-2 py-1 text-xs font-medium text-popover-foreground",
|
|
151
|
+
"opacity-0 shadow-[var(--shadow-dropdown)] transition-[opacity,transform] duration-150 ease-out",
|
|
152
|
+
"group-hover/tip:translate-x-0 group-hover/tip:opacity-100 group-hover/tip:delay-300",
|
|
153
|
+
"group-focus-within/tip:translate-x-0 group-focus-within/tip:opacity-100"
|
|
154
|
+
),
|
|
155
|
+
children: label
|
|
156
|
+
}
|
|
157
|
+
)
|
|
158
|
+
] });
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// src/dashboard/app-sidebar.tsx
|
|
162
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
139
163
|
function DefaultLink({
|
|
140
164
|
href,
|
|
141
165
|
to,
|
|
@@ -143,7 +167,7 @@ function DefaultLink({
|
|
|
143
167
|
children,
|
|
144
168
|
...rest
|
|
145
169
|
}) {
|
|
146
|
-
return /* @__PURE__ */
|
|
170
|
+
return /* @__PURE__ */ jsx3("a", { href: href ?? to, className, ...rest, children });
|
|
147
171
|
}
|
|
148
172
|
function getInitials(name, email) {
|
|
149
173
|
if (name) return name.split(" ").map((w) => w[0]).filter(Boolean).slice(0, 2).join("").toUpperCase();
|
|
@@ -151,31 +175,31 @@ function getInitials(name, email) {
|
|
|
151
175
|
return "?";
|
|
152
176
|
}
|
|
153
177
|
function SettingsIcon({ className }) {
|
|
154
|
-
return /* @__PURE__ */
|
|
155
|
-
/* @__PURE__ */
|
|
156
|
-
/* @__PURE__ */
|
|
157
|
-
/* @__PURE__ */
|
|
178
|
+
return /* @__PURE__ */ jsxs2("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: [
|
|
179
|
+
/* @__PURE__ */ jsx3("title", { children: "Settings icon" }),
|
|
180
|
+
/* @__PURE__ */ jsx3("path", { d: "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" }),
|
|
181
|
+
/* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "3" })
|
|
158
182
|
] });
|
|
159
183
|
}
|
|
160
184
|
function LogOutIcon({ className }) {
|
|
161
|
-
return /* @__PURE__ */
|
|
162
|
-
/* @__PURE__ */
|
|
163
|
-
/* @__PURE__ */
|
|
164
|
-
/* @__PURE__ */
|
|
165
|
-
/* @__PURE__ */
|
|
185
|
+
return /* @__PURE__ */ jsxs2("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: [
|
|
186
|
+
/* @__PURE__ */ jsx3("title", { children: "Log out icon" }),
|
|
187
|
+
/* @__PURE__ */ jsx3("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }),
|
|
188
|
+
/* @__PURE__ */ jsx3("polyline", { points: "16,17 21,12 16,7" }),
|
|
189
|
+
/* @__PURE__ */ jsx3("line", { x1: "21", x2: "9", y1: "12", y2: "12" })
|
|
166
190
|
] });
|
|
167
191
|
}
|
|
168
192
|
function SunIcon({ className }) {
|
|
169
|
-
return /* @__PURE__ */
|
|
170
|
-
/* @__PURE__ */
|
|
171
|
-
/* @__PURE__ */
|
|
172
|
-
/* @__PURE__ */
|
|
193
|
+
return /* @__PURE__ */ jsxs2("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: [
|
|
194
|
+
/* @__PURE__ */ jsx3("title", { children: "Light mode icon" }),
|
|
195
|
+
/* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "4" }),
|
|
196
|
+
/* @__PURE__ */ jsx3("path", { d: "M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" })
|
|
173
197
|
] });
|
|
174
198
|
}
|
|
175
199
|
function MoonIcon({ className }) {
|
|
176
|
-
return /* @__PURE__ */
|
|
177
|
-
/* @__PURE__ */
|
|
178
|
-
/* @__PURE__ */
|
|
200
|
+
return /* @__PURE__ */ jsxs2("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: [
|
|
201
|
+
/* @__PURE__ */ jsx3("title", { children: "Dark mode icon" }),
|
|
202
|
+
/* @__PURE__ */ jsx3("path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" })
|
|
179
203
|
] });
|
|
180
204
|
}
|
|
181
205
|
function RailThemeToggle({ className }) {
|
|
@@ -183,7 +207,7 @@ function RailThemeToggle({ className }) {
|
|
|
183
207
|
const [mounted, setMounted] = React2.useState(false);
|
|
184
208
|
React2.useEffect(() => setMounted(true), []);
|
|
185
209
|
const isDark = mounted && (theme === "dark" || theme === "system" && typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches);
|
|
186
|
-
return /* @__PURE__ */
|
|
210
|
+
return /* @__PURE__ */ jsx3(
|
|
187
211
|
"button",
|
|
188
212
|
{
|
|
189
213
|
type: "button",
|
|
@@ -193,53 +217,52 @@ function RailThemeToggle({ className }) {
|
|
|
193
217
|
className: cn(
|
|
194
218
|
"flex h-9 w-9 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors",
|
|
195
219
|
"hover:bg-[var(--accent-surface-soft)] hover:text-foreground",
|
|
196
|
-
"focus-visible:outline-none focus-visible:ring-
|
|
220
|
+
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
197
221
|
className
|
|
198
222
|
),
|
|
199
|
-
children: isDark ? /* @__PURE__ */
|
|
223
|
+
children: isDark ? /* @__PURE__ */ jsx3(SunIcon, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx3(MoonIcon, { className: "h-4 w-4" })
|
|
200
224
|
}
|
|
201
225
|
);
|
|
202
226
|
}
|
|
203
227
|
function ChevronsLeftIcon({ className }) {
|
|
204
|
-
return /* @__PURE__ */
|
|
205
|
-
/* @__PURE__ */
|
|
206
|
-
/* @__PURE__ */
|
|
228
|
+
return /* @__PURE__ */ jsxs2("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: [
|
|
229
|
+
/* @__PURE__ */ jsx3("title", { children: "Collapse sidebar" }),
|
|
230
|
+
/* @__PURE__ */ jsx3("path", { d: "m11 17-5-5 5-5M18 17l-5-5 5-5" })
|
|
207
231
|
] });
|
|
208
232
|
}
|
|
209
233
|
function ChevronsRightIcon({ className }) {
|
|
210
|
-
return /* @__PURE__ */
|
|
211
|
-
/* @__PURE__ */
|
|
212
|
-
/* @__PURE__ */
|
|
234
|
+
return /* @__PURE__ */ jsxs2("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: [
|
|
235
|
+
/* @__PURE__ */ jsx3("title", { children: "Expand sidebar" }),
|
|
236
|
+
/* @__PURE__ */ jsx3("path", { d: "m6 17 5-5-5-5M13 17l5-5-5-5" })
|
|
213
237
|
] });
|
|
214
238
|
}
|
|
215
239
|
function RailCollapseToggle({ collapsed, showLabel, onToggle, className }) {
|
|
216
240
|
const label = collapsed ? "Expand sidebar" : "Collapse sidebar";
|
|
217
241
|
const Icon = collapsed ? ChevronsRightIcon : ChevronsLeftIcon;
|
|
218
|
-
return /* @__PURE__ */
|
|
242
|
+
return /* @__PURE__ */ jsx3(RailTooltip, { label, disabled: showLabel, className: showLabel ? "w-full" : void 0, children: /* @__PURE__ */ jsxs2(
|
|
219
243
|
"button",
|
|
220
244
|
{
|
|
221
245
|
type: "button",
|
|
222
246
|
onClick: onToggle,
|
|
223
247
|
"aria-label": label,
|
|
224
248
|
"aria-pressed": collapsed,
|
|
225
|
-
title: label,
|
|
226
249
|
className: cn(
|
|
227
|
-
"
|
|
250
|
+
"flex shrink-0 items-center rounded-md text-muted-foreground transition-colors",
|
|
228
251
|
showLabel ? "h-9 w-full justify-start gap-2.5 px-2.5" : "h-9 w-9 justify-center",
|
|
229
252
|
"hover:bg-[var(--accent-surface-soft)] hover:text-foreground",
|
|
230
|
-
"focus-visible:outline-none focus-visible:ring-
|
|
253
|
+
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
231
254
|
className
|
|
232
255
|
),
|
|
233
256
|
children: [
|
|
234
|
-
/* @__PURE__ */
|
|
235
|
-
showLabel && /* @__PURE__ */
|
|
257
|
+
/* @__PURE__ */ jsx3(Icon, { className: "h-[17px] w-[17px] shrink-0" }),
|
|
258
|
+
showLabel && /* @__PURE__ */ jsx3("span", { className: "text-[13.5px] font-medium", children: label })
|
|
236
259
|
]
|
|
237
260
|
}
|
|
238
|
-
);
|
|
261
|
+
) });
|
|
239
262
|
}
|
|
240
263
|
function Sidebar({ children, className, style }) {
|
|
241
264
|
const { panelOpen, hidden, hasPanels, railWidth } = useSidebar();
|
|
242
|
-
return /* @__PURE__ */
|
|
265
|
+
return /* @__PURE__ */ jsx3(
|
|
243
266
|
"div",
|
|
244
267
|
{
|
|
245
268
|
"data-sidebar": "true",
|
|
@@ -255,7 +278,7 @@ function Sidebar({ children, className, style }) {
|
|
|
255
278
|
}
|
|
256
279
|
function SidebarRail({ children, className, wide = false }) {
|
|
257
280
|
const { railWidth } = useSidebar();
|
|
258
|
-
return /* @__PURE__ */
|
|
281
|
+
return /* @__PURE__ */ jsx3(
|
|
259
282
|
"div",
|
|
260
283
|
{
|
|
261
284
|
className: cn(
|
|
@@ -269,42 +292,44 @@ function SidebarRail({ children, className, wide = false }) {
|
|
|
269
292
|
);
|
|
270
293
|
}
|
|
271
294
|
function SidebarRailHeader({ children, className }) {
|
|
272
|
-
return /* @__PURE__ */
|
|
295
|
+
return /* @__PURE__ */ jsx3("div", { className: cn("flex h-14 shrink-0 items-center justify-center border-b border-border", className), children });
|
|
273
296
|
}
|
|
274
297
|
function SidebarRailNav({ children, className }) {
|
|
275
|
-
return /* @__PURE__ */
|
|
298
|
+
return /* @__PURE__ */ jsx3("nav", { className: cn("flex flex-col items-center gap-1 py-3 flex-1 min-h-0 overflow-y-auto", className), children });
|
|
276
299
|
}
|
|
277
300
|
function SidebarRailFooter({ children, className }) {
|
|
278
|
-
return /* @__PURE__ */
|
|
301
|
+
return /* @__PURE__ */ jsx3("div", { className: cn("flex flex-col items-center gap-1 pb-3 shrink-0", className), children });
|
|
279
302
|
}
|
|
280
303
|
function RailSeparator({ className }) {
|
|
281
|
-
return /* @__PURE__ */
|
|
304
|
+
return /* @__PURE__ */ jsx3("div", { className: cn("my-2 h-px w-10 bg-[var(--md3-outline-variant)]", className) });
|
|
282
305
|
}
|
|
283
306
|
function RailButton({ icon: Icon, label, isActive, badge, onClick, className, showLabel, asChild, children }) {
|
|
284
307
|
const classes = cn(
|
|
285
|
-
"
|
|
308
|
+
"relative flex shrink-0 items-center justify-center rounded-md transition-colors duration-150",
|
|
286
309
|
showLabel ? "w-full justify-start px-2.5 h-9 gap-2.5" : "w-9 h-9 justify-center",
|
|
287
|
-
|
|
288
|
-
"
|
|
289
|
-
"
|
|
290
|
-
isActive && "bg-[var(--accent-surface-strong)] text-[var(--accent-text)]",
|
|
291
|
-
!isActive && "text-muted-foreground",
|
|
310
|
+
// Quiet press feedback via color only — no scale on the full-width row.
|
|
311
|
+
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
312
|
+
isActive ? "bg-[var(--accent-surface-strong)] text-[var(--accent-text)]" : "text-muted-foreground hover:bg-[var(--accent-surface-soft)] hover:text-foreground",
|
|
292
313
|
className
|
|
293
314
|
);
|
|
294
|
-
const
|
|
295
|
-
/* @__PURE__ */
|
|
296
|
-
|
|
297
|
-
|
|
315
|
+
const iconWithBadge = /* @__PURE__ */ jsxs2("span", { className: "relative flex shrink-0 items-center justify-center", children: [
|
|
316
|
+
/* @__PURE__ */ jsx3(Icon, { className: "h-[17px] w-[17px] shrink-0" }),
|
|
317
|
+
badge !== void 0 && badge > 0 && /* @__PURE__ */ jsx3("span", { className: "absolute -top-1.5 -right-1.5 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", children: badge > 99 ? "99+" : badge })
|
|
318
|
+
] });
|
|
319
|
+
const content = /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
320
|
+
iconWithBadge,
|
|
321
|
+
showLabel && /* @__PURE__ */ jsx3("span", { className: "text-[13.5px] font-medium", children: label })
|
|
298
322
|
] });
|
|
299
323
|
if (asChild && React2.isValidElement(children)) {
|
|
300
324
|
const child = children;
|
|
301
|
-
|
|
325
|
+
const merged = React2.cloneElement(
|
|
302
326
|
child,
|
|
303
|
-
{ className: cn(classes, child.props.className),
|
|
327
|
+
{ className: cn(classes, child.props.className), "aria-label": child.props["aria-label"] ?? label },
|
|
304
328
|
content
|
|
305
329
|
);
|
|
330
|
+
return /* @__PURE__ */ jsx3(RailTooltip, { label, disabled: showLabel, className: showLabel ? "w-full" : void 0, children: merged });
|
|
306
331
|
}
|
|
307
|
-
return /* @__PURE__ */
|
|
332
|
+
return /* @__PURE__ */ jsx3(RailTooltip, { label, disabled: showLabel, className: showLabel ? "w-full" : void 0, children: /* @__PURE__ */ jsx3("button", { type: "button", onClick, "aria-label": label, className: classes, children: content }) });
|
|
308
333
|
}
|
|
309
334
|
function RailFlyout({
|
|
310
335
|
icon: Icon,
|
|
@@ -332,28 +357,28 @@ function RailFlyout({
|
|
|
332
357
|
document.removeEventListener("keydown", onKey);
|
|
333
358
|
};
|
|
334
359
|
}, [open]);
|
|
360
|
+
const active = isActive || open;
|
|
335
361
|
const triggerClasses = cn(
|
|
336
|
-
"
|
|
362
|
+
"relative flex shrink-0 items-center rounded-md transition-colors duration-150",
|
|
337
363
|
showLabel ? "w-full justify-start px-2.5 h-9 gap-2.5" : "w-9 h-9 justify-center",
|
|
338
|
-
"
|
|
339
|
-
"
|
|
340
|
-
isActive || open ? "bg-[var(--accent-surface-strong)] text-[var(--accent-text)]" : "text-muted-foreground",
|
|
364
|
+
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
365
|
+
active ? "bg-[var(--accent-surface-strong)] text-[var(--accent-text)]" : "text-muted-foreground hover:bg-[var(--accent-surface-soft)] hover:text-foreground",
|
|
341
366
|
className
|
|
342
367
|
);
|
|
343
|
-
return /* @__PURE__ */
|
|
344
|
-
/* @__PURE__ */
|
|
368
|
+
return /* @__PURE__ */ jsxs2("div", { ref, className: cn("relative", showLabel && "w-full"), children: [
|
|
369
|
+
/* @__PURE__ */ jsx3(RailTooltip, { label, disabled: showLabel || open, className: showLabel ? "w-full" : void 0, children: /* @__PURE__ */ jsxs2(
|
|
345
370
|
"button",
|
|
346
371
|
{
|
|
347
372
|
type: "button",
|
|
348
|
-
|
|
373
|
+
"aria-label": label,
|
|
349
374
|
"aria-haspopup": "menu",
|
|
350
375
|
"aria-expanded": open,
|
|
351
376
|
onClick: () => setOpen((v) => !v),
|
|
352
377
|
className: triggerClasses,
|
|
353
378
|
children: [
|
|
354
|
-
/* @__PURE__ */
|
|
355
|
-
showLabel && /* @__PURE__ */
|
|
356
|
-
showLabel && /* @__PURE__ */
|
|
379
|
+
/* @__PURE__ */ jsx3(Icon, { className: "h-[17px] w-[17px] shrink-0" }),
|
|
380
|
+
showLabel && /* @__PURE__ */ jsx3("span", { className: "text-sm font-medium", children: label }),
|
|
381
|
+
showLabel && /* @__PURE__ */ jsx3(
|
|
357
382
|
ChevronRightIcon,
|
|
358
383
|
{
|
|
359
384
|
className: cn(
|
|
@@ -364,11 +389,11 @@ function RailFlyout({
|
|
|
364
389
|
)
|
|
365
390
|
]
|
|
366
391
|
}
|
|
367
|
-
),
|
|
392
|
+
) }),
|
|
368
393
|
open && // Anchored to the right edge of the rail item; full-height-independent
|
|
369
394
|
// floating card. `onClickCapture` closes after a child link/button fires
|
|
370
395
|
// so selecting a sub-surface dismisses the flyout.
|
|
371
|
-
/* @__PURE__ */
|
|
396
|
+
/* @__PURE__ */ jsxs2(
|
|
372
397
|
"div",
|
|
373
398
|
{
|
|
374
399
|
role: "menu",
|
|
@@ -377,11 +402,11 @@ function RailFlyout({
|
|
|
377
402
|
if (el.closest("a,button")) setOpen(false);
|
|
378
403
|
},
|
|
379
404
|
className: cn(
|
|
380
|
-
"absolute top-0 z-50 min-w-[12rem] rounded-md border border-border bg-popover p-1.5 shadow-dropdown",
|
|
405
|
+
"absolute top-0 z-50 min-w-[12rem] rounded-md border border-border bg-popover p-1.5 shadow-[var(--shadow-dropdown)]",
|
|
381
406
|
showLabel ? "left-full ml-2" : "left-full ml-2"
|
|
382
407
|
),
|
|
383
408
|
children: [
|
|
384
|
-
/* @__PURE__ */
|
|
409
|
+
/* @__PURE__ */ jsx3("p", { className: "px-2 pb-1 pt-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/70 select-none", children: title ?? label }),
|
|
385
410
|
children
|
|
386
411
|
]
|
|
387
412
|
}
|
|
@@ -389,14 +414,14 @@ function RailFlyout({
|
|
|
389
414
|
] });
|
|
390
415
|
}
|
|
391
416
|
function ChevronRightIcon({ className }) {
|
|
392
|
-
return /* @__PURE__ */
|
|
393
|
-
/* @__PURE__ */
|
|
394
|
-
/* @__PURE__ */
|
|
417
|
+
return /* @__PURE__ */ jsxs2("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: [
|
|
418
|
+
/* @__PURE__ */ jsx3("title", { children: "Expand" }),
|
|
419
|
+
/* @__PURE__ */ jsx3("path", { d: "m9 18 6-6-6-6" })
|
|
395
420
|
] });
|
|
396
421
|
}
|
|
397
422
|
function RailModeButton({ mode, icon, label, badge, className, showLabel }) {
|
|
398
423
|
const { panelOpen, mode: currentMode, switchMode } = useSidebar();
|
|
399
|
-
return /* @__PURE__ */
|
|
424
|
+
return /* @__PURE__ */ jsx3(
|
|
400
425
|
RailButton,
|
|
401
426
|
{
|
|
402
427
|
icon,
|
|
@@ -411,7 +436,7 @@ function RailModeButton({ mode, icon, label, badge, className, showLabel }) {
|
|
|
411
436
|
}
|
|
412
437
|
function SidebarPanel({ children, className }) {
|
|
413
438
|
const { panelOpen } = useSidebar();
|
|
414
|
-
return /* @__PURE__ */
|
|
439
|
+
return /* @__PURE__ */ jsx3(
|
|
415
440
|
"div",
|
|
416
441
|
{
|
|
417
442
|
className: cn(
|
|
@@ -419,19 +444,19 @@ function SidebarPanel({ children, className }) {
|
|
|
419
444
|
panelOpen ? "w-[268px] opacity-100" : "w-0 opacity-0 pointer-events-none",
|
|
420
445
|
className
|
|
421
446
|
),
|
|
422
|
-
children: /* @__PURE__ */
|
|
447
|
+
children: /* @__PURE__ */ jsx3("div", { className: "flex flex-col h-full w-[268px]", children })
|
|
423
448
|
}
|
|
424
449
|
);
|
|
425
450
|
}
|
|
426
451
|
function SidebarPanelHeader({ children, title, className }) {
|
|
427
|
-
return /* @__PURE__ */
|
|
452
|
+
return /* @__PURE__ */ jsx3("div", { className: cn("flex h-14 items-center px-4 border-b border-border shrink-0", className), children: children ?? /* @__PURE__ */ jsx3("h2", { className: "text-sm font-semibold text-foreground", children: title }) });
|
|
428
453
|
}
|
|
429
454
|
function SidebarPanelContent({ children, className }) {
|
|
430
|
-
return /* @__PURE__ */
|
|
455
|
+
return /* @__PURE__ */ jsx3("div", { className: cn("flex-1 overflow-y-auto px-2 py-2", className), children });
|
|
431
456
|
}
|
|
432
457
|
function SidebarContent({ children, className }) {
|
|
433
458
|
const { contentMargin } = useSidebar();
|
|
434
|
-
return /* @__PURE__ */
|
|
459
|
+
return /* @__PURE__ */ jsx3(
|
|
435
460
|
"main",
|
|
436
461
|
{
|
|
437
462
|
className: cn(
|
|
@@ -455,58 +480,58 @@ function ProfileAvatar({
|
|
|
455
480
|
LinkComponent
|
|
456
481
|
}) {
|
|
457
482
|
const Link = LinkComponent ?? DefaultLink;
|
|
458
|
-
return /* @__PURE__ */
|
|
459
|
-
/* @__PURE__ */
|
|
483
|
+
return /* @__PURE__ */ jsxs2(DropdownMenu, { children: [
|
|
484
|
+
/* @__PURE__ */ jsx3(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs2(
|
|
460
485
|
"button",
|
|
461
486
|
{
|
|
462
487
|
type: "button",
|
|
463
488
|
className: cn(
|
|
464
489
|
"flex items-center rounded-lg transition-colors hover:bg-[var(--accent-surface-soft)]",
|
|
465
|
-
"focus-visible:outline-none focus-visible:ring-
|
|
490
|
+
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
466
491
|
showDetails ? "w-full gap-2.5 px-3 py-2 text-left" : "justify-center w-12 h-12",
|
|
467
492
|
className
|
|
468
493
|
),
|
|
469
494
|
"aria-label": "User menu",
|
|
470
495
|
children: [
|
|
471
|
-
isLoading ? /* @__PURE__ */
|
|
472
|
-
user?.avatarUrl && /* @__PURE__ */
|
|
473
|
-
/* @__PURE__ */
|
|
496
|
+
isLoading ? /* @__PURE__ */ jsx3(Skeleton, { className: "h-7 w-7 shrink-0 rounded-full" }) : /* @__PURE__ */ jsxs2(Avatar, { className: "h-7 w-7 shrink-0", children: [
|
|
497
|
+
user?.avatarUrl && /* @__PURE__ */ jsx3(AvatarImage, { src: user.avatarUrl, alt: "" }),
|
|
498
|
+
/* @__PURE__ */ jsx3(AvatarFallback, { className: "text-[10px] bg-violet-500/20 text-violet-300", children: getInitials(user?.name, user?.email) })
|
|
474
499
|
] }),
|
|
475
|
-
showDetails && /* @__PURE__ */
|
|
500
|
+
showDetails && /* @__PURE__ */ jsx3("div", { className: "min-w-0 flex-1", children: isLoading ? /* @__PURE__ */ jsx3(Skeleton, { className: "h-3.5 w-24" }) : /* @__PURE__ */ jsx3("p", { className: "truncate text-sm font-medium text-foreground", children: user?.name ?? user?.email ?? "Not signed in" }) })
|
|
476
501
|
]
|
|
477
502
|
}
|
|
478
503
|
) }),
|
|
479
|
-
/* @__PURE__ */
|
|
480
|
-
/* @__PURE__ */
|
|
481
|
-
/* @__PURE__ */
|
|
482
|
-
user?.avatarUrl && /* @__PURE__ */
|
|
483
|
-
/* @__PURE__ */
|
|
504
|
+
/* @__PURE__ */ jsxs2(DropdownMenuContent, { side: "right", align: "end", sideOffset: 8, className: "w-72", children: [
|
|
505
|
+
/* @__PURE__ */ jsx3(DropdownMenuLabel, { className: "p-0 font-normal", children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-3 px-2 py-3", children: [
|
|
506
|
+
/* @__PURE__ */ jsxs2(Avatar, { className: "h-12 w-12 shrink-0", children: [
|
|
507
|
+
user?.avatarUrl && /* @__PURE__ */ jsx3(AvatarImage, { src: user.avatarUrl, alt: "" }),
|
|
508
|
+
/* @__PURE__ */ jsx3(AvatarFallback, { className: "text-sm bg-[var(--surface-violet-bg)] text-[var(--surface-violet-text)]", children: getInitials(user?.name, user?.email) })
|
|
484
509
|
] }),
|
|
485
|
-
/* @__PURE__ */
|
|
486
|
-
/* @__PURE__ */
|
|
487
|
-
/* @__PURE__ */
|
|
488
|
-
] }) : /* @__PURE__ */
|
|
489
|
-
/* @__PURE__ */
|
|
490
|
-
user?.email && user?.name && /* @__PURE__ */
|
|
491
|
-
user?.tier && /* @__PURE__ */
|
|
510
|
+
/* @__PURE__ */ jsx3("div", { className: "min-w-0 flex-1", children: isLoading ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
511
|
+
/* @__PURE__ */ jsx3(Skeleton, { className: "h-4 w-24 mb-1" }),
|
|
512
|
+
/* @__PURE__ */ jsx3(Skeleton, { className: "h-3 w-32" })
|
|
513
|
+
] }) : /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
514
|
+
/* @__PURE__ */ jsx3("p", { className: "text-sm font-semibold truncate", children: user?.name ?? user?.email ?? "Not logged in" }),
|
|
515
|
+
user?.email && user?.name && /* @__PURE__ */ jsx3("p", { className: "text-xs text-muted-foreground truncate", children: user.email }),
|
|
516
|
+
user?.tier && /* @__PURE__ */ jsxs2("p", { className: "text-xs text-muted-foreground capitalize", children: [
|
|
492
517
|
user.tier,
|
|
493
518
|
" Plan"
|
|
494
519
|
] })
|
|
495
520
|
] }) })
|
|
496
521
|
] }) }),
|
|
497
|
-
/* @__PURE__ */
|
|
522
|
+
/* @__PURE__ */ jsx3(DropdownMenuSeparator, {}),
|
|
498
523
|
children,
|
|
499
|
-
onSettingsClick ? /* @__PURE__ */
|
|
500
|
-
/* @__PURE__ */
|
|
524
|
+
onSettingsClick ? /* @__PURE__ */ jsxs2(DropdownMenuItem, { onClick: onSettingsClick, children: [
|
|
525
|
+
/* @__PURE__ */ jsx3(SettingsIcon, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }),
|
|
501
526
|
"Settings"
|
|
502
|
-
] }) : /* @__PURE__ */
|
|
503
|
-
/* @__PURE__ */
|
|
527
|
+
] }) : /* @__PURE__ */ jsx3(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs2(Link, { href: settingsHref, to: settingsHref, className: "flex items-center", children: [
|
|
528
|
+
/* @__PURE__ */ jsx3(SettingsIcon, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }),
|
|
504
529
|
"Settings"
|
|
505
530
|
] }) }),
|
|
506
|
-
onLogout && /* @__PURE__ */
|
|
507
|
-
/* @__PURE__ */
|
|
508
|
-
/* @__PURE__ */
|
|
509
|
-
/* @__PURE__ */
|
|
531
|
+
onLogout && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
532
|
+
/* @__PURE__ */ jsx3(DropdownMenuSeparator, {}),
|
|
533
|
+
/* @__PURE__ */ jsxs2(DropdownMenuItem, { className: "text-[var(--surface-danger-text)]", onClick: onLogout, children: [
|
|
534
|
+
/* @__PURE__ */ jsx3(LogOutIcon, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }),
|
|
510
535
|
"Sign Out"
|
|
511
536
|
] })
|
|
512
537
|
] })
|
|
@@ -516,7 +541,7 @@ function ProfileAvatar({
|
|
|
516
541
|
|
|
517
542
|
// src/dashboard/credit-balance.tsx
|
|
518
543
|
import * as React3 from "react";
|
|
519
|
-
import { jsx as
|
|
544
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
520
545
|
function CreditBalance({
|
|
521
546
|
amount,
|
|
522
547
|
description = "Credits are automatically deducted based on hourly Sandbox usage and Agent operations.",
|
|
@@ -525,7 +550,7 @@ function CreditBalance({
|
|
|
525
550
|
className
|
|
526
551
|
}) {
|
|
527
552
|
const [topUpValue, setTopUpValue] = React3.useState("50.00");
|
|
528
|
-
return /* @__PURE__ */
|
|
553
|
+
return /* @__PURE__ */ jsxs3(
|
|
529
554
|
"div",
|
|
530
555
|
{
|
|
531
556
|
className: cn(
|
|
@@ -533,17 +558,17 @@ function CreditBalance({
|
|
|
533
558
|
className
|
|
534
559
|
),
|
|
535
560
|
children: [
|
|
536
|
-
/* @__PURE__ */
|
|
537
|
-
/* @__PURE__ */
|
|
538
|
-
/* @__PURE__ */
|
|
561
|
+
/* @__PURE__ */ jsxs3("div", { children: [
|
|
562
|
+
/* @__PURE__ */ jsx4("h3", { className: "text-sm font-semibold text-muted-foreground uppercase tracking-widest mb-2", children: "Available Credits" }),
|
|
563
|
+
/* @__PURE__ */ jsxs3("div", { className: "text-4xl font-extrabold text-primary tracking-tighter mb-2", children: [
|
|
539
564
|
"$",
|
|
540
565
|
amount.toFixed(2)
|
|
541
566
|
] }),
|
|
542
|
-
/* @__PURE__ */
|
|
567
|
+
/* @__PURE__ */ jsx4("p", { className: "text-sm text-muted-foreground leading-relaxed", children: description })
|
|
543
568
|
] }),
|
|
544
|
-
onTopUp && /* @__PURE__ */
|
|
545
|
-
/* @__PURE__ */
|
|
546
|
-
/* @__PURE__ */
|
|
569
|
+
onTopUp && /* @__PURE__ */ jsxs3("div", { className: "space-y-2.5 mt-5", children: [
|
|
570
|
+
/* @__PURE__ */ jsxs3("div", { className: "bg-card border border-border p-1 rounded-lg flex items-center", children: [
|
|
571
|
+
/* @__PURE__ */ jsx4(
|
|
547
572
|
"input",
|
|
548
573
|
{
|
|
549
574
|
type: "text",
|
|
@@ -555,7 +580,7 @@ function CreditBalance({
|
|
|
555
580
|
className: "bg-transparent border-none text-foreground font-mono text-lg w-full focus:ring-0 px-4 outline-none"
|
|
556
581
|
}
|
|
557
582
|
),
|
|
558
|
-
/* @__PURE__ */
|
|
583
|
+
/* @__PURE__ */ jsx4(
|
|
559
584
|
"button",
|
|
560
585
|
{
|
|
561
586
|
type: "button",
|
|
@@ -569,7 +594,7 @@ function CreditBalance({
|
|
|
569
594
|
}
|
|
570
595
|
)
|
|
571
596
|
] }),
|
|
572
|
-
/* @__PURE__ */
|
|
597
|
+
/* @__PURE__ */ jsx4("div", { className: "flex justify-between gap-2", children: quickAmounts.filter((qa) => Number.isFinite(qa) && qa > 0).map((qa) => /* @__PURE__ */ jsxs3(
|
|
573
598
|
"button",
|
|
574
599
|
{
|
|
575
600
|
type: "button",
|
|
@@ -593,7 +618,7 @@ function CreditBalance({
|
|
|
593
618
|
}
|
|
594
619
|
|
|
595
620
|
// src/dashboard/out-of-credits.tsx
|
|
596
|
-
import { jsx as
|
|
621
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
597
622
|
var INSUFFICIENT_BALANCE_CODE = "insufficient_balance";
|
|
598
623
|
function parseInsufficientBalance(payload, opts = {}) {
|
|
599
624
|
if (!payload || typeof payload !== "object") return null;
|
|
@@ -616,7 +641,7 @@ function OutOfCreditsModal({
|
|
|
616
641
|
className
|
|
617
642
|
}) {
|
|
618
643
|
if (!balance) return null;
|
|
619
|
-
return /* @__PURE__ */
|
|
644
|
+
return /* @__PURE__ */ jsx5(
|
|
620
645
|
"div",
|
|
621
646
|
{
|
|
622
647
|
role: "dialog",
|
|
@@ -624,27 +649,27 @@ function OutOfCreditsModal({
|
|
|
624
649
|
"aria-label": "Out of credits",
|
|
625
650
|
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4",
|
|
626
651
|
onClick: onClose,
|
|
627
|
-
children: /* @__PURE__ */
|
|
652
|
+
children: /* @__PURE__ */ jsxs4(
|
|
628
653
|
"div",
|
|
629
654
|
{
|
|
630
655
|
className: cn(
|
|
631
|
-
"bg-card border border-border rounded-xl p-6 max-w-md w-full shadow-
|
|
656
|
+
"bg-card border border-border rounded-xl p-6 max-w-md w-full shadow-[var(--shadow-dropdown)]",
|
|
632
657
|
className
|
|
633
658
|
),
|
|
634
659
|
onClick: (e) => e.stopPropagation(),
|
|
635
660
|
children: [
|
|
636
|
-
/* @__PURE__ */
|
|
637
|
-
/* @__PURE__ */
|
|
661
|
+
/* @__PURE__ */ jsx5("h3", { className: "text-lg font-bold text-foreground mb-1", children: "You're out of credits" }),
|
|
662
|
+
/* @__PURE__ */ jsxs4("p", { className: "text-sm text-muted-foreground leading-relaxed mb-4", children: [
|
|
638
663
|
balance.message ?? "Add credits or start a subscription to keep going. Usage is billed to your Tangle account.",
|
|
639
|
-
typeof balance.remainingBalanceUsd === "number" && /* @__PURE__ */
|
|
664
|
+
typeof balance.remainingBalanceUsd === "number" && /* @__PURE__ */ jsxs4("span", { className: "block mt-1", children: [
|
|
640
665
|
"Balance: $",
|
|
641
666
|
balance.remainingBalanceUsd.toFixed(2),
|
|
642
667
|
balance.plan ? ` \xB7 ${balance.plan} plan` : ""
|
|
643
668
|
] })
|
|
644
669
|
] }),
|
|
645
|
-
/* @__PURE__ */
|
|
646
|
-
onClose && /* @__PURE__ */
|
|
647
|
-
/* @__PURE__ */
|
|
670
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex gap-2 justify-end", children: [
|
|
671
|
+
onClose && /* @__PURE__ */ jsx5(Button, { variant: "outline", onClick: onClose, children: "Not now" }),
|
|
672
|
+
/* @__PURE__ */ jsx5(Button, { asChild: true, children: /* @__PURE__ */ jsx5("a", { href: balance.manageUrl, target: "_blank", rel: "noopener noreferrer", children: ctaLabel }) })
|
|
648
673
|
] })
|
|
649
674
|
]
|
|
650
675
|
}
|
|
@@ -654,32 +679,32 @@ function OutOfCreditsModal({
|
|
|
654
679
|
}
|
|
655
680
|
|
|
656
681
|
// src/dashboard/cluster-status-bar.tsx
|
|
657
|
-
import { Fragment as
|
|
682
|
+
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
658
683
|
function ClusterStatusBar({ items, latency, className }) {
|
|
659
684
|
if (!items?.length) return null;
|
|
660
|
-
return /* @__PURE__ */
|
|
661
|
-
/* @__PURE__ */
|
|
662
|
-
/* @__PURE__ */
|
|
663
|
-
/* @__PURE__ */
|
|
664
|
-
/* @__PURE__ */
|
|
665
|
-
/* @__PURE__ */
|
|
685
|
+
return /* @__PURE__ */ jsx6("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__ */ jsxs5("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: [
|
|
686
|
+
/* @__PURE__ */ jsx6("div", { className: "flex items-center gap-6", children: items.map((item, i) => /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
|
|
687
|
+
/* @__PURE__ */ jsx6("span", { className: "text-[var(--md3-primary)] [&_svg]:h-[18px] [&_svg]:w-[18px]", children: item.icon }),
|
|
688
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col", children: [
|
|
689
|
+
/* @__PURE__ */ jsx6("span", { className: "text-[10px] text-[var(--md3-on-surface-variant)] uppercase tracking-wider font-bold", children: item.label }),
|
|
690
|
+
/* @__PURE__ */ jsx6("span", { className: cn("text-xs font-bold text-foreground", item.valueClass), children: item.value })
|
|
666
691
|
] })
|
|
667
692
|
] }, i)) }),
|
|
668
|
-
latency && /* @__PURE__ */
|
|
669
|
-
/* @__PURE__ */
|
|
670
|
-
/* @__PURE__ */
|
|
671
|
-
/* @__PURE__ */
|
|
672
|
-
/* @__PURE__ */
|
|
673
|
-
/* @__PURE__ */
|
|
693
|
+
latency && /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
694
|
+
/* @__PURE__ */ jsx6("div", { className: "h-6 w-px bg-border" }),
|
|
695
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3", children: [
|
|
696
|
+
/* @__PURE__ */ jsxs5("div", { className: "relative flex h-2.5 w-2.5 items-center justify-center", children: [
|
|
697
|
+
/* @__PURE__ */ jsx6("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-green-400 opacity-75" }),
|
|
698
|
+
/* @__PURE__ */ jsx6("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-green-500" })
|
|
674
699
|
] }),
|
|
675
|
-
/* @__PURE__ */
|
|
700
|
+
/* @__PURE__ */ jsx6("span", { className: "text-xs font-mono text-green-400 font-bold", children: latency })
|
|
676
701
|
] })
|
|
677
702
|
] })
|
|
678
703
|
] }) });
|
|
679
704
|
}
|
|
680
705
|
|
|
681
706
|
// src/dashboard/resource-meter.tsx
|
|
682
|
-
import { jsx as
|
|
707
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
683
708
|
function getBarColor(percent) {
|
|
684
709
|
if (percent >= 90) return "bg-[var(--code-error)]";
|
|
685
710
|
if (percent >= 70) return "bg-[var(--surface-warning-text)]";
|
|
@@ -689,25 +714,25 @@ function ResourceMeter({ label, value, max = 100, unit, valueLabel, icon, classN
|
|
|
689
714
|
const percent = max > 0 ? Math.max(0, Math.min(value / max * 100, 100)) : 0;
|
|
690
715
|
const barColor = getBarColor(percent);
|
|
691
716
|
const readout = valueLabel ?? (unit ? `${value}${unit}/${max}${unit}` : `${Math.round(percent)}%`);
|
|
692
|
-
return /* @__PURE__ */
|
|
693
|
-
/* @__PURE__ */
|
|
717
|
+
return /* @__PURE__ */ jsxs6("div", { className: cn("flex items-center gap-3", className), children: [
|
|
718
|
+
/* @__PURE__ */ jsxs6("span", { className: "flex shrink-0 items-center gap-1 text-[10px] font-mono text-muted-foreground uppercase tracking-wide", children: [
|
|
694
719
|
icon,
|
|
695
720
|
label
|
|
696
721
|
] }),
|
|
697
|
-
/* @__PURE__ */
|
|
722
|
+
/* @__PURE__ */ jsx7("div", { className: "h-1.5 min-w-0 flex-1 bg-card rounded-full overflow-hidden", children: /* @__PURE__ */ jsx7(
|
|
698
723
|
"div",
|
|
699
724
|
{
|
|
700
725
|
className: cn("h-full rounded-full transition-all duration-500", barColor),
|
|
701
726
|
style: { width: `${percent}%` }
|
|
702
727
|
}
|
|
703
728
|
) }),
|
|
704
|
-
/* @__PURE__ */
|
|
729
|
+
/* @__PURE__ */ jsx7("span", { className: "shrink-0 text-[10px] font-mono tabular-nums text-muted-foreground", children: readout })
|
|
705
730
|
] });
|
|
706
731
|
}
|
|
707
732
|
|
|
708
733
|
// src/dashboard/resource-snapshot.tsx
|
|
709
734
|
import { Skeleton as Skeleton2 } from "@tangle-network/ui/primitives";
|
|
710
|
-
import { jsx as
|
|
735
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
711
736
|
function ResourceSnapshot({
|
|
712
737
|
title = "Resources",
|
|
713
738
|
action,
|
|
@@ -717,7 +742,7 @@ function ResourceSnapshot({
|
|
|
717
742
|
className
|
|
718
743
|
}) {
|
|
719
744
|
const rowCount = items.length > 0 ? items.length : 3;
|
|
720
|
-
return /* @__PURE__ */
|
|
745
|
+
return /* @__PURE__ */ jsxs7(
|
|
721
746
|
"div",
|
|
722
747
|
{
|
|
723
748
|
className: cn(
|
|
@@ -725,11 +750,11 @@ function ResourceSnapshot({
|
|
|
725
750
|
className
|
|
726
751
|
),
|
|
727
752
|
children: [
|
|
728
|
-
/* @__PURE__ */
|
|
729
|
-
/* @__PURE__ */
|
|
753
|
+
/* @__PURE__ */ jsxs7("div", { className: "mb-4 flex items-center justify-between gap-2", children: [
|
|
754
|
+
/* @__PURE__ */ jsx8("h3", { className: "font-display font-semibold text-foreground text-sm", children: title }),
|
|
730
755
|
action
|
|
731
756
|
] }),
|
|
732
|
-
error ? /* @__PURE__ */
|
|
757
|
+
error ? /* @__PURE__ */ jsx8("p", { className: "text-[var(--surface-danger-text)] text-xs", children: error }) : loading ? /* @__PURE__ */ jsx8("div", { className: "space-y-3", children: Array.from({ length: rowCount }).map((_, i) => /* @__PURE__ */ jsx8(Skeleton2, { className: "h-4 w-full" }, i)) }) : /* @__PURE__ */ jsx8("div", { className: "space-y-3", children: items.map((item, idx) => /* @__PURE__ */ jsx8(
|
|
733
758
|
ResourceMeter,
|
|
734
759
|
{
|
|
735
760
|
label: item.label,
|
|
@@ -750,7 +775,7 @@ function ResourceSnapshot({
|
|
|
750
775
|
import * as React4 from "react";
|
|
751
776
|
import { Skeleton as Skeleton3 } from "@tangle-network/ui/primitives";
|
|
752
777
|
import { timeAgo } from "@tangle-network/ui/utils";
|
|
753
|
-
import { jsx as
|
|
778
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
754
779
|
function ActivityFeed({
|
|
755
780
|
title = "Recent activity",
|
|
756
781
|
action,
|
|
@@ -764,7 +789,7 @@ function ActivityFeed({
|
|
|
764
789
|
() => [...items].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0)).slice(0, maxItems),
|
|
765
790
|
[items, maxItems]
|
|
766
791
|
);
|
|
767
|
-
return /* @__PURE__ */
|
|
792
|
+
return /* @__PURE__ */ jsxs8(
|
|
768
793
|
"div",
|
|
769
794
|
{
|
|
770
795
|
className: cn(
|
|
@@ -772,17 +797,17 @@ function ActivityFeed({
|
|
|
772
797
|
className
|
|
773
798
|
),
|
|
774
799
|
children: [
|
|
775
|
-
/* @__PURE__ */
|
|
776
|
-
/* @__PURE__ */
|
|
800
|
+
/* @__PURE__ */ jsxs8("div", { className: "mb-4 flex items-center justify-between gap-2", children: [
|
|
801
|
+
/* @__PURE__ */ jsx9("h3", { className: "font-display font-semibold text-foreground text-sm", children: title }),
|
|
777
802
|
action
|
|
778
803
|
] }),
|
|
779
|
-
loading ? /* @__PURE__ */
|
|
780
|
-
item.icon && /* @__PURE__ */
|
|
781
|
-
/* @__PURE__ */
|
|
782
|
-
/* @__PURE__ */
|
|
783
|
-
item.detail && /* @__PURE__ */
|
|
804
|
+
loading ? /* @__PURE__ */ jsx9("div", { className: "space-y-3", children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsx9(Skeleton3, { className: "h-9 w-full" }, i)) }) : sorted.length === 0 ? /* @__PURE__ */ jsx9("p", { className: "text-muted-foreground text-sm", children: emptyLabel }) : /* @__PURE__ */ jsx9("ul", { className: "space-y-3", children: sorted.map((item) => /* @__PURE__ */ jsxs8("li", { className: "flex items-start gap-3", children: [
|
|
805
|
+
item.icon && /* @__PURE__ */ jsx9("span", { className: "mt-0.5 shrink-0 text-muted-foreground", children: item.icon }),
|
|
806
|
+
/* @__PURE__ */ jsxs8("div", { className: "min-w-0 flex-1", children: [
|
|
807
|
+
/* @__PURE__ */ jsx9("p", { className: "truncate font-medium text-foreground text-sm", children: item.title }),
|
|
808
|
+
item.detail && /* @__PURE__ */ jsx9("p", { className: "truncate text-muted-foreground text-xs", children: item.detail })
|
|
784
809
|
] }),
|
|
785
|
-
item.timestamp != null && /* @__PURE__ */
|
|
810
|
+
item.timestamp != null && /* @__PURE__ */ jsx9("span", { className: "shrink-0 text-muted-foreground text-xs tabular-nums", children: timeAgo(item.timestamp) })
|
|
786
811
|
] }, item.id)) })
|
|
787
812
|
]
|
|
788
813
|
}
|
|
@@ -813,7 +838,7 @@ import {
|
|
|
813
838
|
Plus,
|
|
814
839
|
Users
|
|
815
840
|
} from "lucide-react";
|
|
816
|
-
import { Fragment as
|
|
841
|
+
import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
817
842
|
function canAdminSandbox(sandbox) {
|
|
818
843
|
if (!sandbox.team) return true;
|
|
819
844
|
return sandbox.team.role === "owner" || sandbox.team.role === "admin";
|
|
@@ -836,115 +861,115 @@ function SandboxCard({
|
|
|
836
861
|
const isRunning = sandbox.status === "running";
|
|
837
862
|
const isTransitioning = sandbox.status === "provisioning" || sandbox.status === "creating";
|
|
838
863
|
const isStopped = !isRunning && !isTransitioning;
|
|
839
|
-
return /* @__PURE__ */
|
|
864
|
+
return /* @__PURE__ */ jsxs9("div", { className: cn(
|
|
840
865
|
"group relative flex flex-col justify-between overflow-hidden rounded-lg border bg-card p-5 transition-colors",
|
|
841
866
|
isRunning ? "border-[var(--status-running)]/30" : "border-border",
|
|
842
867
|
"hover:border-foreground/15",
|
|
843
868
|
className
|
|
844
869
|
), children: [
|
|
845
|
-
/* @__PURE__ */
|
|
846
|
-
/* @__PURE__ */
|
|
847
|
-
/* @__PURE__ */
|
|
848
|
-
/* @__PURE__ */
|
|
870
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-start justify-between", children: [
|
|
871
|
+
/* @__PURE__ */ jsxs9("div", { children: [
|
|
872
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
873
|
+
/* @__PURE__ */ jsxs9("h3", { className: "flex items-center gap-2 text-sm font-bold text-foreground", children: [
|
|
849
874
|
sandbox.name,
|
|
850
|
-
isRunning && /* @__PURE__ */
|
|
851
|
-
/* @__PURE__ */
|
|
852
|
-
/* @__PURE__ */
|
|
875
|
+
isRunning && /* @__PURE__ */ jsxs9("span", { className: "relative flex h-2 w-2", children: [
|
|
876
|
+
/* @__PURE__ */ jsx10("span", { className: "absolute inline-flex h-full w-full animate-pulse rounded-full bg-[var(--status-running)] opacity-75" }),
|
|
877
|
+
/* @__PURE__ */ jsx10("span", { className: "relative inline-flex h-1.5 w-1.5 rounded-full bg-[var(--status-running)]" })
|
|
853
878
|
] })
|
|
854
879
|
] }),
|
|
855
|
-
sandbox.team && /* @__PURE__ */
|
|
880
|
+
sandbox.team && /* @__PURE__ */ jsxs9(
|
|
856
881
|
"span",
|
|
857
882
|
{
|
|
858
883
|
className: "inline-flex items-center gap-1 rounded-full bg-[var(--accent-surface-soft)] px-2 py-0.5 text-[10px] font-semibold text-[var(--accent-text)]",
|
|
859
884
|
title: `Shared with ${sandbox.team.name ?? "Team"} \xB7 ${sandbox.team.role}`,
|
|
860
885
|
children: [
|
|
861
|
-
/* @__PURE__ */
|
|
886
|
+
/* @__PURE__ */ jsx10(Users, { className: "h-3 w-3", "aria-hidden": "true" }),
|
|
862
887
|
sandbox.team.name ?? "Team"
|
|
863
888
|
]
|
|
864
889
|
}
|
|
865
890
|
)
|
|
866
891
|
] }),
|
|
867
|
-
/* @__PURE__ */
|
|
892
|
+
/* @__PURE__ */ jsxs9("p", { className: "mt-0.5 font-mono text-[10px] tracking-wider text-muted-foreground uppercase", children: [
|
|
868
893
|
sandbox.nodeId || "Unknown Node",
|
|
869
|
-
sandbox.team && /* @__PURE__ */
|
|
894
|
+
sandbox.team && /* @__PURE__ */ jsxs9("span", { className: "ml-2 normal-case tracking-normal", children: [
|
|
870
895
|
"\xB7 your role: ",
|
|
871
896
|
sandbox.team.role
|
|
872
897
|
] })
|
|
873
898
|
] })
|
|
874
899
|
] }),
|
|
875
|
-
/* @__PURE__ */
|
|
876
|
-
/* @__PURE__ */
|
|
900
|
+
/* @__PURE__ */ jsxs9(DropdownMenu2, { children: [
|
|
901
|
+
/* @__PURE__ */ jsx10(DropdownMenuTrigger2, { asChild: true, children: /* @__PURE__ */ jsx10(
|
|
877
902
|
"button",
|
|
878
903
|
{
|
|
879
904
|
type: "button",
|
|
880
905
|
className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground outline-none",
|
|
881
906
|
"aria-label": "Sandbox options",
|
|
882
|
-
children: /* @__PURE__ */
|
|
907
|
+
children: /* @__PURE__ */ jsx10(MoreVertical, { className: "h-4 w-4" })
|
|
883
908
|
}
|
|
884
909
|
) }),
|
|
885
|
-
/* @__PURE__ */
|
|
886
|
-
isRunning && /* @__PURE__ */
|
|
887
|
-
onStop && /* @__PURE__ */
|
|
888
|
-
/* @__PURE__ */
|
|
910
|
+
/* @__PURE__ */ jsxs9(DropdownMenuContent2, { align: "end", className: "min-w-[180px]", children: [
|
|
911
|
+
isRunning && /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
912
|
+
onStop && /* @__PURE__ */ jsxs9(DropdownMenuItem2, { onClick: () => onStop(sandbox.id), children: [
|
|
913
|
+
/* @__PURE__ */ jsx10(PowerOff, { className: "mr-2 h-4 w-4" }),
|
|
889
914
|
" Stop Sandbox"
|
|
890
915
|
] }),
|
|
891
|
-
onKeepAlive && /* @__PURE__ */
|
|
892
|
-
/* @__PURE__ */
|
|
916
|
+
onKeepAlive && /* @__PURE__ */ jsxs9(DropdownMenuItem2, { onClick: () => onKeepAlive(sandbox.id), children: [
|
|
917
|
+
/* @__PURE__ */ jsx10(Clock, { className: "mr-2 h-4 w-4" }),
|
|
893
918
|
" Keep Alive"
|
|
894
919
|
] }),
|
|
895
|
-
(onStop || onKeepAlive) && /* @__PURE__ */
|
|
896
|
-
onUsage && /* @__PURE__ */
|
|
897
|
-
/* @__PURE__ */
|
|
920
|
+
(onStop || onKeepAlive) && /* @__PURE__ */ jsx10(DropdownMenuSeparator2, {}),
|
|
921
|
+
onUsage && /* @__PURE__ */ jsxs9(DropdownMenuItem2, { onClick: () => onUsage(sandbox.id), children: [
|
|
922
|
+
/* @__PURE__ */ jsx10(BarChart2, { className: "mr-2 h-4 w-4" }),
|
|
898
923
|
" View Usage"
|
|
899
924
|
] }),
|
|
900
|
-
onHealth && /* @__PURE__ */
|
|
901
|
-
/* @__PURE__ */
|
|
925
|
+
onHealth && /* @__PURE__ */ jsxs9(DropdownMenuItem2, { onClick: () => onHealth(sandbox.id), children: [
|
|
926
|
+
/* @__PURE__ */ jsx10(Activity, { className: "mr-2 h-4 w-4" }),
|
|
902
927
|
" Health Check"
|
|
903
928
|
] }),
|
|
904
|
-
(onUsage || onHealth) && /* @__PURE__ */
|
|
905
|
-
onFork && /* @__PURE__ */
|
|
906
|
-
/* @__PURE__ */
|
|
907
|
-
/* @__PURE__ */
|
|
929
|
+
(onUsage || onHealth) && /* @__PURE__ */ jsx10(DropdownMenuSeparator2, {}),
|
|
930
|
+
onFork && /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
931
|
+
/* @__PURE__ */ jsxs9(DropdownMenuItem2, { onClick: () => onFork(sandbox.id), children: [
|
|
932
|
+
/* @__PURE__ */ jsx10(Copy, { className: "mr-2 h-4 w-4" }),
|
|
908
933
|
" Fork Sandbox"
|
|
909
934
|
] }),
|
|
910
|
-
/* @__PURE__ */
|
|
935
|
+
/* @__PURE__ */ jsx10(DropdownMenuSeparator2, {})
|
|
911
936
|
] })
|
|
912
937
|
] }),
|
|
913
|
-
isStopped && /* @__PURE__ */
|
|
914
|
-
onResume && /* @__PURE__ */
|
|
915
|
-
/* @__PURE__ */
|
|
938
|
+
isStopped && /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
939
|
+
onResume && /* @__PURE__ */ jsxs9(DropdownMenuItem2, { onClick: () => onResume(sandbox.id), children: [
|
|
940
|
+
/* @__PURE__ */ jsx10(Power, { className: "mr-2 h-4 w-4" }),
|
|
916
941
|
" Resume Sandbox"
|
|
917
942
|
] }),
|
|
918
|
-
onFork && /* @__PURE__ */
|
|
919
|
-
/* @__PURE__ */
|
|
943
|
+
onFork && /* @__PURE__ */ jsxs9(DropdownMenuItem2, { onClick: () => onFork(sandbox.id), children: [
|
|
944
|
+
/* @__PURE__ */ jsx10(Copy, { className: "mr-2 h-4 w-4" }),
|
|
920
945
|
" Fork Sandbox"
|
|
921
946
|
] }),
|
|
922
|
-
(onResume || onFork) && /* @__PURE__ */
|
|
947
|
+
(onResume || onFork) && /* @__PURE__ */ jsx10(DropdownMenuSeparator2, {})
|
|
923
948
|
] }),
|
|
924
|
-
onDelete && canAdminSandbox(sandbox) && /* @__PURE__ */
|
|
925
|
-
/* @__PURE__ */
|
|
949
|
+
onDelete && canAdminSandbox(sandbox) && /* @__PURE__ */ jsxs9(DropdownMenuItem2, { className: "text-destructive focus:bg-destructive/10 focus:text-destructive", onClick: () => onDelete(sandbox.id), children: [
|
|
950
|
+
/* @__PURE__ */ jsx10(Trash2, { className: "mr-2 h-4 w-4" }),
|
|
926
951
|
" Delete Sandbox"
|
|
927
952
|
] })
|
|
928
953
|
] })
|
|
929
954
|
] })
|
|
930
955
|
] }),
|
|
931
|
-
/* @__PURE__ */
|
|
932
|
-
/* @__PURE__ */
|
|
933
|
-
/* @__PURE__ */
|
|
934
|
-
/* @__PURE__ */
|
|
935
|
-
/* @__PURE__ */
|
|
936
|
-
/* @__PURE__ */
|
|
956
|
+
/* @__PURE__ */ jsxs9("div", { className: "my-4", children: [
|
|
957
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3 rounded-md border border-border bg-muted/30 p-3", children: [
|
|
958
|
+
/* @__PURE__ */ jsx10("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__ */ jsx10(Code2, { className: cn("h-5 w-5", isRunning ? "text-[var(--surface-success-text)]" : "text-muted-foreground") }) : /* @__PURE__ */ jsx10(Terminal, { className: cn("h-5 w-5", isRunning ? "text-[var(--surface-success-text)]" : "text-muted-foreground") }) }),
|
|
959
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-col", children: [
|
|
960
|
+
/* @__PURE__ */ jsx10("span", { className: "text-[10px] text-muted-foreground uppercase tracking-widest font-bold", children: "Environment" }),
|
|
961
|
+
/* @__PURE__ */ jsx10("span", { className: "text-xs font-medium text-foreground font-mono mt-0.5", children: sandbox.image || "Universal" })
|
|
937
962
|
] })
|
|
938
963
|
] }),
|
|
939
|
-
isTransitioning && /* @__PURE__ */
|
|
940
|
-
/* @__PURE__ */
|
|
941
|
-
/* @__PURE__ */
|
|
942
|
-
/* @__PURE__ */
|
|
964
|
+
isTransitioning && /* @__PURE__ */ jsxs9("div", { className: "mt-3", children: [
|
|
965
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex justify-between text-xs text-muted-foreground font-medium mb-1", children: [
|
|
966
|
+
/* @__PURE__ */ jsx10("span", { children: sandbox.provisioningMessage || "Starting..." }),
|
|
967
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
943
968
|
sandbox.provisioningPercent || 0,
|
|
944
969
|
"%"
|
|
945
970
|
] })
|
|
946
971
|
] }),
|
|
947
|
-
/* @__PURE__ */
|
|
972
|
+
/* @__PURE__ */ jsx10("div", { className: "h-1 w-full overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx10(
|
|
948
973
|
"div",
|
|
949
974
|
{
|
|
950
975
|
className: "h-full bg-primary transition-all duration-500 rounded-full",
|
|
@@ -953,18 +978,18 @@ function SandboxCard({
|
|
|
953
978
|
) })
|
|
954
979
|
] })
|
|
955
980
|
] }),
|
|
956
|
-
/* @__PURE__ */
|
|
981
|
+
/* @__PURE__ */ jsx10("div", { className: "border-t border-border pt-3", children: isRunning ? /* @__PURE__ */ jsxs9(
|
|
957
982
|
"button",
|
|
958
983
|
{
|
|
959
984
|
type: "button",
|
|
960
985
|
onClick: () => onOpenIDE?.(sandbox.id),
|
|
961
986
|
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]",
|
|
962
987
|
children: [
|
|
963
|
-
/* @__PURE__ */
|
|
988
|
+
/* @__PURE__ */ jsx10(Network, { className: "h-4 w-4" }),
|
|
964
989
|
"Connect Session"
|
|
965
990
|
]
|
|
966
991
|
}
|
|
967
|
-
) : /* @__PURE__ */
|
|
992
|
+
) : /* @__PURE__ */ jsxs9(
|
|
968
993
|
"button",
|
|
969
994
|
{
|
|
970
995
|
type: "button",
|
|
@@ -975,7 +1000,7 @@ function SandboxCard({
|
|
|
975
1000
|
isTransitioning ? "bg-muted text-muted-foreground cursor-not-allowed border-border" : "bg-card text-foreground hover:bg-muted border-border active:scale-[0.97]"
|
|
976
1001
|
),
|
|
977
1002
|
children: [
|
|
978
|
-
/* @__PURE__ */
|
|
1003
|
+
/* @__PURE__ */ jsx10(Play, { className: "h-4 w-4" }),
|
|
979
1004
|
isTransitioning ? "Starting..." : "Wake Sandbox"
|
|
980
1005
|
]
|
|
981
1006
|
}
|
|
@@ -983,7 +1008,7 @@ function SandboxCard({
|
|
|
983
1008
|
] });
|
|
984
1009
|
}
|
|
985
1010
|
function NewSandboxCard({ onClick, className }) {
|
|
986
|
-
return /* @__PURE__ */
|
|
1011
|
+
return /* @__PURE__ */ jsxs9(
|
|
987
1012
|
"button",
|
|
988
1013
|
{
|
|
989
1014
|
type: "button",
|
|
@@ -993,9 +1018,9 @@ function NewSandboxCard({ onClick, className }) {
|
|
|
993
1018
|
className
|
|
994
1019
|
),
|
|
995
1020
|
children: [
|
|
996
|
-
/* @__PURE__ */
|
|
997
|
-
/* @__PURE__ */
|
|
998
|
-
/* @__PURE__ */
|
|
1021
|
+
/* @__PURE__ */ jsx10("div", { className: "flex h-12 w-12 items-center justify-center rounded-lg bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx10(Plus, { className: "h-6 w-6" }) }),
|
|
1022
|
+
/* @__PURE__ */ jsx10("span", { className: "mt-4 text-sm font-semibold text-foreground", children: "New Sandbox" }),
|
|
1023
|
+
/* @__PURE__ */ jsx10("span", { className: "mt-1 text-xs text-muted-foreground", children: "Deploy a new isolated environment" })
|
|
999
1024
|
]
|
|
1000
1025
|
}
|
|
1001
1026
|
);
|
|
@@ -1029,7 +1054,7 @@ import {
|
|
|
1029
1054
|
DropdownMenuSeparator as DropdownMenuSeparator3,
|
|
1030
1055
|
DropdownMenuTrigger as DropdownMenuTrigger3
|
|
1031
1056
|
} from "@tangle-network/ui/primitives";
|
|
1032
|
-
import { Fragment as
|
|
1057
|
+
import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1033
1058
|
var statusColors = {
|
|
1034
1059
|
running: { dot: "bg-[var(--code-success)] animate-pulse", text: "text-[var(--code-success)]", bar: "bg-[var(--code-success)]" },
|
|
1035
1060
|
hibernating: { dot: "bg-muted-foreground", text: "text-muted-foreground", bar: "bg-muted-foreground" },
|
|
@@ -1043,15 +1068,15 @@ function isResumable(status) {
|
|
|
1043
1068
|
return status !== "running" && status !== "provisioning" && status !== "creating";
|
|
1044
1069
|
}
|
|
1045
1070
|
function MiniMeter({ label, percent, className }) {
|
|
1046
|
-
return /* @__PURE__ */
|
|
1047
|
-
/* @__PURE__ */
|
|
1048
|
-
/* @__PURE__ */
|
|
1049
|
-
/* @__PURE__ */
|
|
1071
|
+
return /* @__PURE__ */ jsxs10("div", { className: cn("space-y-1", className), children: [
|
|
1072
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex justify-between text-[10px] font-mono text-muted-foreground", children: [
|
|
1073
|
+
/* @__PURE__ */ jsx11("span", { className: "font-bold", children: label }),
|
|
1074
|
+
/* @__PURE__ */ jsxs10("span", { className: "text-primary", children: [
|
|
1050
1075
|
percent,
|
|
1051
1076
|
"%"
|
|
1052
1077
|
] })
|
|
1053
1078
|
] }),
|
|
1054
|
-
/* @__PURE__ */
|
|
1079
|
+
/* @__PURE__ */ jsx11("div", { className: "h-1.5 w-full bg-background rounded-full overflow-hidden", children: /* @__PURE__ */ jsx11("div", { className: "h-full bg-primary rounded-full", style: { width: `${percent}%` } }) })
|
|
1055
1080
|
] });
|
|
1056
1081
|
}
|
|
1057
1082
|
function SandboxTable({
|
|
@@ -1090,17 +1115,17 @@ function SandboxTable({
|
|
|
1090
1115
|
const handler = resolveResumeHandler(sb.status);
|
|
1091
1116
|
return handler ? () => handler(sb.id) : void 0;
|
|
1092
1117
|
};
|
|
1093
|
-
return /* @__PURE__ */
|
|
1094
|
-
/* @__PURE__ */
|
|
1095
|
-
/* @__PURE__ */
|
|
1096
|
-
/* @__PURE__ */
|
|
1097
|
-
/* @__PURE__ */
|
|
1098
|
-
hasTeamSandboxes && /* @__PURE__ */
|
|
1099
|
-
/* @__PURE__ */
|
|
1100
|
-
/* @__PURE__ */
|
|
1101
|
-
/* @__PURE__ */
|
|
1118
|
+
return /* @__PURE__ */ jsxs10("div", { className: cn("w-full", className), children: [
|
|
1119
|
+
/* @__PURE__ */ jsx11("div", { className: "w-full bg-card rounded-2xl overflow-hidden border border-border", children: /* @__PURE__ */ jsx11("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs10("table", { className: "w-full text-left border-collapse", children: [
|
|
1120
|
+
/* @__PURE__ */ jsx11("thead", { children: /* @__PURE__ */ jsxs10("tr", { className: "bg-background border-b border-border", children: [
|
|
1121
|
+
/* @__PURE__ */ jsx11("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Status" }),
|
|
1122
|
+
/* @__PURE__ */ jsx11("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Sandbox Name" }),
|
|
1123
|
+
hasTeamSandboxes && /* @__PURE__ */ jsx11("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Scope" }),
|
|
1124
|
+
/* @__PURE__ */ jsx11("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Environment" }),
|
|
1125
|
+
/* @__PURE__ */ jsx11("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Resources" }),
|
|
1126
|
+
/* @__PURE__ */ jsx11("th", { className: "px-6 py-4 text-xs font-semibold text-muted-foreground uppercase tracking-wider text-right", children: "Actions" })
|
|
1102
1127
|
] }) }),
|
|
1103
|
-
/* @__PURE__ */
|
|
1128
|
+
/* @__PURE__ */ jsx11("tbody", { className: "divide-y divide-border", children: sandboxes.map((sb) => {
|
|
1104
1129
|
const sc = statusColors[sb.status] ?? statusColors.stopped;
|
|
1105
1130
|
const isActive = sb.status === "running";
|
|
1106
1131
|
const isHibernating = sb.status === "hibernating";
|
|
@@ -1122,7 +1147,7 @@ function SandboxTable({
|
|
|
1122
1147
|
// IDE, Delete, …), which keep their native
|
|
1123
1148
|
// semantics. Mouse users get the click-anywhere
|
|
1124
1149
|
// affordance; nobody loses access.
|
|
1125
|
-
/* @__PURE__ */
|
|
1150
|
+
/* @__PURE__ */ jsxs10(
|
|
1126
1151
|
"tr",
|
|
1127
1152
|
{
|
|
1128
1153
|
className: cn(
|
|
@@ -1131,69 +1156,69 @@ function SandboxTable({
|
|
|
1131
1156
|
),
|
|
1132
1157
|
onClick: onRowClick,
|
|
1133
1158
|
children: [
|
|
1134
|
-
/* @__PURE__ */
|
|
1135
|
-
/* @__PURE__ */
|
|
1136
|
-
/* @__PURE__ */
|
|
1159
|
+
/* @__PURE__ */ jsx11("td", { className: "px-6 py-5 whitespace-nowrap", children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
|
|
1160
|
+
/* @__PURE__ */ jsx11("span", { className: cn("flex h-2.5 w-2.5 rounded-full", sc.dot) }),
|
|
1161
|
+
/* @__PURE__ */ jsx11("span", { className: cn("text-xs font-bold uppercase tracking-wide", sc.text), children: sb.status.charAt(0).toUpperCase() + sb.status.slice(1) })
|
|
1137
1162
|
] }) }),
|
|
1138
|
-
/* @__PURE__ */
|
|
1139
|
-
/* @__PURE__ */
|
|
1140
|
-
sb.nodeId && /* @__PURE__ */
|
|
1163
|
+
/* @__PURE__ */ jsx11("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsxs10("div", { className: "flex flex-col", children: [
|
|
1164
|
+
/* @__PURE__ */ jsx11("span", { className: "text-sm font-bold text-foreground group-hover:text-primary transition-colors", children: sb.name }),
|
|
1165
|
+
sb.nodeId && /* @__PURE__ */ jsx11("span", { className: "text-[10px] font-mono text-muted-foreground", children: sb.nodeId })
|
|
1141
1166
|
] }) }),
|
|
1142
|
-
hasTeamSandboxes && /* @__PURE__ */
|
|
1167
|
+
hasTeamSandboxes && /* @__PURE__ */ jsx11("td", { className: "px-6 py-5", children: sb.team ? /* @__PURE__ */ jsxs10(
|
|
1143
1168
|
"div",
|
|
1144
1169
|
{
|
|
1145
1170
|
className: "inline-flex items-center gap-1.5 rounded-full bg-[var(--accent-surface-soft)] px-2.5 py-1 text-[11px] font-semibold text-[var(--accent-text)]",
|
|
1146
1171
|
title: `Shared with ${sb.team.name ?? "Team"} \xB7 ${sb.team.role}`,
|
|
1147
1172
|
children: [
|
|
1148
|
-
/* @__PURE__ */
|
|
1149
|
-
/* @__PURE__ */
|
|
1150
|
-
/* @__PURE__ */
|
|
1173
|
+
/* @__PURE__ */ jsx11(Users2, { className: "h-3 w-3", "aria-hidden": "true" }),
|
|
1174
|
+
/* @__PURE__ */ jsx11("span", { children: sb.team.name ?? "Team" }),
|
|
1175
|
+
/* @__PURE__ */ jsxs10("span", { className: "font-normal text-muted-foreground", children: [
|
|
1151
1176
|
"\xB7 ",
|
|
1152
1177
|
sb.team.role
|
|
1153
1178
|
] })
|
|
1154
1179
|
]
|
|
1155
1180
|
}
|
|
1156
|
-
) : /* @__PURE__ */
|
|
1181
|
+
) : /* @__PURE__ */ jsxs10(
|
|
1157
1182
|
"div",
|
|
1158
1183
|
{
|
|
1159
1184
|
className: "inline-flex items-center gap-1.5 rounded-full bg-muted px-2.5 py-1 text-[11px] font-medium text-muted-foreground",
|
|
1160
1185
|
title: "Personal sandbox",
|
|
1161
1186
|
children: [
|
|
1162
|
-
/* @__PURE__ */
|
|
1187
|
+
/* @__PURE__ */ jsx11(User, { className: "h-3 w-3", "aria-hidden": "true" }),
|
|
1163
1188
|
"Personal"
|
|
1164
1189
|
]
|
|
1165
1190
|
}
|
|
1166
1191
|
) }),
|
|
1167
|
-
/* @__PURE__ */
|
|
1168
|
-
sb.imageIcon && /* @__PURE__ */
|
|
1169
|
-
sb.image && /* @__PURE__ */
|
|
1192
|
+
/* @__PURE__ */ jsx11("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-3", children: [
|
|
1193
|
+
sb.imageIcon && /* @__PURE__ */ jsx11("div", { className: "w-8 h-8 rounded-lg bg-muted/50 flex items-center justify-center", children: sb.imageIcon }),
|
|
1194
|
+
sb.image && /* @__PURE__ */ jsx11("span", { className: "text-xs font-bold text-foreground", children: sb.image })
|
|
1170
1195
|
] }) }),
|
|
1171
|
-
/* @__PURE__ */
|
|
1172
|
-
/* @__PURE__ */
|
|
1173
|
-
/* @__PURE__ */
|
|
1174
|
-
] }) : isProvisioning ? /* @__PURE__ */
|
|
1175
|
-
/* @__PURE__ */
|
|
1196
|
+
/* @__PURE__ */ jsx11("td", { className: "px-6 py-5", children: isActive ? /* @__PURE__ */ jsxs10("div", { className: "space-y-3 w-48", children: [
|
|
1197
|
+
/* @__PURE__ */ jsx11(MiniMeter, { label: "CPU", percent: sb.cpuPercent ?? 0 }),
|
|
1198
|
+
/* @__PURE__ */ jsx11(MiniMeter, { label: "RAM", percent: sb.ramTotal ? Math.round((sb.ramUsed ?? 0) / sb.ramTotal * 100) : 0 })
|
|
1199
|
+
] }) : isProvisioning ? /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2 text-primary italic text-[10px] font-bold", children: [
|
|
1200
|
+
/* @__PURE__ */ jsx11(RefreshCw, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
1176
1201
|
sb.provisioningMessage ?? "Allocating nodes..."
|
|
1177
|
-
] }) : isHibernating ? /* @__PURE__ */
|
|
1178
|
-
/* @__PURE__ */
|
|
1179
|
-
/* @__PURE__ */
|
|
1202
|
+
] }) : isHibernating ? /* @__PURE__ */ jsxs10("div", { className: "space-y-3 w-48 opacity-30", children: [
|
|
1203
|
+
/* @__PURE__ */ jsx11(MiniMeter, { label: "CPU", percent: 0 }),
|
|
1204
|
+
/* @__PURE__ */ jsx11(MiniMeter, { label: "RAM", percent: 0 })
|
|
1180
1205
|
] }) : null }),
|
|
1181
|
-
/* @__PURE__ */
|
|
1182
|
-
isActive && /* @__PURE__ */
|
|
1183
|
-
/* @__PURE__ */
|
|
1206
|
+
/* @__PURE__ */ jsx11("td", { className: "px-6 py-5 text-right", children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-end gap-1", children: [
|
|
1207
|
+
isActive && /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
1208
|
+
/* @__PURE__ */ jsx11("button", { type: "button", onClick: (e) => {
|
|
1184
1209
|
stopRowClick(e);
|
|
1185
1210
|
onOpenIDE?.(sb.id);
|
|
1186
|
-
}, className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "Open IDE", children: /* @__PURE__ */
|
|
1187
|
-
/* @__PURE__ */
|
|
1211
|
+
}, className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "Open IDE", children: /* @__PURE__ */ jsx11(Code22, { className: "h-4 w-4" }) }),
|
|
1212
|
+
/* @__PURE__ */ jsx11("button", { type: "button", onClick: (e) => {
|
|
1188
1213
|
stopRowClick(e);
|
|
1189
1214
|
onOpenTerminal?.(sb.id);
|
|
1190
|
-
}, className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "Terminal", children: /* @__PURE__ */
|
|
1191
|
-
/* @__PURE__ */
|
|
1215
|
+
}, className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "Terminal", children: /* @__PURE__ */ jsx11(Terminal2, { className: "h-4 w-4" }) }),
|
|
1216
|
+
/* @__PURE__ */ jsx11("button", { type: "button", onClick: (e) => {
|
|
1192
1217
|
stopRowClick(e);
|
|
1193
1218
|
onSSH?.(sb.id);
|
|
1194
|
-
}, className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "SSH", children: /* @__PURE__ */
|
|
1219
|
+
}, className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90", title: "SSH", children: /* @__PURE__ */ jsx11(Key, { className: "h-4 w-4" }) })
|
|
1195
1220
|
] }),
|
|
1196
|
-
resumeHandler && /* @__PURE__ */
|
|
1221
|
+
resumeHandler && /* @__PURE__ */ jsxs10(
|
|
1197
1222
|
"button",
|
|
1198
1223
|
{
|
|
1199
1224
|
type: "button",
|
|
@@ -1204,7 +1229,7 @@ function SandboxTable({
|
|
|
1204
1229
|
className: "inline-flex items-center gap-1.5 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",
|
|
1205
1230
|
title: resumeLabel,
|
|
1206
1231
|
children: [
|
|
1207
|
-
/* @__PURE__ */
|
|
1232
|
+
/* @__PURE__ */ jsx11(Play2, { className: "h-3 w-3" }),
|
|
1208
1233
|
resumeLabel
|
|
1209
1234
|
]
|
|
1210
1235
|
}
|
|
@@ -1218,55 +1243,55 @@ function SandboxTable({
|
|
|
1218
1243
|
if (isActive) {
|
|
1219
1244
|
const lifecycle = [];
|
|
1220
1245
|
if (onStop) lifecycle.push(
|
|
1221
|
-
/* @__PURE__ */
|
|
1222
|
-
/* @__PURE__ */
|
|
1246
|
+
/* @__PURE__ */ jsxs10(DropdownMenuItem3, { onClick: runItem(onStop), children: [
|
|
1247
|
+
/* @__PURE__ */ jsx11(PowerOff2, { className: "mr-2 h-4 w-4" }),
|
|
1223
1248
|
" Stop Sandbox"
|
|
1224
1249
|
] }, "stop")
|
|
1225
1250
|
);
|
|
1226
1251
|
if (onKeepAlive) lifecycle.push(
|
|
1227
|
-
/* @__PURE__ */
|
|
1228
|
-
/* @__PURE__ */
|
|
1252
|
+
/* @__PURE__ */ jsxs10(DropdownMenuItem3, { onClick: runItem(onKeepAlive), children: [
|
|
1253
|
+
/* @__PURE__ */ jsx11(Clock2, { className: "mr-2 h-4 w-4" }),
|
|
1229
1254
|
" Keep Alive"
|
|
1230
1255
|
] }, "keep-alive")
|
|
1231
1256
|
);
|
|
1232
1257
|
if (lifecycle.length) overflowSections.push(lifecycle);
|
|
1233
1258
|
const observability = [];
|
|
1234
1259
|
if (onUsage) observability.push(
|
|
1235
|
-
/* @__PURE__ */
|
|
1236
|
-
/* @__PURE__ */
|
|
1260
|
+
/* @__PURE__ */ jsxs10(DropdownMenuItem3, { onClick: runItem(onUsage), children: [
|
|
1261
|
+
/* @__PURE__ */ jsx11(BarChart22, { className: "mr-2 h-4 w-4" }),
|
|
1237
1262
|
" View Usage"
|
|
1238
1263
|
] }, "usage")
|
|
1239
1264
|
);
|
|
1240
1265
|
if (onHealth) observability.push(
|
|
1241
|
-
/* @__PURE__ */
|
|
1242
|
-
/* @__PURE__ */
|
|
1266
|
+
/* @__PURE__ */ jsxs10(DropdownMenuItem3, { onClick: runItem(onHealth), children: [
|
|
1267
|
+
/* @__PURE__ */ jsx11(Activity2, { className: "mr-2 h-4 w-4" }),
|
|
1243
1268
|
" Health Check"
|
|
1244
1269
|
] }, "health")
|
|
1245
1270
|
);
|
|
1246
1271
|
if (observability.length) overflowSections.push(observability);
|
|
1247
1272
|
if (onFork) overflowSections.push([
|
|
1248
|
-
/* @__PURE__ */
|
|
1249
|
-
/* @__PURE__ */
|
|
1273
|
+
/* @__PURE__ */ jsxs10(DropdownMenuItem3, { onClick: runItem(onFork), children: [
|
|
1274
|
+
/* @__PURE__ */ jsx11(Copy2, { className: "mr-2 h-4 w-4" }),
|
|
1250
1275
|
" Fork Sandbox"
|
|
1251
1276
|
] }, "fork")
|
|
1252
1277
|
]);
|
|
1253
1278
|
} else if (isResumable(sb.status)) {
|
|
1254
1279
|
if (onFork) overflowSections.push([
|
|
1255
|
-
/* @__PURE__ */
|
|
1256
|
-
/* @__PURE__ */
|
|
1280
|
+
/* @__PURE__ */ jsxs10(DropdownMenuItem3, { onClick: runItem(onFork), children: [
|
|
1281
|
+
/* @__PURE__ */ jsx11(Copy2, { className: "mr-2 h-4 w-4" }),
|
|
1257
1282
|
" Fork Sandbox"
|
|
1258
1283
|
] }, "fork")
|
|
1259
1284
|
]);
|
|
1260
1285
|
}
|
|
1261
1286
|
if (onMore) overflowSections.push([
|
|
1262
|
-
/* @__PURE__ */
|
|
1263
|
-
/* @__PURE__ */
|
|
1287
|
+
/* @__PURE__ */ jsxs10(DropdownMenuItem3, { onClick: runItem(onMore), children: [
|
|
1288
|
+
/* @__PURE__ */ jsx11(ExternalLink, { className: "mr-2 h-4 w-4" }),
|
|
1264
1289
|
" View Details"
|
|
1265
1290
|
] }, "view-details")
|
|
1266
1291
|
]);
|
|
1267
1292
|
if (overflowSections.length === 0) return null;
|
|
1268
|
-
return /* @__PURE__ */
|
|
1269
|
-
/* @__PURE__ */
|
|
1293
|
+
return /* @__PURE__ */ jsxs10(DropdownMenu3, { children: [
|
|
1294
|
+
/* @__PURE__ */ jsx11(DropdownMenuTrigger3, { asChild: true, children: /* @__PURE__ */ jsx11(
|
|
1270
1295
|
"button",
|
|
1271
1296
|
{
|
|
1272
1297
|
type: "button",
|
|
@@ -1274,19 +1299,19 @@ function SandboxTable({
|
|
|
1274
1299
|
className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-all active:scale-90 outline-none",
|
|
1275
1300
|
"aria-label": "More actions",
|
|
1276
1301
|
title: "More actions",
|
|
1277
|
-
children: /* @__PURE__ */
|
|
1302
|
+
children: /* @__PURE__ */ jsx11(MoreVertical2, { className: "h-4 w-4" })
|
|
1278
1303
|
}
|
|
1279
1304
|
) }),
|
|
1280
|
-
/* @__PURE__ */
|
|
1281
|
-
sectionIdx > 0 && /* @__PURE__ */
|
|
1305
|
+
/* @__PURE__ */ jsx11(DropdownMenuContent3, { align: "end", className: "min-w-[180px]", children: overflowSections.map((section, sectionIdx) => /* @__PURE__ */ jsxs10(React5.Fragment, { children: [
|
|
1306
|
+
sectionIdx > 0 && /* @__PURE__ */ jsx11(DropdownMenuSeparator3, {}),
|
|
1282
1307
|
section
|
|
1283
1308
|
] }, sectionIdx)) })
|
|
1284
1309
|
] });
|
|
1285
1310
|
})(),
|
|
1286
|
-
onDelete && canAdminSandbox(sb) && /* @__PURE__ */
|
|
1311
|
+
onDelete && canAdminSandbox(sb) && /* @__PURE__ */ jsx11("button", { type: "button", onClick: (e) => {
|
|
1287
1312
|
stopRowClick(e);
|
|
1288
1313
|
onDelete(sb.id);
|
|
1289
|
-
}, 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__ */
|
|
1314
|
+
}, 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__ */ jsx11(Trash22, { className: "h-4 w-4" }) })
|
|
1290
1315
|
] }) })
|
|
1291
1316
|
]
|
|
1292
1317
|
},
|
|
@@ -1295,17 +1320,17 @@ function SandboxTable({
|
|
|
1295
1320
|
);
|
|
1296
1321
|
}) })
|
|
1297
1322
|
] }) }) }),
|
|
1298
|
-
totalPages > 1 && /* @__PURE__ */
|
|
1299
|
-
/* @__PURE__ */
|
|
1323
|
+
totalPages > 1 && /* @__PURE__ */ jsxs10("div", { className: "mt-6 flex flex-col md:flex-row justify-between items-center text-muted-foreground text-xs font-medium gap-4", children: [
|
|
1324
|
+
/* @__PURE__ */ jsxs10("p", { children: [
|
|
1300
1325
|
"Showing ",
|
|
1301
1326
|
sandboxes.length,
|
|
1302
1327
|
" of ",
|
|
1303
1328
|
totalCount,
|
|
1304
1329
|
" active sandboxes"
|
|
1305
1330
|
] }),
|
|
1306
|
-
/* @__PURE__ */
|
|
1307
|
-
/* @__PURE__ */
|
|
1308
|
-
Array.from({ length: Math.min(totalPages, 5) }, (_, i) => i + 1).map((p) => /* @__PURE__ */
|
|
1331
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
|
|
1332
|
+
/* @__PURE__ */ jsx11("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__ */ jsx11(ChevronLeft, { className: "h-4 w-4" }) }),
|
|
1333
|
+
Array.from({ length: Math.min(totalPages, 5) }, (_, i) => i + 1).map((p) => /* @__PURE__ */ jsx11(
|
|
1309
1334
|
"button",
|
|
1310
1335
|
{
|
|
1311
1336
|
type: "button",
|
|
@@ -1318,7 +1343,7 @@ function SandboxTable({
|
|
|
1318
1343
|
},
|
|
1319
1344
|
p
|
|
1320
1345
|
)),
|
|
1321
|
-
/* @__PURE__ */
|
|
1346
|
+
/* @__PURE__ */ jsx11("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__ */ jsx11(ChevronRight, { className: "h-4 w-4" }) })
|
|
1322
1347
|
] })
|
|
1323
1348
|
] })
|
|
1324
1349
|
] });
|
|
@@ -1326,51 +1351,51 @@ function SandboxTable({
|
|
|
1326
1351
|
|
|
1327
1352
|
// src/dashboard/invoice-table.tsx
|
|
1328
1353
|
import { Download, FileText } from "lucide-react";
|
|
1329
|
-
import { jsx as
|
|
1354
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1330
1355
|
var statusStyle = {
|
|
1331
1356
|
paid: "bg-[var(--accent-surface-soft)] text-primary border border-border",
|
|
1332
1357
|
pending: "bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)] border border-[var(--surface-warning-border)]",
|
|
1333
1358
|
failed: "bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)] border border-[var(--surface-danger-border)]"
|
|
1334
1359
|
};
|
|
1335
1360
|
function InvoiceTable({ invoices, onExportAll, onLoadMore, onViewInvoice, hasMore, className }) {
|
|
1336
|
-
return /* @__PURE__ */
|
|
1337
|
-
/* @__PURE__ */
|
|
1338
|
-
/* @__PURE__ */
|
|
1339
|
-
onExportAll && /* @__PURE__ */
|
|
1340
|
-
/* @__PURE__ */
|
|
1361
|
+
return /* @__PURE__ */ jsxs11("section", { className, children: [
|
|
1362
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex justify-between items-center mb-6 px-2", children: [
|
|
1363
|
+
/* @__PURE__ */ jsx12("h2", { className: "text-2xl font-bold text-foreground tracking-tight", children: "Invoice History" }),
|
|
1364
|
+
onExportAll && /* @__PURE__ */ jsxs11("button", { type: "button", onClick: onExportAll, className: "text-[10px] font-mono text-primary uppercase tracking-widest flex items-center gap-2 hover:underline", children: [
|
|
1365
|
+
/* @__PURE__ */ jsx12(Download, { className: "h-3.5 w-3.5" }),
|
|
1341
1366
|
"Export All"
|
|
1342
1367
|
] })
|
|
1343
1368
|
] }),
|
|
1344
|
-
/* @__PURE__ */
|
|
1345
|
-
/* @__PURE__ */
|
|
1346
|
-
/* @__PURE__ */
|
|
1347
|
-
/* @__PURE__ */
|
|
1348
|
-
/* @__PURE__ */
|
|
1349
|
-
/* @__PURE__ */
|
|
1350
|
-
/* @__PURE__ */
|
|
1369
|
+
/* @__PURE__ */ jsx12("div", { className: "bg-card rounded-xl overflow-hidden border border-border", children: /* @__PURE__ */ jsxs11("table", { className: "w-full text-left border-collapse", children: [
|
|
1370
|
+
/* @__PURE__ */ jsx12("thead", { children: /* @__PURE__ */ jsxs11("tr", { className: "bg-background border-b border-border", children: [
|
|
1371
|
+
/* @__PURE__ */ jsx12("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Invoice ID" }),
|
|
1372
|
+
/* @__PURE__ */ jsx12("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Date" }),
|
|
1373
|
+
/* @__PURE__ */ jsx12("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Amount" }),
|
|
1374
|
+
/* @__PURE__ */ jsx12("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest", children: "Status" }),
|
|
1375
|
+
/* @__PURE__ */ jsx12("th", { className: "px-6 py-4 font-mono text-[10px] text-muted-foreground uppercase tracking-widest text-right", children: "Action" })
|
|
1351
1376
|
] }) }),
|
|
1352
|
-
/* @__PURE__ */
|
|
1353
|
-
/* @__PURE__ */
|
|
1354
|
-
/* @__PURE__ */
|
|
1355
|
-
/* @__PURE__ */
|
|
1377
|
+
/* @__PURE__ */ jsx12("tbody", { className: "divide-y divide-border", children: invoices.map((inv) => /* @__PURE__ */ jsxs11("tr", { className: "hover:bg-muted/50 transition-colors", children: [
|
|
1378
|
+
/* @__PURE__ */ jsx12("td", { className: "px-6 py-5 font-mono text-xs text-foreground", children: inv.id }),
|
|
1379
|
+
/* @__PURE__ */ jsx12("td", { className: "px-6 py-5 text-sm text-foreground", children: inv.date }),
|
|
1380
|
+
/* @__PURE__ */ jsxs11("td", { className: "px-6 py-5 text-sm font-bold text-foreground", children: [
|
|
1356
1381
|
"$",
|
|
1357
1382
|
inv.amount.toFixed(2)
|
|
1358
1383
|
] }),
|
|
1359
|
-
/* @__PURE__ */
|
|
1360
|
-
/* @__PURE__ */
|
|
1384
|
+
/* @__PURE__ */ jsx12("td", { className: "px-6 py-5", children: /* @__PURE__ */ jsx12("span", { className: cn("px-2 py-1 text-[10px] font-mono rounded uppercase", statusStyle[inv.status] ?? statusStyle.paid), children: inv.status }) }),
|
|
1385
|
+
/* @__PURE__ */ jsx12("td", { className: "px-6 py-5 text-right", children: /* @__PURE__ */ jsx12("button", { type: "button", onClick: () => onViewInvoice?.(inv.id), className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ jsx12(FileText, { className: "h-4 w-4" }) }) })
|
|
1361
1386
|
] }, inv.id)) })
|
|
1362
1387
|
] }) }),
|
|
1363
|
-
hasMore && onLoadMore && /* @__PURE__ */
|
|
1388
|
+
hasMore && onLoadMore && /* @__PURE__ */ jsx12("div", { className: "mt-6 flex justify-center", children: /* @__PURE__ */ jsx12("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" }) })
|
|
1364
1389
|
] });
|
|
1365
1390
|
}
|
|
1366
1391
|
|
|
1367
1392
|
// src/dashboard/plan-cards.tsx
|
|
1368
1393
|
import { Check } from "lucide-react";
|
|
1369
|
-
import { jsx as
|
|
1394
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1370
1395
|
function PlanCards({ plans, className }) {
|
|
1371
|
-
return /* @__PURE__ */
|
|
1372
|
-
/* @__PURE__ */
|
|
1373
|
-
/* @__PURE__ */
|
|
1396
|
+
return /* @__PURE__ */ jsxs12("section", { className, children: [
|
|
1397
|
+
/* @__PURE__ */ jsx13("h2", { className: "text-2xl font-bold text-foreground tracking-tight mb-5 px-2", children: "Subscription Plans" }),
|
|
1398
|
+
/* @__PURE__ */ jsx13("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-6", children: plans.map((plan) => /* @__PURE__ */ jsxs12(
|
|
1374
1399
|
"div",
|
|
1375
1400
|
{
|
|
1376
1401
|
className: cn(
|
|
@@ -1378,23 +1403,23 @@ function PlanCards({ plans, className }) {
|
|
|
1378
1403
|
plan.popular ? "bg-muted/50 border-border" : "bg-card border-border hover:bg-muted/50 hover:border-primary/20"
|
|
1379
1404
|
),
|
|
1380
1405
|
children: [
|
|
1381
|
-
plan.popular && /* @__PURE__ */
|
|
1382
|
-
/* @__PURE__ */
|
|
1383
|
-
/* @__PURE__ */
|
|
1384
|
-
/* @__PURE__ */
|
|
1406
|
+
plan.popular && /* @__PURE__ */ jsx13("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" }),
|
|
1407
|
+
/* @__PURE__ */ jsxs12("div", { className: "mb-4", children: [
|
|
1408
|
+
/* @__PURE__ */ jsx13("div", { className: cn("text-xs font-mono uppercase tracking-widest mb-2", plan.popular ? "text-primary" : "text-muted-foreground"), children: plan.name }),
|
|
1409
|
+
/* @__PURE__ */ jsxs12("div", { className: "text-3xl font-bold text-foreground", children: [
|
|
1385
1410
|
"$",
|
|
1386
1411
|
plan.price,
|
|
1387
|
-
/* @__PURE__ */
|
|
1412
|
+
/* @__PURE__ */ jsxs12("span", { className: "text-sm font-normal text-muted-foreground tracking-normal", children: [
|
|
1388
1413
|
"/",
|
|
1389
1414
|
plan.period ?? "mo"
|
|
1390
1415
|
] })
|
|
1391
1416
|
] })
|
|
1392
1417
|
] }),
|
|
1393
|
-
/* @__PURE__ */
|
|
1394
|
-
/* @__PURE__ */
|
|
1418
|
+
/* @__PURE__ */ jsx13("ul", { className: "space-y-2 mb-5 text-sm text-muted-foreground", children: plan.features.map((f, i) => /* @__PURE__ */ jsxs12("li", { className: "flex items-center gap-2", children: [
|
|
1419
|
+
/* @__PURE__ */ jsx13(Check, { className: "h-3.5 w-3.5 text-primary shrink-0" }),
|
|
1395
1420
|
f.text
|
|
1396
1421
|
] }, i)) }),
|
|
1397
|
-
/* @__PURE__ */
|
|
1422
|
+
/* @__PURE__ */ jsx13(
|
|
1398
1423
|
"button",
|
|
1399
1424
|
{
|
|
1400
1425
|
type: "button",
|
|
@@ -1416,27 +1441,27 @@ function PlanCards({ plans, className }) {
|
|
|
1416
1441
|
// src/dashboard/dashboard-layout.tsx
|
|
1417
1442
|
import * as React6 from "react";
|
|
1418
1443
|
import { Plus as Plus2, Bell } from "lucide-react";
|
|
1419
|
-
import { Fragment as
|
|
1444
|
+
import { Fragment as Fragment8, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1420
1445
|
function SettingsIconSmall({ className }) {
|
|
1421
|
-
return /* @__PURE__ */
|
|
1422
|
-
/* @__PURE__ */
|
|
1423
|
-
/* @__PURE__ */
|
|
1424
|
-
/* @__PURE__ */
|
|
1446
|
+
return /* @__PURE__ */ jsxs13("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: [
|
|
1447
|
+
/* @__PURE__ */ jsx14("title", { children: "Settings" }),
|
|
1448
|
+
/* @__PURE__ */ jsx14("path", { d: "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" }),
|
|
1449
|
+
/* @__PURE__ */ jsx14("circle", { cx: "12", cy: "12", r: "3" })
|
|
1425
1450
|
] });
|
|
1426
1451
|
}
|
|
1427
1452
|
function MenuIcon({ className }) {
|
|
1428
|
-
return /* @__PURE__ */
|
|
1429
|
-
/* @__PURE__ */
|
|
1430
|
-
/* @__PURE__ */
|
|
1431
|
-
/* @__PURE__ */
|
|
1432
|
-
/* @__PURE__ */
|
|
1453
|
+
return /* @__PURE__ */ jsxs13("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: [
|
|
1454
|
+
/* @__PURE__ */ jsx14("title", { children: "Menu icon" }),
|
|
1455
|
+
/* @__PURE__ */ jsx14("line", { x1: "4", x2: "20", y1: "12", y2: "12" }),
|
|
1456
|
+
/* @__PURE__ */ jsx14("line", { x1: "4", x2: "20", y1: "6", y2: "6" }),
|
|
1457
|
+
/* @__PURE__ */ jsx14("line", { x1: "4", x2: "20", y1: "18", y2: "18" })
|
|
1433
1458
|
] });
|
|
1434
1459
|
}
|
|
1435
1460
|
function XIcon({ className }) {
|
|
1436
|
-
return /* @__PURE__ */
|
|
1437
|
-
/* @__PURE__ */
|
|
1438
|
-
/* @__PURE__ */
|
|
1439
|
-
/* @__PURE__ */
|
|
1461
|
+
return /* @__PURE__ */ jsxs13("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: [
|
|
1462
|
+
/* @__PURE__ */ jsx14("title", { children: "Close icon" }),
|
|
1463
|
+
/* @__PURE__ */ jsx14("path", { d: "M18 6 6 18" }),
|
|
1464
|
+
/* @__PURE__ */ jsx14("path", { d: "m6 6 12 12" })
|
|
1440
1465
|
] });
|
|
1441
1466
|
}
|
|
1442
1467
|
function formatNotifDate(raw) {
|
|
@@ -1450,7 +1475,7 @@ function DefaultLink2({
|
|
|
1450
1475
|
children,
|
|
1451
1476
|
...rest
|
|
1452
1477
|
}) {
|
|
1453
|
-
return /* @__PURE__ */
|
|
1478
|
+
return /* @__PURE__ */ jsx14("a", { href: href ?? to, className, ...rest, children });
|
|
1454
1479
|
}
|
|
1455
1480
|
function DashboardLayoutInner({
|
|
1456
1481
|
children,
|
|
@@ -1505,16 +1530,16 @@ function DashboardLayoutInner({
|
|
|
1505
1530
|
);
|
|
1506
1531
|
const activePanel = panels.find((p) => p.mode === mode);
|
|
1507
1532
|
const buildSidebarContent = React6.useCallback(
|
|
1508
|
-
(showLabels) => /* @__PURE__ */
|
|
1509
|
-
/* @__PURE__ */
|
|
1510
|
-
/* @__PURE__ */
|
|
1511
|
-
/* @__PURE__ */
|
|
1533
|
+
(showLabels) => /* @__PURE__ */ jsxs13(Fragment8, { children: [
|
|
1534
|
+
/* @__PURE__ */ jsxs13(SidebarRail, { wide: showLabels, children: [
|
|
1535
|
+
/* @__PURE__ */ jsx14(SidebarRailHeader, { children: /* @__PURE__ */ jsx14(Link, { href: "/", to: "/", className: "p-1 rounded-md transition-colors hover:bg-muted/50", children: /* @__PURE__ */ jsx14(Logo, { variant, size: "sm", iconOnly: true }) }) }),
|
|
1536
|
+
/* @__PURE__ */ jsx14(SidebarRailNav, { children: navItems.map((item, i) => {
|
|
1512
1537
|
const isMode = modeSet.has(item.id);
|
|
1513
1538
|
const prevIsMode = i > 0 && modeSet.has(navItems[i - 1].id);
|
|
1514
1539
|
const showSep = i > 0 && isMode && !prevIsMode;
|
|
1515
|
-
return /* @__PURE__ */
|
|
1516
|
-
showSep && /* @__PURE__ */
|
|
1517
|
-
isMode ? /* @__PURE__ */
|
|
1540
|
+
return /* @__PURE__ */ jsxs13(React6.Fragment, { children: [
|
|
1541
|
+
showSep && /* @__PURE__ */ jsx14(RailSeparator, {}),
|
|
1542
|
+
isMode ? /* @__PURE__ */ jsx14(
|
|
1518
1543
|
RailModeButton,
|
|
1519
1544
|
{
|
|
1520
1545
|
mode: item.id,
|
|
@@ -1523,7 +1548,7 @@ function DashboardLayoutInner({
|
|
|
1523
1548
|
badge: item.badge,
|
|
1524
1549
|
showLabel: showLabels
|
|
1525
1550
|
}
|
|
1526
|
-
) : /* @__PURE__ */
|
|
1551
|
+
) : /* @__PURE__ */ jsx14(Link, { href: item.href, to: item.href, children: /* @__PURE__ */ jsx14(
|
|
1527
1552
|
RailButton,
|
|
1528
1553
|
{
|
|
1529
1554
|
icon: item.icon,
|
|
@@ -1534,11 +1559,11 @@ function DashboardLayoutInner({
|
|
|
1534
1559
|
) })
|
|
1535
1560
|
] }, item.id);
|
|
1536
1561
|
}) }),
|
|
1537
|
-
/* @__PURE__ */
|
|
1538
|
-
onSettingsClick ? /* @__PURE__ */
|
|
1562
|
+
/* @__PURE__ */ jsxs13(SidebarRailFooter, { children: [
|
|
1563
|
+
onSettingsClick ? /* @__PURE__ */ jsx14(RailButton, { icon: SettingsIconSmall, label: "Settings", onClick: onSettingsClick, showLabel: showLabels }) : /* @__PURE__ */ jsx14(Link, { href: settingsHref, to: settingsHref, children: /* @__PURE__ */ jsx14(RailButton, { icon: SettingsIconSmall, label: "Settings", showLabel: showLabels }) }),
|
|
1539
1564
|
railFooter,
|
|
1540
|
-
/* @__PURE__ */
|
|
1541
|
-
/* @__PURE__ */
|
|
1565
|
+
/* @__PURE__ */ jsx14(RailSeparator, {}),
|
|
1566
|
+
/* @__PURE__ */ jsx14(
|
|
1542
1567
|
ProfileAvatar,
|
|
1543
1568
|
{
|
|
1544
1569
|
user: sidebarUser,
|
|
@@ -1552,9 +1577,9 @@ function DashboardLayoutInner({
|
|
|
1552
1577
|
)
|
|
1553
1578
|
] })
|
|
1554
1579
|
] }),
|
|
1555
|
-
panels.length > 0 && /* @__PURE__ */
|
|
1556
|
-
/* @__PURE__ */
|
|
1557
|
-
/* @__PURE__ */
|
|
1580
|
+
panels.length > 0 && /* @__PURE__ */ jsxs13(SidebarPanel, { children: [
|
|
1581
|
+
/* @__PURE__ */ jsx14(SidebarPanelHeader, { title: activePanel?.title ?? mode }),
|
|
1582
|
+
/* @__PURE__ */ jsx14(SidebarPanelContent, { children: activePanel?.content })
|
|
1558
1583
|
] })
|
|
1559
1584
|
] }),
|
|
1560
1585
|
// biome-ignore lint/correctness/useExhaustiveDependencies: intentional — only the inputs that actually affect the sidebar tree
|
|
@@ -1579,8 +1604,8 @@ function DashboardLayoutInner({
|
|
|
1579
1604
|
);
|
|
1580
1605
|
const sidebarContent = React6.useMemo(() => buildSidebarContent(false), [buildSidebarContent]);
|
|
1581
1606
|
const mobileSidebarContent = React6.useMemo(() => buildSidebarContent(true), [buildSidebarContent]);
|
|
1582
|
-
return /* @__PURE__ */
|
|
1583
|
-
/* @__PURE__ */
|
|
1607
|
+
return /* @__PURE__ */ jsxs13("div", { className: cn("min-h-screen bg-background text-foreground", className), children: [
|
|
1608
|
+
/* @__PURE__ */ jsxs13(
|
|
1584
1609
|
"nav",
|
|
1585
1610
|
{
|
|
1586
1611
|
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",
|
|
@@ -1589,9 +1614,9 @@ function DashboardLayoutInner({
|
|
|
1589
1614
|
width: hidden ? "100%" : `calc(100% - ${contentMargin}px)`
|
|
1590
1615
|
},
|
|
1591
1616
|
children: [
|
|
1592
|
-
/* @__PURE__ */
|
|
1593
|
-
/* @__PURE__ */
|
|
1594
|
-
topNavLinks && topNavLinks.length > 0 && /* @__PURE__ */
|
|
1617
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-8", children: [
|
|
1618
|
+
/* @__PURE__ */ jsx14(Link, { href: "/", to: "/", className: "lg:hidden flex items-center p-1 rounded-md hover:bg-muted/50 transition-colors", children: /* @__PURE__ */ jsx14(Logo, { variant, size: "sm", iconOnly: true }) }),
|
|
1619
|
+
topNavLinks && topNavLinks.length > 0 && /* @__PURE__ */ jsx14("div", { className: "hidden md:flex gap-6", children: topNavLinks.map((link) => /* @__PURE__ */ jsx14(
|
|
1595
1620
|
Link,
|
|
1596
1621
|
{
|
|
1597
1622
|
href: link.href,
|
|
@@ -1605,21 +1630,21 @@ function DashboardLayoutInner({
|
|
|
1605
1630
|
link.href
|
|
1606
1631
|
)) })
|
|
1607
1632
|
] }),
|
|
1608
|
-
/* @__PURE__ */
|
|
1609
|
-
onNewSandbox && /* @__PURE__ */
|
|
1633
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-4", children: [
|
|
1634
|
+
onNewSandbox && /* @__PURE__ */ jsxs13(
|
|
1610
1635
|
"button",
|
|
1611
1636
|
{
|
|
1612
1637
|
type: "button",
|
|
1613
1638
|
onClick: onNewSandbox,
|
|
1614
1639
|
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",
|
|
1615
1640
|
children: [
|
|
1616
|
-
/* @__PURE__ */
|
|
1641
|
+
/* @__PURE__ */ jsx14(Plus2, { className: "h-3.5 w-3.5" }),
|
|
1617
1642
|
"New Sandbox"
|
|
1618
1643
|
]
|
|
1619
1644
|
}
|
|
1620
1645
|
),
|
|
1621
|
-
/* @__PURE__ */
|
|
1622
|
-
/* @__PURE__ */
|
|
1646
|
+
/* @__PURE__ */ jsxs13("div", { className: "relative", ref: notifRef, children: [
|
|
1647
|
+
/* @__PURE__ */ jsxs13(
|
|
1623
1648
|
"button",
|
|
1624
1649
|
{
|
|
1625
1650
|
type: "button",
|
|
@@ -1628,15 +1653,15 @@ function DashboardLayoutInner({
|
|
|
1628
1653
|
"aria-label": "Notifications",
|
|
1629
1654
|
"aria-expanded": notificationsOpen,
|
|
1630
1655
|
children: [
|
|
1631
|
-
/* @__PURE__ */
|
|
1632
|
-
(notifData?.unreadCount ?? 0) > 0 && /* @__PURE__ */
|
|
1656
|
+
/* @__PURE__ */ jsx14(Bell, { className: "h-4 w-4" }),
|
|
1657
|
+
(notifData?.unreadCount ?? 0) > 0 && /* @__PURE__ */ jsx14("span", { className: "absolute top-1 right-1 h-2 w-2 rounded-full bg-destructive" })
|
|
1633
1658
|
]
|
|
1634
1659
|
}
|
|
1635
1660
|
),
|
|
1636
|
-
notificationsOpen && /* @__PURE__ */
|
|
1637
|
-
/* @__PURE__ */
|
|
1638
|
-
/* @__PURE__ */
|
|
1639
|
-
(notifData?.unreadCount ?? 0) > 0 && notifData?.onMarkAllRead && /* @__PURE__ */
|
|
1661
|
+
notificationsOpen && /* @__PURE__ */ jsxs13("div", { className: "absolute right-0 top-full mt-2 w-80 rounded-lg border border-border bg-card shadow-[var(--shadow-dropdown)] z-50", children: [
|
|
1662
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between border-b border-border px-4 py-3", children: [
|
|
1663
|
+
/* @__PURE__ */ jsx14("p", { className: "font-bold text-foreground text-sm", children: "Notifications" }),
|
|
1664
|
+
(notifData?.unreadCount ?? 0) > 0 && notifData?.onMarkAllRead && /* @__PURE__ */ jsx14(
|
|
1640
1665
|
"button",
|
|
1641
1666
|
{
|
|
1642
1667
|
type: "button",
|
|
@@ -1648,11 +1673,11 @@ function DashboardLayoutInner({
|
|
|
1648
1673
|
}
|
|
1649
1674
|
)
|
|
1650
1675
|
] }),
|
|
1651
|
-
!notifData?.items || notifData.items.length === 0 ? /* @__PURE__ */
|
|
1652
|
-
/* @__PURE__ */
|
|
1653
|
-
/* @__PURE__ */
|
|
1654
|
-
/* @__PURE__ */
|
|
1655
|
-
] }) : /* @__PURE__ */
|
|
1676
|
+
!notifData?.items || notifData.items.length === 0 ? /* @__PURE__ */ jsxs13("div", { className: "flex flex-col items-center justify-center px-4 py-8 text-center", children: [
|
|
1677
|
+
/* @__PURE__ */ jsx14(Bell, { className: "h-8 w-8 text-muted-foreground/40 mb-2" }),
|
|
1678
|
+
/* @__PURE__ */ jsx14("p", { className: "text-muted-foreground text-sm", children: "No notifications yet" }),
|
|
1679
|
+
/* @__PURE__ */ jsx14("p", { className: "text-muted-foreground/60 text-xs mt-1", children: "We'll notify you about important updates" })
|
|
1680
|
+
] }) : /* @__PURE__ */ jsx14("div", { className: "max-h-80 overflow-y-auto", children: notifData.items.map((n) => /* @__PURE__ */ jsxs13(
|
|
1656
1681
|
"button",
|
|
1657
1682
|
{
|
|
1658
1683
|
type: "button",
|
|
@@ -1664,9 +1689,9 @@ function DashboardLayoutInner({
|
|
|
1664
1689
|
if (!n.read) notifData.onMarkRead?.(n.id);
|
|
1665
1690
|
},
|
|
1666
1691
|
children: [
|
|
1667
|
-
/* @__PURE__ */
|
|
1668
|
-
/* @__PURE__ */
|
|
1669
|
-
/* @__PURE__ */
|
|
1692
|
+
/* @__PURE__ */ jsx14("p", { className: cn("text-sm", !n.read ? "font-semibold text-foreground" : "text-muted-foreground"), children: n.title }),
|
|
1693
|
+
/* @__PURE__ */ jsx14("p", { className: "text-xs text-muted-foreground mt-0.5 line-clamp-2", children: n.message }),
|
|
1694
|
+
/* @__PURE__ */ jsx14("p", { className: "text-[10px] text-muted-foreground/50 mt-1", children: formatNotifDate(n.createdAt) })
|
|
1670
1695
|
]
|
|
1671
1696
|
},
|
|
1672
1697
|
n.id
|
|
@@ -1674,7 +1699,7 @@ function DashboardLayoutInner({
|
|
|
1674
1699
|
] })
|
|
1675
1700
|
] })
|
|
1676
1701
|
] }),
|
|
1677
|
-
/* @__PURE__ */
|
|
1702
|
+
/* @__PURE__ */ jsx14(
|
|
1678
1703
|
"button",
|
|
1679
1704
|
{
|
|
1680
1705
|
type: "button",
|
|
@@ -1682,14 +1707,14 @@ function DashboardLayoutInner({
|
|
|
1682
1707
|
className: "rounded-md p-2 hover:bg-muted/50 lg:hidden",
|
|
1683
1708
|
"aria-label": mobileMenuOpen ? "Close menu" : "Open menu",
|
|
1684
1709
|
"aria-expanded": mobileMenuOpen,
|
|
1685
|
-
children: mobileMenuOpen ? /* @__PURE__ */
|
|
1710
|
+
children: mobileMenuOpen ? /* @__PURE__ */ jsx14(XIcon, { className: "h-6 w-6" }) : /* @__PURE__ */ jsx14(MenuIcon, { className: "h-6 w-6" })
|
|
1686
1711
|
}
|
|
1687
1712
|
)
|
|
1688
1713
|
]
|
|
1689
1714
|
}
|
|
1690
1715
|
),
|
|
1691
|
-
mobileMenuOpen && /* @__PURE__ */
|
|
1692
|
-
/* @__PURE__ */
|
|
1716
|
+
mobileMenuOpen && /* @__PURE__ */ jsx14("div", { className: "fixed inset-0 z-30 bg-black/50 lg:hidden", onClick: () => setMobileMenuOpen(false), "aria-hidden": "true" }),
|
|
1717
|
+
/* @__PURE__ */ jsx14(
|
|
1693
1718
|
"aside",
|
|
1694
1719
|
{
|
|
1695
1720
|
className: cn(
|
|
@@ -1702,17 +1727,17 @@ function DashboardLayoutInner({
|
|
|
1702
1727
|
children: mobileSidebarContent
|
|
1703
1728
|
}
|
|
1704
1729
|
),
|
|
1705
|
-
/* @__PURE__ */
|
|
1706
|
-
/* @__PURE__ */
|
|
1730
|
+
/* @__PURE__ */ jsx14(Sidebar, { className: cn("hidden lg:flex", sidebarClassName), children: sidebarContent }),
|
|
1731
|
+
/* @__PURE__ */ jsx14(SidebarContent, { className: cn("pt-16 px-6 pb-8 lg:px-8 bg-background", contentClassName), children }),
|
|
1707
1732
|
footer
|
|
1708
1733
|
] });
|
|
1709
1734
|
}
|
|
1710
1735
|
function DashboardLayout({ defaultPanelOpen, defaultMode, ...props }) {
|
|
1711
|
-
return /* @__PURE__ */
|
|
1736
|
+
return /* @__PURE__ */ jsx14(SidebarProvider, { defaultPanelOpen, defaultMode, hasPanels: (props.panels?.length ?? 0) > 0, children: /* @__PURE__ */ jsx14(DashboardLayoutInner, { defaultPanelOpen, defaultMode, ...props }) });
|
|
1712
1737
|
}
|
|
1713
1738
|
|
|
1714
1739
|
// src/dashboard/sidebar-layout.tsx
|
|
1715
|
-
import { jsx as
|
|
1740
|
+
import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1716
1741
|
var HIDE_BELOW_CLASS = {
|
|
1717
1742
|
md: "max-md:hidden",
|
|
1718
1743
|
lg: "max-lg:hidden"
|
|
@@ -1724,7 +1749,7 @@ function DefaultLink3({
|
|
|
1724
1749
|
children,
|
|
1725
1750
|
...rest
|
|
1726
1751
|
}) {
|
|
1727
|
-
return /* @__PURE__ */
|
|
1752
|
+
return /* @__PURE__ */ jsx15("a", { href: href ?? to, className, ...rest, children });
|
|
1728
1753
|
}
|
|
1729
1754
|
function SidebarLayoutInner({
|
|
1730
1755
|
children,
|
|
@@ -1755,10 +1780,10 @@ function SidebarLayoutInner({
|
|
|
1755
1780
|
const handleNavClick = closePanelOnNavigate && panelOpen ? () => setPanelOpen(false) : void 0;
|
|
1756
1781
|
const hasProfile = user !== void 0 || onLogout !== void 0 || onSettingsClick !== void 0;
|
|
1757
1782
|
const showLabels = railLabels && !railCollapsed;
|
|
1758
|
-
return /* @__PURE__ */
|
|
1759
|
-
/* @__PURE__ */
|
|
1760
|
-
/* @__PURE__ */
|
|
1761
|
-
(railHeaderContent !== void 0 || logo !== void 0) && /* @__PURE__ */
|
|
1783
|
+
return /* @__PURE__ */ jsxs14("div", { className: cn("min-h-screen bg-background text-foreground", className), children: [
|
|
1784
|
+
/* @__PURE__ */ jsx15("div", { className: cn(hideBelow && HIDE_BELOW_CLASS[hideBelow]), children: /* @__PURE__ */ jsxs14(Sidebar, { className: sidebarClassName, children: [
|
|
1785
|
+
/* @__PURE__ */ jsxs14(SidebarRail, { children: [
|
|
1786
|
+
(railHeaderContent !== void 0 || logo !== void 0) && /* @__PURE__ */ jsx15(SidebarRailHeader, { className: cn(showLabels && (railHeaderContent !== void 0 ? "px-2" : "justify-start px-4")), children: railHeaderContent !== void 0 ? railHeaderContent : /* @__PURE__ */ jsx15(
|
|
1762
1787
|
Link,
|
|
1763
1788
|
{
|
|
1764
1789
|
href: logoHref,
|
|
@@ -1767,10 +1792,10 @@ function SidebarLayoutInner({
|
|
|
1767
1792
|
children: logo
|
|
1768
1793
|
}
|
|
1769
1794
|
) }),
|
|
1770
|
-
/* @__PURE__ */
|
|
1795
|
+
/* @__PURE__ */ jsx15(SidebarRailNav, { className: showLabels ? "px-2" : void 0, children: navItems.map((item) => {
|
|
1771
1796
|
if (item.flyoutItems && item.flyoutItems.length > 0) {
|
|
1772
1797
|
const activeSet = new Set(item.flyoutActiveIds ?? []);
|
|
1773
|
-
return /* @__PURE__ */
|
|
1798
|
+
return /* @__PURE__ */ jsx15(
|
|
1774
1799
|
RailFlyout,
|
|
1775
1800
|
{
|
|
1776
1801
|
icon: item.icon,
|
|
@@ -1781,7 +1806,7 @@ function SidebarLayoutInner({
|
|
|
1781
1806
|
children: item.flyoutItems.map((f) => {
|
|
1782
1807
|
const FIcon = f.icon;
|
|
1783
1808
|
const active = activeSet.has(f.id);
|
|
1784
|
-
return /* @__PURE__ */
|
|
1809
|
+
return /* @__PURE__ */ jsxs14(
|
|
1785
1810
|
Link,
|
|
1786
1811
|
{
|
|
1787
1812
|
href: f.href,
|
|
@@ -1793,8 +1818,8 @@ function SidebarLayoutInner({
|
|
|
1793
1818
|
active ? "bg-[var(--accent-surface-strong)] font-medium text-[var(--accent-text)]" : "text-muted-foreground hover:bg-[var(--accent-surface-soft)] hover:text-[var(--accent-text)]"
|
|
1794
1819
|
),
|
|
1795
1820
|
children: [
|
|
1796
|
-
/* @__PURE__ */
|
|
1797
|
-
/* @__PURE__ */
|
|
1821
|
+
/* @__PURE__ */ jsx15(FIcon, { className: "h-4 w-4 shrink-0" }),
|
|
1822
|
+
/* @__PURE__ */ jsx15("span", { className: "truncate", children: f.label })
|
|
1798
1823
|
]
|
|
1799
1824
|
},
|
|
1800
1825
|
f.id
|
|
@@ -1804,7 +1829,7 @@ function SidebarLayoutInner({
|
|
|
1804
1829
|
item.id
|
|
1805
1830
|
);
|
|
1806
1831
|
}
|
|
1807
|
-
return item.togglesPanel ? /* @__PURE__ */
|
|
1832
|
+
return item.togglesPanel ? /* @__PURE__ */ jsx15(
|
|
1808
1833
|
RailButton,
|
|
1809
1834
|
{
|
|
1810
1835
|
icon: item.icon,
|
|
@@ -1815,7 +1840,7 @@ function SidebarLayoutInner({
|
|
|
1815
1840
|
showLabel: showLabels
|
|
1816
1841
|
},
|
|
1817
1842
|
item.id
|
|
1818
|
-
) : /* @__PURE__ */
|
|
1843
|
+
) : /* @__PURE__ */ jsx15(RailButton, { icon: item.icon, label: item.label, badge: item.badge, isActive: activeId === item.id, showLabel: showLabels, asChild: true, children: /* @__PURE__ */ jsx15(
|
|
1819
1844
|
Link,
|
|
1820
1845
|
{
|
|
1821
1846
|
href: item.href,
|
|
@@ -1825,11 +1850,11 @@ function SidebarLayoutInner({
|
|
|
1825
1850
|
}
|
|
1826
1851
|
) }, item.id);
|
|
1827
1852
|
}) }),
|
|
1828
|
-
(railLabels || railFooter !== void 0 || hasProfile) && /* @__PURE__ */
|
|
1829
|
-
railLabels && /* @__PURE__ */
|
|
1853
|
+
(railLabels || railFooter !== void 0 || hasProfile) && /* @__PURE__ */ jsxs14(SidebarRailFooter, { className: cn("border-t border-border pt-2", showLabels && "items-stretch px-2"), children: [
|
|
1854
|
+
railLabels && /* @__PURE__ */ jsx15(RailCollapseToggle, { collapsed: railCollapsed, showLabel: showLabels, onToggle: toggleRail }),
|
|
1830
1855
|
railFooter,
|
|
1831
1856
|
hasProfile && (() => {
|
|
1832
|
-
const profile = /* @__PURE__ */
|
|
1857
|
+
const profile = /* @__PURE__ */ jsx15(
|
|
1833
1858
|
ProfileAvatar,
|
|
1834
1859
|
{
|
|
1835
1860
|
user: user ?? void 0,
|
|
@@ -1843,19 +1868,19 @@ function SidebarLayoutInner({
|
|
|
1843
1868
|
}
|
|
1844
1869
|
);
|
|
1845
1870
|
if (!showThemeToggle) return profile;
|
|
1846
|
-
return showLabels ? /* @__PURE__ */
|
|
1847
|
-
/* @__PURE__ */
|
|
1848
|
-
/* @__PURE__ */
|
|
1849
|
-
] }) : /* @__PURE__ */
|
|
1850
|
-
/* @__PURE__ */
|
|
1871
|
+
return showLabels ? /* @__PURE__ */ jsxs14("div", { className: "flex w-full items-center gap-1", children: [
|
|
1872
|
+
/* @__PURE__ */ jsx15("div", { className: "min-w-0 flex-1", children: profile }),
|
|
1873
|
+
/* @__PURE__ */ jsx15(RailThemeToggle, {})
|
|
1874
|
+
] }) : /* @__PURE__ */ jsxs14("div", { className: "flex flex-col items-center gap-1", children: [
|
|
1875
|
+
/* @__PURE__ */ jsx15(RailThemeToggle, {}),
|
|
1851
1876
|
profile
|
|
1852
1877
|
] });
|
|
1853
1878
|
})()
|
|
1854
1879
|
] })
|
|
1855
1880
|
] }),
|
|
1856
|
-
panel != null && /* @__PURE__ */
|
|
1881
|
+
panel != null && /* @__PURE__ */ jsx15(SidebarPanel, { children: panel })
|
|
1857
1882
|
] }) }),
|
|
1858
|
-
/* @__PURE__ */
|
|
1883
|
+
/* @__PURE__ */ jsx15(SidebarContent, { className: contentClassName, children })
|
|
1859
1884
|
] });
|
|
1860
1885
|
}
|
|
1861
1886
|
function SidebarLayout({
|
|
@@ -1867,7 +1892,7 @@ function SidebarLayout({
|
|
|
1867
1892
|
defaultRailCollapsed,
|
|
1868
1893
|
...props
|
|
1869
1894
|
}) {
|
|
1870
|
-
return /* @__PURE__ */
|
|
1895
|
+
return /* @__PURE__ */ jsx15(
|
|
1871
1896
|
SidebarProvider,
|
|
1872
1897
|
{
|
|
1873
1898
|
panelOpen,
|
|
@@ -1878,7 +1903,7 @@ function SidebarLayout({
|
|
|
1878
1903
|
defaultRailCollapsed,
|
|
1879
1904
|
hasPanels: props.panel != null,
|
|
1880
1905
|
labeledRail: props.railLabels ?? false,
|
|
1881
|
-
children: /* @__PURE__ */
|
|
1906
|
+
children: /* @__PURE__ */ jsx15(SidebarLayoutInner, { ...props })
|
|
1882
1907
|
}
|
|
1883
1908
|
);
|
|
1884
1909
|
}
|
|
@@ -1895,7 +1920,7 @@ import {
|
|
|
1895
1920
|
DropdownMenuSeparator as DropdownMenuSeparator4,
|
|
1896
1921
|
DropdownMenuTrigger as DropdownMenuTrigger4
|
|
1897
1922
|
} from "@tangle-network/ui/primitives";
|
|
1898
|
-
import { Fragment as
|
|
1923
|
+
import { Fragment as Fragment9, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1899
1924
|
function ProfileSelector({
|
|
1900
1925
|
profiles,
|
|
1901
1926
|
selectedId,
|
|
@@ -1910,77 +1935,77 @@ function ProfileSelector({
|
|
|
1910
1935
|
const selected = profiles.find((p) => p.id === selectedId);
|
|
1911
1936
|
const builtinProfiles = profiles.filter((p) => p.is_builtin);
|
|
1912
1937
|
const customProfiles = profiles.filter((p) => !p.is_builtin);
|
|
1913
|
-
return /* @__PURE__ */
|
|
1914
|
-
label && /* @__PURE__ */
|
|
1915
|
-
/* @__PURE__ */
|
|
1916
|
-
/* @__PURE__ */
|
|
1917
|
-
/* @__PURE__ */
|
|
1918
|
-
/* @__PURE__ */
|
|
1938
|
+
return /* @__PURE__ */ jsxs15("div", { className, children: [
|
|
1939
|
+
label && /* @__PURE__ */ jsx16("label", { className: "mb-2 block font-medium text-sm", children: label }),
|
|
1940
|
+
/* @__PURE__ */ jsxs15(DropdownMenu4, { children: [
|
|
1941
|
+
/* @__PURE__ */ jsx16(DropdownMenuTrigger4, { asChild: true, children: /* @__PURE__ */ jsxs15(Button2, { variant: "outline", className: "w-full justify-between", children: [
|
|
1942
|
+
/* @__PURE__ */ jsx16("span", { className: "truncate", children: selected ? selected.name : placeholder }),
|
|
1943
|
+
/* @__PURE__ */ jsx16(ChevronDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })
|
|
1919
1944
|
] }) }),
|
|
1920
|
-
/* @__PURE__ */
|
|
1921
|
-
/* @__PURE__ */
|
|
1945
|
+
/* @__PURE__ */ jsxs15(DropdownMenuContent4, { className: "w-[300px]", align: "start", children: [
|
|
1946
|
+
/* @__PURE__ */ jsxs15(
|
|
1922
1947
|
DropdownMenuItem4,
|
|
1923
1948
|
{
|
|
1924
1949
|
onClick: () => onSelect(null),
|
|
1925
1950
|
className: "flex items-center justify-between",
|
|
1926
1951
|
children: [
|
|
1927
|
-
/* @__PURE__ */
|
|
1928
|
-
!selectedId && /* @__PURE__ */
|
|
1952
|
+
/* @__PURE__ */ jsx16("span", { children: placeholder }),
|
|
1953
|
+
!selectedId && /* @__PURE__ */ jsx16(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
|
|
1929
1954
|
]
|
|
1930
1955
|
}
|
|
1931
1956
|
),
|
|
1932
|
-
builtinProfiles.length > 0 && /* @__PURE__ */
|
|
1933
|
-
/* @__PURE__ */
|
|
1934
|
-
/* @__PURE__ */
|
|
1935
|
-
builtinProfiles.map((profile) => /* @__PURE__ */
|
|
1957
|
+
builtinProfiles.length > 0 && /* @__PURE__ */ jsxs15(Fragment9, { children: [
|
|
1958
|
+
/* @__PURE__ */ jsx16(DropdownMenuSeparator4, {}),
|
|
1959
|
+
/* @__PURE__ */ jsx16(DropdownMenuLabel2, { children: "Built-in Profiles" }),
|
|
1960
|
+
builtinProfiles.map((profile) => /* @__PURE__ */ jsxs15(
|
|
1936
1961
|
DropdownMenuItem4,
|
|
1937
1962
|
{
|
|
1938
1963
|
onClick: () => onSelect(profile),
|
|
1939
1964
|
className: "flex flex-col items-start gap-1",
|
|
1940
1965
|
children: [
|
|
1941
|
-
/* @__PURE__ */
|
|
1942
|
-
/* @__PURE__ */
|
|
1943
|
-
/* @__PURE__ */
|
|
1944
|
-
profile.extends && /* @__PURE__ */
|
|
1966
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex w-full items-center justify-between", children: [
|
|
1967
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
|
|
1968
|
+
/* @__PURE__ */ jsx16("span", { className: "font-medium", children: profile.name }),
|
|
1969
|
+
profile.extends && /* @__PURE__ */ jsxs15(Badge, { variant: "secondary", className: "border-0 text-xs", children: [
|
|
1945
1970
|
"extends ",
|
|
1946
1971
|
profile.extends
|
|
1947
1972
|
] })
|
|
1948
1973
|
] }),
|
|
1949
|
-
selectedId === profile.id && /* @__PURE__ */
|
|
1974
|
+
selectedId === profile.id && /* @__PURE__ */ jsx16(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
|
|
1950
1975
|
] }),
|
|
1951
|
-
profile.description && /* @__PURE__ */
|
|
1976
|
+
profile.description && /* @__PURE__ */ jsx16("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description })
|
|
1952
1977
|
]
|
|
1953
1978
|
},
|
|
1954
1979
|
profile.id
|
|
1955
1980
|
))
|
|
1956
1981
|
] }),
|
|
1957
|
-
customProfiles.length > 0 && /* @__PURE__ */
|
|
1958
|
-
/* @__PURE__ */
|
|
1959
|
-
/* @__PURE__ */
|
|
1960
|
-
customProfiles.map((profile) => /* @__PURE__ */
|
|
1982
|
+
customProfiles.length > 0 && /* @__PURE__ */ jsxs15(Fragment9, { children: [
|
|
1983
|
+
/* @__PURE__ */ jsx16(DropdownMenuSeparator4, {}),
|
|
1984
|
+
/* @__PURE__ */ jsx16(DropdownMenuLabel2, { children: "Custom Profiles" }),
|
|
1985
|
+
customProfiles.map((profile) => /* @__PURE__ */ jsxs15(
|
|
1961
1986
|
DropdownMenuItem4,
|
|
1962
1987
|
{
|
|
1963
1988
|
onClick: () => onSelect(profile),
|
|
1964
1989
|
className: "flex flex-col items-start gap-1",
|
|
1965
1990
|
children: [
|
|
1966
|
-
/* @__PURE__ */
|
|
1967
|
-
/* @__PURE__ */
|
|
1968
|
-
/* @__PURE__ */
|
|
1969
|
-
profile.model && /* @__PURE__ */
|
|
1991
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex w-full items-center justify-between", children: [
|
|
1992
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
|
|
1993
|
+
/* @__PURE__ */ jsx16("span", { className: "font-medium", children: profile.name }),
|
|
1994
|
+
profile.model && /* @__PURE__ */ jsx16(Badge, { variant: "secondary", className: "border-0 text-xs", children: profile.model.split("/").pop() })
|
|
1970
1995
|
] }),
|
|
1971
|
-
selectedId === profile.id && /* @__PURE__ */
|
|
1996
|
+
selectedId === profile.id && /* @__PURE__ */ jsx16(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
|
|
1972
1997
|
] }),
|
|
1973
|
-
profile.description && /* @__PURE__ */
|
|
1974
|
-
showMetrics && profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */
|
|
1975
|
-
/* @__PURE__ */
|
|
1998
|
+
profile.description && /* @__PURE__ */ jsx16("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description }),
|
|
1999
|
+
showMetrics && profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */ jsxs15("div", { className: "flex gap-3 text-muted-foreground text-xs", children: [
|
|
2000
|
+
/* @__PURE__ */ jsxs15("span", { children: [
|
|
1976
2001
|
profile.metrics.total_runs,
|
|
1977
2002
|
" runs"
|
|
1978
2003
|
] }),
|
|
1979
|
-
/* @__PURE__ */
|
|
2004
|
+
/* @__PURE__ */ jsxs15("span", { children: [
|
|
1980
2005
|
profile.metrics.success_rate.toFixed(0),
|
|
1981
2006
|
"% success"
|
|
1982
2007
|
] }),
|
|
1983
|
-
/* @__PURE__ */
|
|
2008
|
+
/* @__PURE__ */ jsxs15("span", { children: [
|
|
1984
2009
|
"~",
|
|
1985
2010
|
(profile.metrics.avg_duration_ms / 1e3).toFixed(1),
|
|
1986
2011
|
"s avg"
|
|
@@ -1991,26 +2016,26 @@ function ProfileSelector({
|
|
|
1991
2016
|
profile.id
|
|
1992
2017
|
))
|
|
1993
2018
|
] }),
|
|
1994
|
-
(onCreateClick || onManageClick) && /* @__PURE__ */
|
|
1995
|
-
/* @__PURE__ */
|
|
1996
|
-
onCreateClick && /* @__PURE__ */
|
|
2019
|
+
(onCreateClick || onManageClick) && /* @__PURE__ */ jsxs15(Fragment9, { children: [
|
|
2020
|
+
/* @__PURE__ */ jsx16(DropdownMenuSeparator4, {}),
|
|
2021
|
+
onCreateClick && /* @__PURE__ */ jsxs15(
|
|
1997
2022
|
DropdownMenuItem4,
|
|
1998
2023
|
{
|
|
1999
2024
|
onClick: onCreateClick,
|
|
2000
2025
|
className: "text-[var(--surface-info-text)]",
|
|
2001
2026
|
children: [
|
|
2002
|
-
/* @__PURE__ */
|
|
2027
|
+
/* @__PURE__ */ jsx16(Plus3, { className: "mr-2 h-4 w-4" }),
|
|
2003
2028
|
"Create New Profile"
|
|
2004
2029
|
]
|
|
2005
2030
|
}
|
|
2006
2031
|
),
|
|
2007
|
-
onManageClick && /* @__PURE__ */
|
|
2032
|
+
onManageClick && /* @__PURE__ */ jsxs15(
|
|
2008
2033
|
DropdownMenuItem4,
|
|
2009
2034
|
{
|
|
2010
2035
|
onClick: onManageClick,
|
|
2011
2036
|
className: "text-muted-foreground",
|
|
2012
2037
|
children: [
|
|
2013
|
-
/* @__PURE__ */
|
|
2038
|
+
/* @__PURE__ */ jsx16(Settings, { className: "mr-2 h-4 w-4" }),
|
|
2014
2039
|
"Manage Profiles"
|
|
2015
2040
|
]
|
|
2016
2041
|
}
|
|
@@ -2036,26 +2061,26 @@ function ProfileComparison({
|
|
|
2036
2061
|
const fastestProfile = profilesWithMetrics.reduce(
|
|
2037
2062
|
(best, p) => (p.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) < (best.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) ? p : best
|
|
2038
2063
|
);
|
|
2039
|
-
return /* @__PURE__ */
|
|
2040
|
-
/* @__PURE__ */
|
|
2041
|
-
/* @__PURE__ */
|
|
2064
|
+
return /* @__PURE__ */ jsxs15("div", { className: `rounded-lg border border-border p-4 ${className ?? ""}`, children: [
|
|
2065
|
+
/* @__PURE__ */ jsx16("h4", { className: "mb-3 font-medium text-sm", children: "Profile Performance" }),
|
|
2066
|
+
/* @__PURE__ */ jsx16("div", { className: "space-y-3", children: profilesWithMetrics.map((profile) => {
|
|
2042
2067
|
const isBestSuccess = profile.id === bestSuccess.id;
|
|
2043
2068
|
const isFastest = profile.id === fastestProfile.id;
|
|
2044
|
-
return /* @__PURE__ */
|
|
2069
|
+
return /* @__PURE__ */ jsxs15(
|
|
2045
2070
|
"div",
|
|
2046
2071
|
{
|
|
2047
2072
|
className: "flex items-center justify-between gap-4",
|
|
2048
2073
|
children: [
|
|
2049
|
-
/* @__PURE__ */
|
|
2050
|
-
/* @__PURE__ */
|
|
2051
|
-
isBestSuccess && /* @__PURE__ */
|
|
2052
|
-
isFastest && !isBestSuccess && /* @__PURE__ */
|
|
2074
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
|
|
2075
|
+
/* @__PURE__ */ jsx16("span", { className: "font-medium", children: profile.name }),
|
|
2076
|
+
isBestSuccess && /* @__PURE__ */ jsx16(Badge, { className: "border border-[var(--surface-success-border)] bg-[var(--surface-success-bg)] text-[var(--surface-success-text)] text-xs", children: "Best Success" }),
|
|
2077
|
+
isFastest && !isBestSuccess && /* @__PURE__ */ jsx16(Badge, { className: "border border-[var(--surface-info-border)] bg-[var(--surface-info-bg)] text-[var(--surface-info-text)] text-xs", children: "Fastest" })
|
|
2053
2078
|
] }),
|
|
2054
|
-
/* @__PURE__ */
|
|
2055
|
-
/* @__PURE__ */
|
|
2056
|
-
/* @__PURE__ */
|
|
2079
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-4 text-sm", children: [
|
|
2080
|
+
/* @__PURE__ */ jsxs15("span", { children: [
|
|
2081
|
+
/* @__PURE__ */ jsx16("span", { className: "text-muted-foreground", children: "Success:" }),
|
|
2057
2082
|
" ",
|
|
2058
|
-
/* @__PURE__ */
|
|
2083
|
+
/* @__PURE__ */ jsxs15(
|
|
2059
2084
|
"span",
|
|
2060
2085
|
{
|
|
2061
2086
|
className: (profile.metrics?.success_rate ?? 0) >= 80 ? "text-[var(--surface-success-text)]" : (profile.metrics?.success_rate ?? 0) >= 50 ? "text-[var(--surface-warning-text)]" : "text-[var(--surface-danger-text)]",
|
|
@@ -2066,13 +2091,13 @@ function ProfileComparison({
|
|
|
2066
2091
|
}
|
|
2067
2092
|
)
|
|
2068
2093
|
] }),
|
|
2069
|
-
/* @__PURE__ */
|
|
2070
|
-
/* @__PURE__ */
|
|
2094
|
+
/* @__PURE__ */ jsxs15("span", { children: [
|
|
2095
|
+
/* @__PURE__ */ jsx16("span", { className: "text-muted-foreground", children: "Avg:" }),
|
|
2071
2096
|
" ",
|
|
2072
2097
|
((profile.metrics?.avg_duration_ms ?? 0) / 1e3).toFixed(1),
|
|
2073
2098
|
"s"
|
|
2074
2099
|
] }),
|
|
2075
|
-
/* @__PURE__ */
|
|
2100
|
+
/* @__PURE__ */ jsxs15("span", { className: "text-muted-foreground", children: [
|
|
2076
2101
|
profile.metrics?.total_runs,
|
|
2077
2102
|
" runs"
|
|
2078
2103
|
] })
|
|
@@ -2087,7 +2112,7 @@ function ProfileComparison({
|
|
|
2087
2112
|
|
|
2088
2113
|
// src/dashboard/metric-area-chart.tsx
|
|
2089
2114
|
import * as React7 from "react";
|
|
2090
|
-
import { jsx as
|
|
2115
|
+
import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2091
2116
|
var TONE_VARS = {
|
|
2092
2117
|
primary: "var(--brand-primary, hsl(var(--primary)))",
|
|
2093
2118
|
success: "var(--status-running, #22c55e)",
|
|
@@ -2141,7 +2166,7 @@ function MetricAreaChart({
|
|
|
2141
2166
|
const yMax = maxValue ?? (observedMax > 0 ? observedMax * 1.1 : 1);
|
|
2142
2167
|
const segments = buildSegments(points, width, height, yMax);
|
|
2143
2168
|
const color = TONE_VARS[tone];
|
|
2144
|
-
return /* @__PURE__ */
|
|
2169
|
+
return /* @__PURE__ */ jsxs16(
|
|
2145
2170
|
"div",
|
|
2146
2171
|
{
|
|
2147
2172
|
className: cn(
|
|
@@ -2150,21 +2175,21 @@ function MetricAreaChart({
|
|
|
2150
2175
|
),
|
|
2151
2176
|
"data-testid": `metric-chart-${label.toLowerCase().replace(/\s+/g, "-")}`,
|
|
2152
2177
|
children: [
|
|
2153
|
-
/* @__PURE__ */
|
|
2154
|
-
/* @__PURE__ */
|
|
2155
|
-
/* @__PURE__ */
|
|
2156
|
-
/* @__PURE__ */
|
|
2157
|
-
detail && /* @__PURE__ */
|
|
2178
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-baseline justify-between gap-3", children: [
|
|
2179
|
+
/* @__PURE__ */ jsx17("p", { className: "font-medium text-muted-foreground text-xs uppercase tracking-[0.12em]", children: label }),
|
|
2180
|
+
/* @__PURE__ */ jsxs16("div", { className: "text-right", children: [
|
|
2181
|
+
/* @__PURE__ */ jsx17("span", { className: "font-semibold text-foreground text-xl tabular-nums tracking-tight", children: latest === null ? "\u2014" : formatValue(latest) }),
|
|
2182
|
+
detail && /* @__PURE__ */ jsx17("span", { className: "ml-1.5 text-muted-foreground text-xs", children: detail })
|
|
2158
2183
|
] })
|
|
2159
2184
|
] }),
|
|
2160
|
-
/* @__PURE__ */
|
|
2185
|
+
/* @__PURE__ */ jsx17("div", { className: "mt-3", children: values.length === 0 ? /* @__PURE__ */ jsx17(
|
|
2161
2186
|
"div",
|
|
2162
2187
|
{
|
|
2163
2188
|
className: "flex items-center justify-center text-muted-foreground text-xs",
|
|
2164
2189
|
style: { height },
|
|
2165
2190
|
children: emptyState ?? "Waiting for samples\u2026"
|
|
2166
2191
|
}
|
|
2167
|
-
) : /* @__PURE__ */
|
|
2192
|
+
) : /* @__PURE__ */ jsxs16(
|
|
2168
2193
|
"svg",
|
|
2169
2194
|
{
|
|
2170
2195
|
viewBox: `0 0 ${width} ${height}`,
|
|
@@ -2174,7 +2199,7 @@ function MetricAreaChart({
|
|
|
2174
2199
|
role: "img",
|
|
2175
2200
|
"aria-label": `${label} chart`,
|
|
2176
2201
|
children: [
|
|
2177
|
-
[0.25, 0.5, 0.75].map((fraction) => /* @__PURE__ */
|
|
2202
|
+
[0.25, 0.5, 0.75].map((fraction) => /* @__PURE__ */ jsx17(
|
|
2178
2203
|
"line",
|
|
2179
2204
|
{
|
|
2180
2205
|
x1: 0,
|
|
@@ -2189,13 +2214,13 @@ function MetricAreaChart({
|
|
|
2189
2214
|
},
|
|
2190
2215
|
fraction
|
|
2191
2216
|
)),
|
|
2192
|
-
/* @__PURE__ */
|
|
2193
|
-
/* @__PURE__ */
|
|
2194
|
-
/* @__PURE__ */
|
|
2217
|
+
/* @__PURE__ */ jsx17("defs", { children: /* @__PURE__ */ jsxs16("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
2218
|
+
/* @__PURE__ */ jsx17("stop", { offset: "0%", stopColor: color, stopOpacity: 0.28 }),
|
|
2219
|
+
/* @__PURE__ */ jsx17("stop", { offset: "100%", stopColor: color, stopOpacity: 0.02 })
|
|
2195
2220
|
] }) }),
|
|
2196
|
-
segments.map((segment) => /* @__PURE__ */
|
|
2197
|
-
/* @__PURE__ */
|
|
2198
|
-
/* @__PURE__ */
|
|
2221
|
+
segments.map((segment) => /* @__PURE__ */ jsxs16(React7.Fragment, { children: [
|
|
2222
|
+
/* @__PURE__ */ jsx17("path", { d: segment.area, fill: `url(#${gradientId})` }),
|
|
2223
|
+
/* @__PURE__ */ jsx17(
|
|
2199
2224
|
"path",
|
|
2200
2225
|
{
|
|
2201
2226
|
d: segment.path,
|
|
@@ -2211,9 +2236,9 @@ function MetricAreaChart({
|
|
|
2211
2236
|
]
|
|
2212
2237
|
}
|
|
2213
2238
|
) }),
|
|
2214
|
-
/* @__PURE__ */
|
|
2215
|
-
/* @__PURE__ */
|
|
2216
|
-
/* @__PURE__ */
|
|
2239
|
+
/* @__PURE__ */ jsxs16("div", { className: "mt-1.5 flex justify-between text-[10px] text-muted-foreground tabular-nums", children: [
|
|
2240
|
+
/* @__PURE__ */ jsx17("span", { children: values.length > 0 ? formatValue(0) : "" }),
|
|
2241
|
+
/* @__PURE__ */ jsx17("span", { children: values.length > 0 ? formatValue(yMax) : "" })
|
|
2217
2242
|
] })
|
|
2218
2243
|
]
|
|
2219
2244
|
}
|
|
@@ -2233,7 +2258,7 @@ import {
|
|
|
2233
2258
|
} from "lucide-react";
|
|
2234
2259
|
import { Button as Button3 } from "@tangle-network/ui/primitives";
|
|
2235
2260
|
import { Badge as Badge2 } from "@tangle-network/ui/primitives";
|
|
2236
|
-
import { Fragment as
|
|
2261
|
+
import { Fragment as Fragment11, jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2237
2262
|
var statusConfig = {
|
|
2238
2263
|
pending: {
|
|
2239
2264
|
icon: Clock3,
|
|
@@ -2317,19 +2342,19 @@ function VariantList({
|
|
|
2317
2342
|
isActioning,
|
|
2318
2343
|
className
|
|
2319
2344
|
}) {
|
|
2320
|
-
return /* @__PURE__ */
|
|
2345
|
+
return /* @__PURE__ */ jsx18("div", { className: `space-y-2 ${className || ""}`, children: variants.map((variant) => {
|
|
2321
2346
|
const status = statusConfig[variant.status];
|
|
2322
2347
|
const StatusIcon = status.icon;
|
|
2323
2348
|
const isSelected = variant.id === selectedId;
|
|
2324
|
-
return /* @__PURE__ */
|
|
2349
|
+
return /* @__PURE__ */ jsxs17(
|
|
2325
2350
|
"div",
|
|
2326
2351
|
{
|
|
2327
2352
|
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"}`,
|
|
2328
2353
|
onClick: () => onSelect?.(variant.id),
|
|
2329
2354
|
children: [
|
|
2330
|
-
/* @__PURE__ */
|
|
2331
|
-
/* @__PURE__ */
|
|
2332
|
-
/* @__PURE__ */
|
|
2355
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2", children: [
|
|
2356
|
+
/* @__PURE__ */ jsxs17(Badge2, { className: `shrink-0 ${status.bg} ${status.border} ${status.color}`, children: [
|
|
2357
|
+
/* @__PURE__ */ jsx18(
|
|
2333
2358
|
StatusIcon,
|
|
2334
2359
|
{
|
|
2335
2360
|
className: `mr-1 h-3 w-3 ${status.animate ? "animate-spin" : ""}`
|
|
@@ -2337,27 +2362,27 @@ function VariantList({
|
|
|
2337
2362
|
),
|
|
2338
2363
|
status.label
|
|
2339
2364
|
] }),
|
|
2340
|
-
/* @__PURE__ */
|
|
2341
|
-
variant.sublabel && /* @__PURE__ */
|
|
2365
|
+
/* @__PURE__ */ jsx18("span", { className: "truncate text-sm font-medium text-foreground", children: variant.label }),
|
|
2366
|
+
variant.sublabel && /* @__PURE__ */ jsxs17("span", { className: "shrink-0 text-xs text-muted-foreground", children: [
|
|
2342
2367
|
"(",
|
|
2343
2368
|
variant.sublabel,
|
|
2344
2369
|
")"
|
|
2345
2370
|
] }),
|
|
2346
|
-
variant.durationMs && /* @__PURE__ */
|
|
2347
|
-
/* @__PURE__ */
|
|
2371
|
+
variant.durationMs && /* @__PURE__ */ jsxs17("span", { className: "flex shrink-0 items-center gap-1 text-xs text-muted-foreground", children: [
|
|
2372
|
+
/* @__PURE__ */ jsx18(Timer, { className: "h-3 w-3" }),
|
|
2348
2373
|
(variant.durationMs / 1e3).toFixed(1),
|
|
2349
2374
|
"s"
|
|
2350
2375
|
] }),
|
|
2351
|
-
/* @__PURE__ */
|
|
2352
|
-
variant.outcome && /* @__PURE__ */
|
|
2376
|
+
/* @__PURE__ */ jsxs17("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
|
|
2377
|
+
variant.outcome && /* @__PURE__ */ jsx18(
|
|
2353
2378
|
Badge2,
|
|
2354
2379
|
{
|
|
2355
2380
|
className: `${outcomeConfig[variant.outcome].bg} ${outcomeConfig[variant.outcome].border} ${outcomeConfig[variant.outcome].color}`,
|
|
2356
2381
|
children: outcomeConfig[variant.outcome].label
|
|
2357
2382
|
}
|
|
2358
2383
|
),
|
|
2359
|
-
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */
|
|
2360
|
-
/* @__PURE__ */
|
|
2384
|
+
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */ jsxs17(Fragment11, { children: [
|
|
2385
|
+
/* @__PURE__ */ jsxs17(
|
|
2361
2386
|
Button3,
|
|
2362
2387
|
{
|
|
2363
2388
|
variant: "outline",
|
|
@@ -2369,12 +2394,12 @@ function VariantList({
|
|
|
2369
2394
|
},
|
|
2370
2395
|
disabled: isActioning === variant.id,
|
|
2371
2396
|
children: [
|
|
2372
|
-
/* @__PURE__ */
|
|
2397
|
+
/* @__PURE__ */ jsx18(Check3, { className: "mr-1 h-3 w-3" }),
|
|
2373
2398
|
"Accept"
|
|
2374
2399
|
]
|
|
2375
2400
|
}
|
|
2376
2401
|
),
|
|
2377
|
-
/* @__PURE__ */
|
|
2402
|
+
/* @__PURE__ */ jsxs17(
|
|
2378
2403
|
Button3,
|
|
2379
2404
|
{
|
|
2380
2405
|
variant: "outline",
|
|
@@ -2386,13 +2411,13 @@ function VariantList({
|
|
|
2386
2411
|
},
|
|
2387
2412
|
disabled: isActioning === variant.id,
|
|
2388
2413
|
children: [
|
|
2389
|
-
/* @__PURE__ */
|
|
2414
|
+
/* @__PURE__ */ jsx18(X, { className: "mr-1 h-3 w-3" }),
|
|
2390
2415
|
"Reject"
|
|
2391
2416
|
]
|
|
2392
2417
|
}
|
|
2393
2418
|
)
|
|
2394
2419
|
] }),
|
|
2395
|
-
variant.detailsUrl && /* @__PURE__ */
|
|
2420
|
+
variant.detailsUrl && /* @__PURE__ */ jsx18(
|
|
2396
2421
|
Button3,
|
|
2397
2422
|
{
|
|
2398
2423
|
variant: "ghost",
|
|
@@ -2402,13 +2427,13 @@ function VariantList({
|
|
|
2402
2427
|
e.stopPropagation();
|
|
2403
2428
|
window.open(variant.detailsUrl, "_blank");
|
|
2404
2429
|
},
|
|
2405
|
-
children: /* @__PURE__ */
|
|
2430
|
+
children: /* @__PURE__ */ jsx18(ExternalLink2, { className: "h-3.5 w-3.5" })
|
|
2406
2431
|
}
|
|
2407
2432
|
)
|
|
2408
2433
|
] })
|
|
2409
2434
|
] }),
|
|
2410
|
-
variant.error && /* @__PURE__ */
|
|
2411
|
-
variant.summary && /* @__PURE__ */
|
|
2435
|
+
variant.error && /* @__PURE__ */ jsx18("p", { className: "mt-1.5 text-xs text-[var(--surface-danger-text)]", children: variant.error }),
|
|
2436
|
+
variant.summary && /* @__PURE__ */ jsx18("p", { className: "mt-1.5 line-clamp-2 text-xs text-muted-foreground", children: variant.summary })
|
|
2412
2437
|
]
|
|
2413
2438
|
},
|
|
2414
2439
|
variant.id
|
|
@@ -2419,7 +2444,7 @@ function VariantList({
|
|
|
2419
2444
|
// src/dashboard/system-logs.tsx
|
|
2420
2445
|
import { Terminal as Terminal3 } from "lucide-react";
|
|
2421
2446
|
import { useEffect as useEffect3, useRef as useRef3, useState as useState5 } from "react";
|
|
2422
|
-
import { jsx as
|
|
2447
|
+
import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2423
2448
|
function SystemLogsViewer({ apiUrl, token, className }) {
|
|
2424
2449
|
const [logs, setLogs] = useState5([]);
|
|
2425
2450
|
const [error, setError] = useState5(null);
|
|
@@ -2472,18 +2497,18 @@ function SystemLogsViewer({ apiUrl, token, className }) {
|
|
|
2472
2497
|
const isAtBottom = scrollHeight - scrollTop - clientHeight < 20;
|
|
2473
2498
|
setIsFollowing((prev) => prev === isAtBottom ? prev : isAtBottom);
|
|
2474
2499
|
};
|
|
2475
|
-
return /* @__PURE__ */
|
|
2476
|
-
/* @__PURE__ */
|
|
2477
|
-
/* @__PURE__ */
|
|
2478
|
-
/* @__PURE__ */
|
|
2479
|
-
/* @__PURE__ */
|
|
2500
|
+
return /* @__PURE__ */ jsxs18("div", { className: cn("flex flex-col h-full bg-background text-foreground font-mono text-sm leading-relaxed overflow-hidden rounded-lg border border-border", className), children: [
|
|
2501
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex-none flex items-center justify-between border-b border-border bg-muted/50 backdrop-blur-md px-4 py-2", children: [
|
|
2502
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2", children: [
|
|
2503
|
+
/* @__PURE__ */ jsx19(Terminal3, { className: "h-4 w-4 text-primary animate-pulse" }),
|
|
2504
|
+
/* @__PURE__ */ jsx19("span", { className: "font-bold text-xs uppercase tracking-widest text-muted-foreground", children: "System Traces" })
|
|
2480
2505
|
] }),
|
|
2481
|
-
/* @__PURE__ */
|
|
2482
|
-
error && /* @__PURE__ */
|
|
2483
|
-
/* @__PURE__ */
|
|
2506
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-3", children: [
|
|
2507
|
+
error && /* @__PURE__ */ jsxs18("span", { className: "text-destructive text-xs flex items-center gap-1", children: [
|
|
2508
|
+
/* @__PURE__ */ jsx19("span", { className: "w-2 h-2 rounded-full bg-destructive animate-ping" }),
|
|
2484
2509
|
" Error fetching logs"
|
|
2485
2510
|
] }),
|
|
2486
|
-
/* @__PURE__ */
|
|
2511
|
+
/* @__PURE__ */ jsx19(
|
|
2487
2512
|
"button",
|
|
2488
2513
|
{
|
|
2489
2514
|
onClick: () => {
|
|
@@ -2498,29 +2523,29 @@ function SystemLogsViewer({ apiUrl, token, className }) {
|
|
|
2498
2523
|
)
|
|
2499
2524
|
] })
|
|
2500
2525
|
] }),
|
|
2501
|
-
/* @__PURE__ */
|
|
2526
|
+
/* @__PURE__ */ jsx19(
|
|
2502
2527
|
"div",
|
|
2503
2528
|
{
|
|
2504
2529
|
ref: scrollRef,
|
|
2505
2530
|
onScroll: handleScroll,
|
|
2506
2531
|
className: "flex-1 overflow-y-auto p-4 space-y-1",
|
|
2507
|
-
children: logs.length === 0 && !error ? /* @__PURE__ */
|
|
2508
|
-
/* @__PURE__ */
|
|
2532
|
+
children: logs.length === 0 && !error ? /* @__PURE__ */ jsx19("div", { className: "flex h-full items-center justify-center text-muted-foreground italic", children: "Waiting for orchestrator logs..." }) : logs.map((log, i) => /* @__PURE__ */ jsxs18("div", { className: "break-words", children: [
|
|
2533
|
+
/* @__PURE__ */ jsxs18("span", { className: "text-muted-foreground mr-3 select-none", children: [
|
|
2509
2534
|
"[",
|
|
2510
2535
|
log.timestamp || i.toString().padStart(4, "0"),
|
|
2511
2536
|
"]"
|
|
2512
2537
|
] }),
|
|
2513
|
-
/* @__PURE__ */
|
|
2538
|
+
/* @__PURE__ */ jsxs18("span", { className: "text-primary/70 mr-2", children: [
|
|
2514
2539
|
"[",
|
|
2515
2540
|
log.level,
|
|
2516
2541
|
"]"
|
|
2517
2542
|
] }),
|
|
2518
|
-
/* @__PURE__ */
|
|
2543
|
+
/* @__PURE__ */ jsxs18("span", { className: "text-muted-foreground mr-2", children: [
|
|
2519
2544
|
"[",
|
|
2520
2545
|
log.scope,
|
|
2521
2546
|
"]"
|
|
2522
2547
|
] }),
|
|
2523
|
-
/* @__PURE__ */
|
|
2548
|
+
/* @__PURE__ */ jsx19("span", { className: log.level.toUpperCase() === "ERROR" || log.message.toLowerCase().includes("failed") ? "text-destructive" : log.level.toUpperCase() === "WARN" ? "text-warning" : "text-foreground", children: log.message })
|
|
2524
2549
|
] }, `${log.timestamp}-${log.scope}-${i}`))
|
|
2525
2550
|
}
|
|
2526
2551
|
)
|
|
@@ -2531,50 +2556,50 @@ function SystemLogsViewer({ apiUrl, token, className }) {
|
|
|
2531
2556
|
import { Clock as Clock4, Layers, MessageSquare, DollarSign } from "lucide-react";
|
|
2532
2557
|
import { StatCard } from "@tangle-network/ui/primitives";
|
|
2533
2558
|
import { Skeleton as Skeleton4 } from "@tangle-network/ui/primitives";
|
|
2534
|
-
import { jsx as
|
|
2559
|
+
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2535
2560
|
function UsageSummary({ data, loading = false, className }) {
|
|
2536
2561
|
if (loading || !data) {
|
|
2537
|
-
return /* @__PURE__ */
|
|
2562
|
+
return /* @__PURE__ */ jsx20("div", { className: cn("grid grid-cols-2 gap-4 lg:grid-cols-4", className), children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsx20(Skeleton4, { className: "h-28 rounded-xl" }, i)) });
|
|
2538
2563
|
}
|
|
2539
|
-
return /* @__PURE__ */
|
|
2540
|
-
/* @__PURE__ */
|
|
2564
|
+
return /* @__PURE__ */ jsxs19("div", { className: cn("grid grid-cols-2 gap-4 lg:grid-cols-4", className), children: [
|
|
2565
|
+
/* @__PURE__ */ jsx20(
|
|
2541
2566
|
StatCard,
|
|
2542
2567
|
{
|
|
2543
2568
|
variant: "sandbox",
|
|
2544
2569
|
title: "Compute Hours",
|
|
2545
2570
|
value: data.computeHours.toFixed(1),
|
|
2546
2571
|
subtitle: "This billing period",
|
|
2547
|
-
icon: /* @__PURE__ */
|
|
2572
|
+
icon: /* @__PURE__ */ jsx20(Clock4, { className: "h-5 w-5" })
|
|
2548
2573
|
}
|
|
2549
2574
|
),
|
|
2550
|
-
/* @__PURE__ */
|
|
2575
|
+
/* @__PURE__ */ jsx20(
|
|
2551
2576
|
StatCard,
|
|
2552
2577
|
{
|
|
2553
2578
|
variant: "sandbox",
|
|
2554
2579
|
title: "Active Sessions",
|
|
2555
2580
|
value: data.activeSessions,
|
|
2556
2581
|
subtitle: "Currently running",
|
|
2557
|
-
icon: /* @__PURE__ */
|
|
2582
|
+
icon: /* @__PURE__ */ jsx20(Layers, { className: "h-5 w-5" })
|
|
2558
2583
|
}
|
|
2559
2584
|
),
|
|
2560
|
-
/* @__PURE__ */
|
|
2585
|
+
/* @__PURE__ */ jsx20(
|
|
2561
2586
|
StatCard,
|
|
2562
2587
|
{
|
|
2563
2588
|
variant: "sandbox",
|
|
2564
2589
|
title: "Messages Sent",
|
|
2565
2590
|
value: data.messagesSent.toLocaleString(),
|
|
2566
2591
|
subtitle: "Agent interactions",
|
|
2567
|
-
icon: /* @__PURE__ */
|
|
2592
|
+
icon: /* @__PURE__ */ jsx20(MessageSquare, { className: "h-5 w-5" })
|
|
2568
2593
|
}
|
|
2569
2594
|
),
|
|
2570
|
-
/* @__PURE__ */
|
|
2595
|
+
/* @__PURE__ */ jsx20(
|
|
2571
2596
|
StatCard,
|
|
2572
2597
|
{
|
|
2573
2598
|
variant: "sandbox",
|
|
2574
2599
|
title: "Estimated Cost",
|
|
2575
2600
|
value: `$${data.estimatedCost.toFixed(2)}`,
|
|
2576
2601
|
subtitle: "This billing period",
|
|
2577
|
-
icon: /* @__PURE__ */
|
|
2602
|
+
icon: /* @__PURE__ */ jsx20(DollarSign, { className: "h-5 w-5" })
|
|
2578
2603
|
}
|
|
2579
2604
|
)
|
|
2580
2605
|
] });
|
|
@@ -2582,66 +2607,66 @@ function UsageSummary({ data, loading = false, className }) {
|
|
|
2582
2607
|
|
|
2583
2608
|
// src/dashboard/git-panel.tsx
|
|
2584
2609
|
import { GitBranch, GitCommit, FileEdit, FilePlus, File } from "lucide-react";
|
|
2585
|
-
import { jsx as
|
|
2610
|
+
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2586
2611
|
function GitPanel({ status, log, loading = false, onRefresh, className }) {
|
|
2587
2612
|
if (loading) {
|
|
2588
|
-
return /* @__PURE__ */
|
|
2589
|
-
/* @__PURE__ */
|
|
2613
|
+
return /* @__PURE__ */ jsx21("div", { className: cn("rounded-lg border border-border bg-card p-5", className), children: /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
2614
|
+
/* @__PURE__ */ jsx21("div", { className: "h-4 w-4 animate-spin rounded-full border-2 border-primary border-t-transparent" }),
|
|
2590
2615
|
"Loading git info..."
|
|
2591
2616
|
] }) });
|
|
2592
2617
|
}
|
|
2593
2618
|
if (!status) {
|
|
2594
|
-
return /* @__PURE__ */
|
|
2595
|
-
/* @__PURE__ */
|
|
2619
|
+
return /* @__PURE__ */ jsx21("div", { className: cn("rounded-lg border border-border bg-card p-5", className), children: /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
2620
|
+
/* @__PURE__ */ jsx21(GitBranch, { className: "h-4 w-4" }),
|
|
2596
2621
|
"No git repository detected"
|
|
2597
2622
|
] }) });
|
|
2598
2623
|
}
|
|
2599
2624
|
const changedCount = status.staged.length + status.modified.length + status.untracked.length;
|
|
2600
|
-
return /* @__PURE__ */
|
|
2601
|
-
/* @__PURE__ */
|
|
2602
|
-
/* @__PURE__ */
|
|
2603
|
-
/* @__PURE__ */
|
|
2604
|
-
/* @__PURE__ */
|
|
2605
|
-
status.isDirty && /* @__PURE__ */
|
|
2625
|
+
return /* @__PURE__ */ jsxs20("div", { className: cn("rounded-lg border border-border bg-card overflow-hidden", className), children: [
|
|
2626
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between border-b border-border bg-muted/30 px-4 py-3", children: [
|
|
2627
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2", children: [
|
|
2628
|
+
/* @__PURE__ */ jsx21(GitBranch, { className: "h-4 w-4 text-primary" }),
|
|
2629
|
+
/* @__PURE__ */ jsx21("span", { className: "text-sm font-bold text-foreground", children: status.branch }),
|
|
2630
|
+
status.isDirty && /* @__PURE__ */ jsxs20("span", { className: "rounded-full bg-[var(--surface-warning-bg)] px-1.5 py-0.5 text-[10px] font-bold text-[var(--surface-warning-text)]", children: [
|
|
2606
2631
|
changedCount,
|
|
2607
2632
|
" change",
|
|
2608
2633
|
changedCount !== 1 ? "s" : ""
|
|
2609
2634
|
] })
|
|
2610
2635
|
] }),
|
|
2611
|
-
onRefresh && /* @__PURE__ */
|
|
2636
|
+
onRefresh && /* @__PURE__ */ jsx21("button", { type: "button", onClick: onRefresh, className: "text-xs text-muted-foreground hover:text-foreground transition-colors", children: "Refresh" })
|
|
2612
2637
|
] }),
|
|
2613
|
-
changedCount > 0 && /* @__PURE__ */
|
|
2614
|
-
status.staged.map((f) => /* @__PURE__ */
|
|
2615
|
-
/* @__PURE__ */
|
|
2616
|
-
/* @__PURE__ */
|
|
2617
|
-
/* @__PURE__ */
|
|
2638
|
+
changedCount > 0 && /* @__PURE__ */ jsx21("div", { className: "border-b border-border px-4 py-3", children: /* @__PURE__ */ jsxs20("div", { className: "space-y-1.5", children: [
|
|
2639
|
+
status.staged.map((f) => /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2640
|
+
/* @__PURE__ */ jsx21(FilePlus, { className: "h-3 w-3 text-[var(--surface-success-text)]" }),
|
|
2641
|
+
/* @__PURE__ */ jsx21("span", { className: "font-mono text-foreground truncate", children: f }),
|
|
2642
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[var(--surface-success-text)] text-[10px] font-bold ml-auto", children: "STAGED" })
|
|
2618
2643
|
] }, `s-${f}`)),
|
|
2619
|
-
status.modified.map((f) => /* @__PURE__ */
|
|
2620
|
-
/* @__PURE__ */
|
|
2621
|
-
/* @__PURE__ */
|
|
2644
|
+
status.modified.map((f) => /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2645
|
+
/* @__PURE__ */ jsx21(FileEdit, { className: "h-3 w-3 text-[var(--surface-warning-text)]" }),
|
|
2646
|
+
/* @__PURE__ */ jsx21("span", { className: "font-mono text-foreground truncate", children: f })
|
|
2622
2647
|
] }, `m-${f}`)),
|
|
2623
|
-
status.untracked.map((f) => /* @__PURE__ */
|
|
2624
|
-
/* @__PURE__ */
|
|
2625
|
-
/* @__PURE__ */
|
|
2648
|
+
status.untracked.map((f) => /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2649
|
+
/* @__PURE__ */ jsx21(File, { className: "h-3 w-3 text-muted-foreground" }),
|
|
2650
|
+
/* @__PURE__ */ jsx21("span", { className: "font-mono text-muted-foreground truncate", children: f })
|
|
2626
2651
|
] }, `u-${f}`))
|
|
2627
2652
|
] }) }),
|
|
2628
|
-
log.length > 0 && /* @__PURE__ */
|
|
2629
|
-
/* @__PURE__ */
|
|
2630
|
-
/* @__PURE__ */
|
|
2631
|
-
/* @__PURE__ */
|
|
2632
|
-
/* @__PURE__ */
|
|
2633
|
-
/* @__PURE__ */
|
|
2634
|
-
/* @__PURE__ */
|
|
2653
|
+
log.length > 0 && /* @__PURE__ */ jsxs20("div", { className: "px-4 py-3", children: [
|
|
2654
|
+
/* @__PURE__ */ jsx21("div", { className: "mb-2 text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Recent Commits" }),
|
|
2655
|
+
/* @__PURE__ */ jsx21("div", { className: "space-y-2", children: log.slice(0, 5).map((commit) => /* @__PURE__ */ jsxs20("div", { className: "flex items-start gap-2 text-xs", children: [
|
|
2656
|
+
/* @__PURE__ */ jsx21(GitCommit, { className: "h-3 w-3 text-muted-foreground mt-0.5 shrink-0" }),
|
|
2657
|
+
/* @__PURE__ */ jsxs20("div", { className: "min-w-0", children: [
|
|
2658
|
+
/* @__PURE__ */ jsx21("span", { className: "font-mono text-primary mr-1.5", children: commit.shortSha }),
|
|
2659
|
+
/* @__PURE__ */ jsx21("span", { className: "text-foreground", children: commit.message })
|
|
2635
2660
|
] })
|
|
2636
2661
|
] }, commit.shortSha)) })
|
|
2637
2662
|
] }),
|
|
2638
|
-
(status.ahead > 0 || status.behind > 0) && /* @__PURE__ */
|
|
2639
|
-
status.ahead > 0 && /* @__PURE__ */
|
|
2663
|
+
(status.ahead > 0 || status.behind > 0) && /* @__PURE__ */ jsxs20("div", { className: "border-t border-border px-4 py-2 flex items-center gap-3 text-xs text-muted-foreground", children: [
|
|
2664
|
+
status.ahead > 0 && /* @__PURE__ */ jsxs20("span", { children: [
|
|
2640
2665
|
"\u2191 ",
|
|
2641
2666
|
status.ahead,
|
|
2642
2667
|
" ahead"
|
|
2643
2668
|
] }),
|
|
2644
|
-
status.behind > 0 && /* @__PURE__ */
|
|
2669
|
+
status.behind > 0 && /* @__PURE__ */ jsxs20("span", { children: [
|
|
2645
2670
|
"\u2193 ",
|
|
2646
2671
|
status.behind,
|
|
2647
2672
|
" behind"
|
|
@@ -2653,7 +2678,7 @@ function GitPanel({ status, log, loading = false, onRefresh, className }) {
|
|
|
2653
2678
|
// src/dashboard/ports-list.tsx
|
|
2654
2679
|
import * as React9 from "react";
|
|
2655
2680
|
import { Copy as Copy3, Check as Check4, Globe, Plus as Plus4, Trash2 as Trash23 } from "lucide-react";
|
|
2656
|
-
import { jsx as
|
|
2681
|
+
import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2657
2682
|
function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, className }) {
|
|
2658
2683
|
const [newPort, setNewPort] = React9.useState("");
|
|
2659
2684
|
const [copiedPort, setCopiedPort] = React9.useState(null);
|
|
@@ -2680,48 +2705,48 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2680
2705
|
setNewPort("");
|
|
2681
2706
|
}
|
|
2682
2707
|
};
|
|
2683
|
-
return /* @__PURE__ */
|
|
2684
|
-
ports.length > 0 ? /* @__PURE__ */
|
|
2685
|
-
/* @__PURE__ */
|
|
2686
|
-
/* @__PURE__ */
|
|
2687
|
-
/* @__PURE__ */
|
|
2688
|
-
/* @__PURE__ */
|
|
2689
|
-
/* @__PURE__ */
|
|
2708
|
+
return /* @__PURE__ */ jsxs21("div", { className: cn("space-y-4", className), children: [
|
|
2709
|
+
ports.length > 0 ? /* @__PURE__ */ jsx22("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs21("table", { className: "w-full text-sm", children: [
|
|
2710
|
+
/* @__PURE__ */ jsx22("thead", { className: "bg-muted/30 border-b border-border", children: /* @__PURE__ */ jsxs21("tr", { children: [
|
|
2711
|
+
/* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Port" }),
|
|
2712
|
+
/* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Public URL" }),
|
|
2713
|
+
/* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Status" }),
|
|
2714
|
+
/* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground w-20" })
|
|
2690
2715
|
] }) }),
|
|
2691
|
-
/* @__PURE__ */
|
|
2692
|
-
/* @__PURE__ */
|
|
2693
|
-
/* @__PURE__ */
|
|
2716
|
+
/* @__PURE__ */ jsx22("tbody", { className: "divide-y divide-border", children: ports.map((p) => /* @__PURE__ */ jsxs21("tr", { children: [
|
|
2717
|
+
/* @__PURE__ */ jsx22("td", { className: "px-4 py-3 font-mono text-xs text-foreground", children: p.port }),
|
|
2718
|
+
/* @__PURE__ */ jsx22("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs21(
|
|
2694
2719
|
"button",
|
|
2695
2720
|
{
|
|
2696
2721
|
type: "button",
|
|
2697
2722
|
onClick: () => handleCopy(p.url, p.port),
|
|
2698
2723
|
className: "flex items-center gap-2 font-mono text-xs text-primary hover:underline cursor-pointer group",
|
|
2699
2724
|
children: [
|
|
2700
|
-
/* @__PURE__ */
|
|
2701
|
-
copiedPort === p.port ? /* @__PURE__ */
|
|
2725
|
+
/* @__PURE__ */ jsx22("span", { className: "truncate max-w-[300px]", children: p.url }),
|
|
2726
|
+
copiedPort === p.port ? /* @__PURE__ */ jsx22(Check4, { className: "h-3 w-3 text-[var(--surface-success-text)] shrink-0" }) : /* @__PURE__ */ jsx22(Copy3, { className: "h-3 w-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0" })
|
|
2702
2727
|
]
|
|
2703
2728
|
}
|
|
2704
2729
|
) }),
|
|
2705
|
-
/* @__PURE__ */
|
|
2730
|
+
/* @__PURE__ */ jsx22("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx22("span", { className: cn(
|
|
2706
2731
|
"inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider",
|
|
2707
2732
|
p.status === "active" ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : "bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]"
|
|
2708
2733
|
), children: p.status }) }),
|
|
2709
|
-
/* @__PURE__ */
|
|
2734
|
+
/* @__PURE__ */ jsx22("td", { className: "px-4 py-3 text-right", children: onRemovePort && /* @__PURE__ */ jsx22(
|
|
2710
2735
|
"button",
|
|
2711
2736
|
{
|
|
2712
2737
|
type: "button",
|
|
2713
2738
|
onClick: () => onRemovePort(p.port),
|
|
2714
2739
|
className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
|
|
2715
|
-
children: /* @__PURE__ */
|
|
2740
|
+
children: /* @__PURE__ */ jsx22(Trash23, { className: "h-3.5 w-3.5" })
|
|
2716
2741
|
}
|
|
2717
2742
|
) })
|
|
2718
2743
|
] }, p.port)) })
|
|
2719
|
-
] }) }) : /* @__PURE__ */
|
|
2720
|
-
/* @__PURE__ */
|
|
2721
|
-
/* @__PURE__ */
|
|
2744
|
+
] }) }) : /* @__PURE__ */ jsxs21("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
2745
|
+
/* @__PURE__ */ jsx22(Globe, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
|
|
2746
|
+
/* @__PURE__ */ jsx22("p", { className: "text-sm text-muted-foreground", children: "No ports exposed yet" })
|
|
2722
2747
|
] }),
|
|
2723
|
-
/* @__PURE__ */
|
|
2724
|
-
/* @__PURE__ */
|
|
2748
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-3", children: [
|
|
2749
|
+
/* @__PURE__ */ jsx22(
|
|
2725
2750
|
"input",
|
|
2726
2751
|
{
|
|
2727
2752
|
type: "number",
|
|
@@ -2731,10 +2756,10 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2731
2756
|
value: newPort,
|
|
2732
2757
|
onChange: (e) => setNewPort(e.target.value),
|
|
2733
2758
|
onKeyDown: (e) => e.key === "Enter" && handleExpose(),
|
|
2734
|
-
className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-
|
|
2759
|
+
className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
2735
2760
|
}
|
|
2736
2761
|
),
|
|
2737
|
-
/* @__PURE__ */
|
|
2762
|
+
/* @__PURE__ */ jsxs21(
|
|
2738
2763
|
"button",
|
|
2739
2764
|
{
|
|
2740
2765
|
type: "button",
|
|
@@ -2742,7 +2767,7 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2742
2767
|
disabled: !newPort || isExposing,
|
|
2743
2768
|
className: "inline-flex items-center gap-2 rounded-lg bg-primary/20 border border-primary/30 px-4 py-2 text-sm font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors disabled:opacity-50",
|
|
2744
2769
|
children: [
|
|
2745
|
-
/* @__PURE__ */
|
|
2770
|
+
/* @__PURE__ */ jsx22(Plus4, { className: "h-4 w-4" }),
|
|
2746
2771
|
"Expose"
|
|
2747
2772
|
]
|
|
2748
2773
|
}
|
|
@@ -2754,7 +2779,7 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
|
|
|
2754
2779
|
// src/dashboard/process-list.tsx
|
|
2755
2780
|
import * as React10 from "react";
|
|
2756
2781
|
import { Activity as Activity3, Plus as Plus5, Skull, Terminal as Terminal4 } from "lucide-react";
|
|
2757
|
-
import { jsx as
|
|
2782
|
+
import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2758
2783
|
function formatUptime(startedAt) {
|
|
2759
2784
|
if (!startedAt) return "-";
|
|
2760
2785
|
const ms = Date.now() - new Date(startedAt).getTime();
|
|
@@ -2772,43 +2797,43 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2772
2797
|
setNewCommand("");
|
|
2773
2798
|
}
|
|
2774
2799
|
};
|
|
2775
|
-
return /* @__PURE__ */
|
|
2776
|
-
loading ? /* @__PURE__ */
|
|
2777
|
-
/* @__PURE__ */
|
|
2778
|
-
/* @__PURE__ */
|
|
2779
|
-
] }) : processes.length > 0 ? /* @__PURE__ */
|
|
2780
|
-
/* @__PURE__ */
|
|
2781
|
-
/* @__PURE__ */
|
|
2782
|
-
/* @__PURE__ */
|
|
2783
|
-
/* @__PURE__ */
|
|
2784
|
-
/* @__PURE__ */
|
|
2785
|
-
/* @__PURE__ */
|
|
2800
|
+
return /* @__PURE__ */ jsxs22("div", { className: cn("space-y-4", className), children: [
|
|
2801
|
+
loading ? /* @__PURE__ */ jsxs22("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
2802
|
+
/* @__PURE__ */ jsx23(Activity3, { className: "mx-auto h-6 w-6 text-muted-foreground animate-spin mb-2" }),
|
|
2803
|
+
/* @__PURE__ */ jsx23("p", { className: "text-sm text-muted-foreground", children: "Loading processes..." })
|
|
2804
|
+
] }) : processes.length > 0 ? /* @__PURE__ */ jsx23("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs22("table", { className: "w-full text-sm", children: [
|
|
2805
|
+
/* @__PURE__ */ jsx23("thead", { className: "bg-muted/30 border-b border-border", children: /* @__PURE__ */ jsxs22("tr", { children: [
|
|
2806
|
+
/* @__PURE__ */ jsx23("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "PID" }),
|
|
2807
|
+
/* @__PURE__ */ jsx23("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Command" }),
|
|
2808
|
+
/* @__PURE__ */ jsx23("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Status" }),
|
|
2809
|
+
/* @__PURE__ */ jsx23("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Uptime" }),
|
|
2810
|
+
/* @__PURE__ */ jsx23("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground w-20" })
|
|
2786
2811
|
] }) }),
|
|
2787
|
-
/* @__PURE__ */
|
|
2788
|
-
/* @__PURE__ */
|
|
2789
|
-
/* @__PURE__ */
|
|
2790
|
-
/* @__PURE__ */
|
|
2812
|
+
/* @__PURE__ */ jsx23("tbody", { className: "divide-y divide-border", children: processes.map((p) => /* @__PURE__ */ jsxs22("tr", { children: [
|
|
2813
|
+
/* @__PURE__ */ jsx23("td", { className: "px-4 py-3 font-mono text-xs text-foreground", children: p.pid }),
|
|
2814
|
+
/* @__PURE__ */ jsx23("td", { className: "px-4 py-3 font-mono text-xs text-foreground truncate max-w-[250px]", children: p.command }),
|
|
2815
|
+
/* @__PURE__ */ jsx23("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx23("span", { className: cn(
|
|
2791
2816
|
"inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider",
|
|
2792
2817
|
p.running ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : "bg-muted text-muted-foreground"
|
|
2793
2818
|
), children: p.running ? "running" : `exited (${p.exitCode ?? "?"})` }) }),
|
|
2794
|
-
/* @__PURE__ */
|
|
2795
|
-
/* @__PURE__ */
|
|
2819
|
+
/* @__PURE__ */ jsx23("td", { className: "px-4 py-3 font-mono text-xs text-muted-foreground", children: formatUptime(p.startedAt) }),
|
|
2820
|
+
/* @__PURE__ */ jsx23("td", { className: "px-4 py-3 text-right", children: p.running && /* @__PURE__ */ jsx23(
|
|
2796
2821
|
"button",
|
|
2797
2822
|
{
|
|
2798
2823
|
type: "button",
|
|
2799
2824
|
onClick: () => onKill(p.pid),
|
|
2800
2825
|
className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
|
|
2801
2826
|
title: "Kill process",
|
|
2802
|
-
children: /* @__PURE__ */
|
|
2827
|
+
children: /* @__PURE__ */ jsx23(Skull, { className: "h-3.5 w-3.5" })
|
|
2803
2828
|
}
|
|
2804
2829
|
) })
|
|
2805
2830
|
] }, `${p.pid}-${p.startedAt ?? p.command}`)) })
|
|
2806
|
-
] }) }) : /* @__PURE__ */
|
|
2807
|
-
/* @__PURE__ */
|
|
2808
|
-
/* @__PURE__ */
|
|
2831
|
+
] }) }) : /* @__PURE__ */ jsxs22("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
2832
|
+
/* @__PURE__ */ jsx23(Terminal4, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
|
|
2833
|
+
/* @__PURE__ */ jsx23("p", { className: "text-sm text-muted-foreground", children: "No processes running" })
|
|
2809
2834
|
] }),
|
|
2810
|
-
/* @__PURE__ */
|
|
2811
|
-
/* @__PURE__ */
|
|
2835
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-3", children: [
|
|
2836
|
+
/* @__PURE__ */ jsx23(
|
|
2812
2837
|
"input",
|
|
2813
2838
|
{
|
|
2814
2839
|
type: "text",
|
|
@@ -2816,10 +2841,10 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2816
2841
|
value: newCommand,
|
|
2817
2842
|
onChange: (e) => setNewCommand(e.target.value),
|
|
2818
2843
|
onKeyDown: (e) => e.key === "Enter" && handleSpawn(),
|
|
2819
|
-
className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-
|
|
2844
|
+
className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
2820
2845
|
}
|
|
2821
2846
|
),
|
|
2822
|
-
/* @__PURE__ */
|
|
2847
|
+
/* @__PURE__ */ jsxs22(
|
|
2823
2848
|
"button",
|
|
2824
2849
|
{
|
|
2825
2850
|
type: "button",
|
|
@@ -2827,7 +2852,7 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2827
2852
|
disabled: !newCommand.trim(),
|
|
2828
2853
|
className: "inline-flex items-center gap-2 rounded-lg bg-primary/20 border border-primary/30 px-4 py-2 text-sm font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors disabled:opacity-50",
|
|
2829
2854
|
children: [
|
|
2830
|
-
/* @__PURE__ */
|
|
2855
|
+
/* @__PURE__ */ jsx23(Plus5, { className: "h-4 w-4" }),
|
|
2831
2856
|
"Spawn"
|
|
2832
2857
|
]
|
|
2833
2858
|
}
|
|
@@ -2839,7 +2864,7 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
|
|
|
2839
2864
|
// src/dashboard/network-config.tsx
|
|
2840
2865
|
import * as React11 from "react";
|
|
2841
2866
|
import { Network as Network2, Plus as Plus6, Trash2 as Trash24, ShieldAlert } from "lucide-react";
|
|
2842
|
-
import { jsx as
|
|
2867
|
+
import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2843
2868
|
function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
2844
2869
|
const [newCidr, setNewCidr] = React11.useState("");
|
|
2845
2870
|
const isValidCidr = (value) => {
|
|
@@ -2862,21 +2887,21 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2862
2887
|
}
|
|
2863
2888
|
};
|
|
2864
2889
|
if (loading || !config) {
|
|
2865
|
-
return /* @__PURE__ */
|
|
2866
|
-
/* @__PURE__ */
|
|
2867
|
-
/* @__PURE__ */
|
|
2890
|
+
return /* @__PURE__ */ jsxs23("div", { className: cn("rounded-lg border border-border bg-muted/20 p-6 text-center", className), children: [
|
|
2891
|
+
/* @__PURE__ */ jsx24(Network2, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
|
|
2892
|
+
/* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground", children: "Loading network configuration..." })
|
|
2868
2893
|
] });
|
|
2869
2894
|
}
|
|
2870
|
-
return /* @__PURE__ */
|
|
2871
|
-
/* @__PURE__ */
|
|
2872
|
-
/* @__PURE__ */
|
|
2873
|
-
/* @__PURE__ */
|
|
2874
|
-
/* @__PURE__ */
|
|
2875
|
-
/* @__PURE__ */
|
|
2876
|
-
/* @__PURE__ */
|
|
2895
|
+
return /* @__PURE__ */ jsxs23("div", { className: cn("space-y-4", className), children: [
|
|
2896
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between rounded-lg border border-border bg-card px-4 py-3", children: [
|
|
2897
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-3", children: [
|
|
2898
|
+
/* @__PURE__ */ jsx24(ShieldAlert, { className: "h-4 w-4 text-muted-foreground" }),
|
|
2899
|
+
/* @__PURE__ */ jsxs23("div", { children: [
|
|
2900
|
+
/* @__PURE__ */ jsx24("p", { className: "text-sm font-medium text-foreground", children: "Block Outbound Traffic" }),
|
|
2901
|
+
/* @__PURE__ */ jsx24("p", { className: "text-xs text-muted-foreground", children: "Prevent the sandbox from making external network requests" })
|
|
2877
2902
|
] })
|
|
2878
2903
|
] }),
|
|
2879
|
-
/* @__PURE__ */
|
|
2904
|
+
/* @__PURE__ */ jsx24(
|
|
2880
2905
|
"button",
|
|
2881
2906
|
{
|
|
2882
2907
|
type: "button",
|
|
@@ -2888,7 +2913,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2888
2913
|
"relative inline-flex h-6 w-11 items-center rounded-full transition-colors",
|
|
2889
2914
|
config.blockOutbound ? "bg-destructive" : "bg-muted"
|
|
2890
2915
|
),
|
|
2891
|
-
children: /* @__PURE__ */
|
|
2916
|
+
children: /* @__PURE__ */ jsx24(
|
|
2892
2917
|
"span",
|
|
2893
2918
|
{
|
|
2894
2919
|
className: cn(
|
|
@@ -2900,22 +2925,22 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2900
2925
|
}
|
|
2901
2926
|
)
|
|
2902
2927
|
] }),
|
|
2903
|
-
/* @__PURE__ */
|
|
2904
|
-
/* @__PURE__ */
|
|
2905
|
-
config.allowList.length > 0 ? /* @__PURE__ */
|
|
2906
|
-
/* @__PURE__ */
|
|
2907
|
-
/* @__PURE__ */
|
|
2928
|
+
/* @__PURE__ */ jsxs23("div", { children: [
|
|
2929
|
+
/* @__PURE__ */ jsx24("h4", { className: "text-xs font-medium text-muted-foreground mb-2 uppercase tracking-wider", children: "Allowlist (CIDR)" }),
|
|
2930
|
+
config.allowList.length > 0 ? /* @__PURE__ */ jsx24("div", { className: "space-y-1.5 mb-3", children: config.allowList.map((cidr) => /* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between rounded border border-border bg-muted/20 px-3 py-2", children: [
|
|
2931
|
+
/* @__PURE__ */ jsx24("span", { className: "font-mono text-xs text-foreground", children: cidr }),
|
|
2932
|
+
/* @__PURE__ */ jsx24(
|
|
2908
2933
|
"button",
|
|
2909
2934
|
{
|
|
2910
2935
|
type: "button",
|
|
2911
2936
|
onClick: () => handleRemoveCidr(cidr),
|
|
2912
2937
|
className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
|
|
2913
|
-
children: /* @__PURE__ */
|
|
2938
|
+
children: /* @__PURE__ */ jsx24(Trash24, { className: "h-3 w-3" })
|
|
2914
2939
|
}
|
|
2915
2940
|
)
|
|
2916
|
-
] }, cidr)) }) : /* @__PURE__ */
|
|
2917
|
-
/* @__PURE__ */
|
|
2918
|
-
/* @__PURE__ */
|
|
2941
|
+
] }, cidr)) }) : /* @__PURE__ */ jsx24("p", { className: "text-xs text-muted-foreground mb-3", children: "No CIDR rules configured. All traffic is allowed." }),
|
|
2942
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-3", children: [
|
|
2943
|
+
/* @__PURE__ */ jsx24(
|
|
2919
2944
|
"input",
|
|
2920
2945
|
{
|
|
2921
2946
|
type: "text",
|
|
@@ -2923,10 +2948,10 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2923
2948
|
value: newCidr,
|
|
2924
2949
|
onChange: (e) => setNewCidr(e.target.value),
|
|
2925
2950
|
onKeyDown: (e) => e.key === "Enter" && handleAddCidr(),
|
|
2926
|
-
className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-
|
|
2951
|
+
className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
2927
2952
|
}
|
|
2928
2953
|
),
|
|
2929
|
-
/* @__PURE__ */
|
|
2954
|
+
/* @__PURE__ */ jsxs23(
|
|
2930
2955
|
"button",
|
|
2931
2956
|
{
|
|
2932
2957
|
type: "button",
|
|
@@ -2934,7 +2959,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2934
2959
|
disabled: !newCidr.trim(),
|
|
2935
2960
|
className: "inline-flex items-center gap-2 rounded-lg bg-primary/20 border border-primary/30 px-4 py-2 text-sm font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors disabled:opacity-50",
|
|
2936
2961
|
children: [
|
|
2937
|
-
/* @__PURE__ */
|
|
2962
|
+
/* @__PURE__ */ jsx24(Plus6, { className: "h-4 w-4" }),
|
|
2938
2963
|
"Add"
|
|
2939
2964
|
]
|
|
2940
2965
|
}
|
|
@@ -2947,7 +2972,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
|
|
|
2947
2972
|
// src/dashboard/backend-config.tsx
|
|
2948
2973
|
import * as React12 from "react";
|
|
2949
2974
|
import { Bot, Plus as Plus7, RefreshCw as RefreshCw2, Trash2 as Trash25, Server, Wrench } from "lucide-react";
|
|
2950
|
-
import { Fragment as
|
|
2975
|
+
import { Fragment as Fragment12, jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2951
2976
|
function BackendConfig({
|
|
2952
2977
|
status,
|
|
2953
2978
|
mcpServers,
|
|
@@ -2977,122 +3002,122 @@ function BackendConfig({
|
|
|
2977
3002
|
}
|
|
2978
3003
|
};
|
|
2979
3004
|
if (loading || !status) {
|
|
2980
|
-
return /* @__PURE__ */
|
|
2981
|
-
/* @__PURE__ */
|
|
2982
|
-
/* @__PURE__ */
|
|
3005
|
+
return /* @__PURE__ */ jsxs24("div", { className: cn("rounded-lg border border-border bg-muted/20 p-6 text-center", className), children: [
|
|
3006
|
+
/* @__PURE__ */ jsx25(Bot, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
|
|
3007
|
+
/* @__PURE__ */ jsx25("p", { className: "text-sm text-muted-foreground", children: "Loading backend status..." })
|
|
2983
3008
|
] });
|
|
2984
3009
|
}
|
|
2985
|
-
return /* @__PURE__ */
|
|
2986
|
-
/* @__PURE__ */
|
|
2987
|
-
/* @__PURE__ */
|
|
2988
|
-
/* @__PURE__ */
|
|
2989
|
-
/* @__PURE__ */
|
|
3010
|
+
return /* @__PURE__ */ jsxs24("div", { className: cn("space-y-4", className), children: [
|
|
3011
|
+
/* @__PURE__ */ jsxs24("div", { className: "rounded-lg border border-border bg-card overflow-hidden", children: [
|
|
3012
|
+
/* @__PURE__ */ jsxs24("div", { className: "px-4 py-3 border-b border-border bg-muted/30 flex items-center justify-between", children: [
|
|
3013
|
+
/* @__PURE__ */ jsx25("h4", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider", children: "Agent Status" }),
|
|
3014
|
+
/* @__PURE__ */ jsxs24(
|
|
2990
3015
|
"button",
|
|
2991
3016
|
{
|
|
2992
3017
|
type: "button",
|
|
2993
3018
|
onClick: onRestart,
|
|
2994
3019
|
className: "inline-flex items-center gap-1.5 rounded-md bg-muted px-2.5 py-1 text-xs font-medium text-foreground hover:bg-muted/80 transition-colors border border-border",
|
|
2995
3020
|
children: [
|
|
2996
|
-
/* @__PURE__ */
|
|
3021
|
+
/* @__PURE__ */ jsx25(RefreshCw2, { className: "h-3 w-3" }),
|
|
2997
3022
|
"Restart"
|
|
2998
3023
|
]
|
|
2999
3024
|
}
|
|
3000
3025
|
)
|
|
3001
3026
|
] }),
|
|
3002
|
-
/* @__PURE__ */
|
|
3003
|
-
/* @__PURE__ */
|
|
3004
|
-
/* @__PURE__ */
|
|
3027
|
+
/* @__PURE__ */ jsx25("div", { className: "p-4", children: /* @__PURE__ */ jsxs24("dl", { className: "grid grid-cols-[100px_1fr] gap-y-3 text-sm", children: [
|
|
3028
|
+
/* @__PURE__ */ jsx25("dt", { className: "text-muted-foreground", children: "Status" }),
|
|
3029
|
+
/* @__PURE__ */ jsx25("dd", { children: /* @__PURE__ */ jsx25("span", { className: cn(
|
|
3005
3030
|
"inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider",
|
|
3006
3031
|
status.running ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : "bg-destructive/10 text-destructive"
|
|
3007
3032
|
), children: status.running ? "Running" : "Stopped" }) }),
|
|
3008
|
-
/* @__PURE__ */
|
|
3009
|
-
/* @__PURE__ */
|
|
3010
|
-
status.provider && /* @__PURE__ */
|
|
3011
|
-
/* @__PURE__ */
|
|
3012
|
-
/* @__PURE__ */
|
|
3033
|
+
/* @__PURE__ */ jsx25("dt", { className: "text-muted-foreground", children: "Model" }),
|
|
3034
|
+
/* @__PURE__ */ jsx25("dd", { className: "font-mono text-xs", children: status.model ?? "Default" }),
|
|
3035
|
+
status.provider && /* @__PURE__ */ jsxs24(Fragment12, { children: [
|
|
3036
|
+
/* @__PURE__ */ jsx25("dt", { className: "text-muted-foreground", children: "Provider" }),
|
|
3037
|
+
/* @__PURE__ */ jsx25("dd", { className: "font-mono text-xs", children: status.provider })
|
|
3013
3038
|
] })
|
|
3014
3039
|
] }) })
|
|
3015
3040
|
] }),
|
|
3016
|
-
/* @__PURE__ */
|
|
3017
|
-
/* @__PURE__ */
|
|
3018
|
-
/* @__PURE__ */
|
|
3019
|
-
/* @__PURE__ */
|
|
3041
|
+
/* @__PURE__ */ jsxs24("div", { className: "rounded-lg border border-border bg-card overflow-hidden", children: [
|
|
3042
|
+
/* @__PURE__ */ jsxs24("div", { className: "px-4 py-3 border-b border-border bg-muted/30 flex items-center justify-between", children: [
|
|
3043
|
+
/* @__PURE__ */ jsxs24("h4", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: [
|
|
3044
|
+
/* @__PURE__ */ jsx25(Wrench, { className: "h-3.5 w-3.5" }),
|
|
3020
3045
|
"MCP Servers"
|
|
3021
3046
|
] }),
|
|
3022
|
-
/* @__PURE__ */
|
|
3047
|
+
/* @__PURE__ */ jsxs24(
|
|
3023
3048
|
"button",
|
|
3024
3049
|
{
|
|
3025
3050
|
type: "button",
|
|
3026
3051
|
onClick: () => setShowAddMcp(!showAddMcp),
|
|
3027
3052
|
className: "inline-flex items-center gap-1.5 rounded-md bg-primary/20 border border-primary/30 px-2.5 py-1 text-xs font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors",
|
|
3028
3053
|
children: [
|
|
3029
|
-
/* @__PURE__ */
|
|
3054
|
+
/* @__PURE__ */ jsx25(Plus7, { className: "h-3 w-3" }),
|
|
3030
3055
|
"Add"
|
|
3031
3056
|
]
|
|
3032
3057
|
}
|
|
3033
3058
|
)
|
|
3034
3059
|
] }),
|
|
3035
|
-
mcpServers.length > 0 ? /* @__PURE__ */
|
|
3036
|
-
/* @__PURE__ */
|
|
3037
|
-
/* @__PURE__ */
|
|
3038
|
-
/* @__PURE__ */
|
|
3039
|
-
/* @__PURE__ */
|
|
3040
|
-
/* @__PURE__ */
|
|
3060
|
+
mcpServers.length > 0 ? /* @__PURE__ */ jsx25("div", { className: "divide-y divide-border", children: mcpServers.map((s) => /* @__PURE__ */ jsxs24("div", { className: "flex items-center justify-between px-4 py-3", children: [
|
|
3061
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
3062
|
+
/* @__PURE__ */ jsx25(Server, { className: "h-3.5 w-3.5 text-muted-foreground shrink-0" }),
|
|
3063
|
+
/* @__PURE__ */ jsxs24("div", { className: "min-w-0", children: [
|
|
3064
|
+
/* @__PURE__ */ jsx25("p", { className: "text-sm font-medium text-foreground truncate", children: s.name }),
|
|
3065
|
+
/* @__PURE__ */ jsxs24("p", { className: "text-xs font-mono text-muted-foreground truncate", children: [
|
|
3041
3066
|
s.command,
|
|
3042
3067
|
" ",
|
|
3043
3068
|
s.args?.join(" ") ?? ""
|
|
3044
3069
|
] })
|
|
3045
3070
|
] })
|
|
3046
3071
|
] }),
|
|
3047
|
-
/* @__PURE__ */
|
|
3048
|
-
s.status && /* @__PURE__ */
|
|
3072
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
3073
|
+
s.status && /* @__PURE__ */ jsx25("span", { className: cn(
|
|
3049
3074
|
"inline-flex items-center rounded-full px-1.5 py-0.5 text-[9px] font-bold uppercase",
|
|
3050
3075
|
s.status === "running" ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : s.status === "error" ? "bg-destructive/10 text-destructive" : "bg-muted text-muted-foreground"
|
|
3051
3076
|
), children: s.status }),
|
|
3052
|
-
/* @__PURE__ */
|
|
3077
|
+
/* @__PURE__ */ jsx25(
|
|
3053
3078
|
"button",
|
|
3054
3079
|
{
|
|
3055
3080
|
type: "button",
|
|
3056
3081
|
onClick: () => onRemoveMcp(s.name),
|
|
3057
3082
|
className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
|
|
3058
|
-
children: /* @__PURE__ */
|
|
3083
|
+
children: /* @__PURE__ */ jsx25(Trash25, { className: "h-3.5 w-3.5" })
|
|
3059
3084
|
}
|
|
3060
3085
|
)
|
|
3061
3086
|
] })
|
|
3062
|
-
] }, s.name)) }) : /* @__PURE__ */
|
|
3063
|
-
showAddMcp && /* @__PURE__ */
|
|
3064
|
-
/* @__PURE__ */
|
|
3087
|
+
] }, s.name)) }) : /* @__PURE__ */ jsx25("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsx25("p", { className: "text-xs text-muted-foreground", children: "No MCP servers configured" }) }),
|
|
3088
|
+
showAddMcp && /* @__PURE__ */ jsxs24("div", { className: "p-4 border-t border-border bg-muted/10 space-y-2", children: [
|
|
3089
|
+
/* @__PURE__ */ jsx25(
|
|
3065
3090
|
"input",
|
|
3066
3091
|
{
|
|
3067
3092
|
type: "text",
|
|
3068
3093
|
placeholder: "Server name",
|
|
3069
3094
|
value: mcpName,
|
|
3070
3095
|
onChange: (e) => setMcpName(e.target.value),
|
|
3071
|
-
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-
|
|
3096
|
+
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
3072
3097
|
}
|
|
3073
3098
|
),
|
|
3074
|
-
/* @__PURE__ */
|
|
3099
|
+
/* @__PURE__ */ jsx25(
|
|
3075
3100
|
"input",
|
|
3076
3101
|
{
|
|
3077
3102
|
type: "text",
|
|
3078
3103
|
placeholder: "Command (e.g. npx @server/mcp)",
|
|
3079
3104
|
value: mcpCommand,
|
|
3080
3105
|
onChange: (e) => setMcpCommand(e.target.value),
|
|
3081
|
-
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-
|
|
3106
|
+
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
3082
3107
|
}
|
|
3083
3108
|
),
|
|
3084
|
-
/* @__PURE__ */
|
|
3109
|
+
/* @__PURE__ */ jsx25(
|
|
3085
3110
|
"input",
|
|
3086
3111
|
{
|
|
3087
3112
|
type: "text",
|
|
3088
3113
|
placeholder: "Arguments (space-separated, optional)",
|
|
3089
3114
|
value: mcpArgs,
|
|
3090
3115
|
onChange: (e) => setMcpArgs(e.target.value),
|
|
3091
|
-
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-
|
|
3116
|
+
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
3092
3117
|
}
|
|
3093
3118
|
),
|
|
3094
|
-
/* @__PURE__ */
|
|
3095
|
-
/* @__PURE__ */
|
|
3119
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex justify-end gap-2 pt-1", children: [
|
|
3120
|
+
/* @__PURE__ */ jsx25(
|
|
3096
3121
|
"button",
|
|
3097
3122
|
{
|
|
3098
3123
|
type: "button",
|
|
@@ -3101,7 +3126,7 @@ function BackendConfig({
|
|
|
3101
3126
|
children: "Cancel"
|
|
3102
3127
|
}
|
|
3103
3128
|
),
|
|
3104
|
-
/* @__PURE__ */
|
|
3129
|
+
/* @__PURE__ */ jsx25(
|
|
3105
3130
|
"button",
|
|
3106
3131
|
{
|
|
3107
3132
|
type: "button",
|
|
@@ -3120,7 +3145,7 @@ function BackendConfig({
|
|
|
3120
3145
|
// src/dashboard/snapshot-list.tsx
|
|
3121
3146
|
import * as React13 from "react";
|
|
3122
3147
|
import { Camera, Clock as Clock5, HardDrive, Plus as Plus8, RotateCcw } from "lucide-react";
|
|
3123
|
-
import { jsx as
|
|
3148
|
+
import { jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
3124
3149
|
function formatBytes(bytes) {
|
|
3125
3150
|
if (bytes == null || bytes < 0) return "-";
|
|
3126
3151
|
if (bytes === 0) return "0 B";
|
|
@@ -3143,25 +3168,25 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
3143
3168
|
setTags("");
|
|
3144
3169
|
setShowCreate(false);
|
|
3145
3170
|
};
|
|
3146
|
-
return /* @__PURE__ */
|
|
3147
|
-
/* @__PURE__ */
|
|
3148
|
-
/* @__PURE__ */
|
|
3149
|
-
/* @__PURE__ */
|
|
3171
|
+
return /* @__PURE__ */ jsxs25("div", { className: cn("space-y-4", className), children: [
|
|
3172
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between", children: [
|
|
3173
|
+
/* @__PURE__ */ jsx26("h3", { className: "text-sm font-bold text-foreground", children: "Snapshots" }),
|
|
3174
|
+
/* @__PURE__ */ jsxs25(
|
|
3150
3175
|
"button",
|
|
3151
3176
|
{
|
|
3152
3177
|
type: "button",
|
|
3153
3178
|
onClick: () => setShowCreate(!showCreate),
|
|
3154
3179
|
className: "inline-flex items-center gap-1.5 rounded-lg bg-primary/20 border border-primary/30 px-3 py-1.5 text-xs font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors",
|
|
3155
3180
|
children: [
|
|
3156
|
-
/* @__PURE__ */
|
|
3181
|
+
/* @__PURE__ */ jsx26(Plus8, { className: "h-3.5 w-3.5" }),
|
|
3157
3182
|
"Create Snapshot"
|
|
3158
3183
|
]
|
|
3159
3184
|
}
|
|
3160
3185
|
)
|
|
3161
3186
|
] }),
|
|
3162
|
-
showCreate && /* @__PURE__ */
|
|
3163
|
-
/* @__PURE__ */
|
|
3164
|
-
/* @__PURE__ */
|
|
3187
|
+
showCreate && /* @__PURE__ */ jsxs25("div", { className: "rounded-lg border border-primary/20 bg-primary/5 p-4 space-y-3", children: [
|
|
3188
|
+
/* @__PURE__ */ jsx26("p", { className: "text-sm text-foreground font-medium", children: "Create a new snapshot of the current sandbox state." }),
|
|
3189
|
+
/* @__PURE__ */ jsx26(
|
|
3165
3190
|
"input",
|
|
3166
3191
|
{
|
|
3167
3192
|
type: "text",
|
|
@@ -3169,11 +3194,11 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
3169
3194
|
value: tags,
|
|
3170
3195
|
onChange: (e) => setTags(e.target.value),
|
|
3171
3196
|
onKeyDown: (e) => e.key === "Enter" && handleCreate(),
|
|
3172
|
-
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-
|
|
3197
|
+
className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
3173
3198
|
}
|
|
3174
3199
|
),
|
|
3175
|
-
/* @__PURE__ */
|
|
3176
|
-
/* @__PURE__ */
|
|
3200
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex justify-end gap-2", children: [
|
|
3201
|
+
/* @__PURE__ */ jsx26(
|
|
3177
3202
|
"button",
|
|
3178
3203
|
{
|
|
3179
3204
|
type: "button",
|
|
@@ -3182,44 +3207,44 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
3182
3207
|
children: "Cancel"
|
|
3183
3208
|
}
|
|
3184
3209
|
),
|
|
3185
|
-
/* @__PURE__ */
|
|
3210
|
+
/* @__PURE__ */ jsxs25(
|
|
3186
3211
|
"button",
|
|
3187
3212
|
{
|
|
3188
3213
|
type: "button",
|
|
3189
3214
|
onClick: handleCreate,
|
|
3190
3215
|
className: "rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 transition-colors",
|
|
3191
3216
|
children: [
|
|
3192
|
-
/* @__PURE__ */
|
|
3217
|
+
/* @__PURE__ */ jsx26(Camera, { className: "h-3 w-3 mr-1.5 inline" }),
|
|
3193
3218
|
"Create"
|
|
3194
3219
|
]
|
|
3195
3220
|
}
|
|
3196
3221
|
)
|
|
3197
3222
|
] })
|
|
3198
3223
|
] }),
|
|
3199
|
-
loading ? /* @__PURE__ */
|
|
3200
|
-
/* @__PURE__ */
|
|
3201
|
-
/* @__PURE__ */
|
|
3202
|
-
] }) : snapshots.length > 0 ? /* @__PURE__ */
|
|
3203
|
-
/* @__PURE__ */
|
|
3204
|
-
/* @__PURE__ */
|
|
3205
|
-
/* @__PURE__ */
|
|
3206
|
-
/* @__PURE__ */
|
|
3207
|
-
/* @__PURE__ */
|
|
3208
|
-
/* @__PURE__ */
|
|
3224
|
+
loading ? /* @__PURE__ */ jsxs25("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
3225
|
+
/* @__PURE__ */ jsx26(Camera, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
|
|
3226
|
+
/* @__PURE__ */ jsx26("p", { className: "text-sm text-muted-foreground", children: "Loading snapshots..." })
|
|
3227
|
+
] }) : snapshots.length > 0 ? /* @__PURE__ */ jsx26("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs25("table", { className: "w-full text-sm", children: [
|
|
3228
|
+
/* @__PURE__ */ jsx26("thead", { className: "bg-muted/30 border-b border-border", children: /* @__PURE__ */ jsxs25("tr", { children: [
|
|
3229
|
+
/* @__PURE__ */ jsx26("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "ID" }),
|
|
3230
|
+
/* @__PURE__ */ jsx26("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Created" }),
|
|
3231
|
+
/* @__PURE__ */ jsx26("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Size" }),
|
|
3232
|
+
/* @__PURE__ */ jsx26("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Tags" }),
|
|
3233
|
+
/* @__PURE__ */ jsx26("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground w-24" })
|
|
3209
3234
|
] }) }),
|
|
3210
|
-
/* @__PURE__ */
|
|
3211
|
-
/* @__PURE__ */
|
|
3212
|
-
/* @__PURE__ */
|
|
3213
|
-
/* @__PURE__ */
|
|
3235
|
+
/* @__PURE__ */ jsx26("tbody", { className: "divide-y divide-border", children: snapshots.map((s) => /* @__PURE__ */ jsxs25("tr", { children: [
|
|
3236
|
+
/* @__PURE__ */ jsx26("td", { className: "px-4 py-3 font-mono text-xs text-foreground", children: s.id.slice(0, 12) }),
|
|
3237
|
+
/* @__PURE__ */ jsx26("td", { className: "px-4 py-3 text-xs text-muted-foreground", children: /* @__PURE__ */ jsxs25("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
3238
|
+
/* @__PURE__ */ jsx26(Clock5, { className: "h-3 w-3" }),
|
|
3214
3239
|
formatDate(s.createdAt)
|
|
3215
3240
|
] }) }),
|
|
3216
|
-
/* @__PURE__ */
|
|
3217
|
-
/* @__PURE__ */
|
|
3241
|
+
/* @__PURE__ */ jsx26("td", { className: "px-4 py-3 text-xs text-muted-foreground", children: /* @__PURE__ */ jsxs25("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
3242
|
+
/* @__PURE__ */ jsx26(HardDrive, { className: "h-3 w-3" }),
|
|
3218
3243
|
formatBytes(s.sizeBytes)
|
|
3219
3244
|
] }) }),
|
|
3220
|
-
/* @__PURE__ */
|
|
3221
|
-
/* @__PURE__ */
|
|
3222
|
-
/* @__PURE__ */
|
|
3245
|
+
/* @__PURE__ */ jsx26("td", { className: "px-4 py-3", children: s.tags?.length ? /* @__PURE__ */ jsx26("div", { className: "flex items-center gap-1 flex-wrap", children: s.tags.map((tag) => /* @__PURE__ */ jsx26("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground border border-border", children: tag }, tag)) }) : /* @__PURE__ */ jsx26("span", { className: "text-xs text-muted-foreground", children: "-" }) }),
|
|
3246
|
+
/* @__PURE__ */ jsx26("td", { className: "px-4 py-3 text-right", children: /* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-end gap-2", children: [
|
|
3247
|
+
/* @__PURE__ */ jsxs25(
|
|
3223
3248
|
"button",
|
|
3224
3249
|
{
|
|
3225
3250
|
type: "button",
|
|
@@ -3227,12 +3252,12 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
3227
3252
|
className: "inline-flex items-center gap-1.5 rounded-md bg-muted px-2.5 py-1 text-xs font-medium text-foreground hover:bg-muted/80 transition-colors border border-border",
|
|
3228
3253
|
title: "Restore to new sandbox",
|
|
3229
3254
|
children: [
|
|
3230
|
-
/* @__PURE__ */
|
|
3255
|
+
/* @__PURE__ */ jsx26(RotateCcw, { className: "h-3 w-3" }),
|
|
3231
3256
|
"Restore"
|
|
3232
3257
|
]
|
|
3233
3258
|
}
|
|
3234
3259
|
),
|
|
3235
|
-
onSaveAsTemplate && /* @__PURE__ */
|
|
3260
|
+
onSaveAsTemplate && /* @__PURE__ */ jsx26(
|
|
3236
3261
|
"button",
|
|
3237
3262
|
{
|
|
3238
3263
|
type: "button",
|
|
@@ -3244,16 +3269,16 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
|
|
|
3244
3269
|
)
|
|
3245
3270
|
] }) })
|
|
3246
3271
|
] }, s.id)) })
|
|
3247
|
-
] }) }) : /* @__PURE__ */
|
|
3248
|
-
/* @__PURE__ */
|
|
3249
|
-
/* @__PURE__ */
|
|
3250
|
-
/* @__PURE__ */
|
|
3272
|
+
] }) }) : /* @__PURE__ */ jsxs25("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
|
|
3273
|
+
/* @__PURE__ */ jsx26(Camera, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
|
|
3274
|
+
/* @__PURE__ */ jsx26("p", { className: "text-sm text-muted-foreground", children: "No snapshots yet" }),
|
|
3275
|
+
/* @__PURE__ */ jsx26("p", { className: "text-xs text-muted-foreground mt-1", children: "Create a snapshot to save the current state of your sandbox." })
|
|
3251
3276
|
] })
|
|
3252
3277
|
] });
|
|
3253
3278
|
}
|
|
3254
3279
|
|
|
3255
3280
|
// src/dashboard/promo-banner.tsx
|
|
3256
|
-
import { Fragment as
|
|
3281
|
+
import { Fragment as Fragment13, jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
3257
3282
|
function PromoBanner({
|
|
3258
3283
|
title,
|
|
3259
3284
|
description,
|
|
@@ -3268,21 +3293,21 @@ function PromoBanner({
|
|
|
3268
3293
|
"mt-6 inline-flex items-center gap-2 rounded-md border border-white/20 bg-[var(--btn-primary-bg)] px-4 py-2 text-sm font-medium text-[var(--btn-primary-text)] transition-colors",
|
|
3269
3294
|
disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-[var(--btn-primary-hover)]"
|
|
3270
3295
|
);
|
|
3271
|
-
const buttonContent = /* @__PURE__ */
|
|
3296
|
+
const buttonContent = /* @__PURE__ */ jsxs26(Fragment13, { children: [
|
|
3272
3297
|
buttonLabel,
|
|
3273
|
-
/* @__PURE__ */
|
|
3274
|
-
/* @__PURE__ */
|
|
3275
|
-
/* @__PURE__ */
|
|
3298
|
+
/* @__PURE__ */ jsxs26("svg", { "aria-hidden": "true", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "h-4 w-4", children: [
|
|
3299
|
+
/* @__PURE__ */ jsx27("path", { d: "M5 12h14" }),
|
|
3300
|
+
/* @__PURE__ */ jsx27("path", { d: "m12 5 7 7-7 7" })
|
|
3276
3301
|
] })
|
|
3277
3302
|
] });
|
|
3278
|
-
return /* @__PURE__ */
|
|
3279
|
-
/* @__PURE__ */
|
|
3280
|
-
/* @__PURE__ */
|
|
3281
|
-
/* @__PURE__ */
|
|
3282
|
-
href && !disabled ? /* @__PURE__ */
|
|
3303
|
+
return /* @__PURE__ */ jsxs26("div", { className: cn("relative overflow-hidden rounded-xl bg-[var(--brand-strong)] p-8 md:flex md:items-center md:justify-between", className), children: [
|
|
3304
|
+
/* @__PURE__ */ jsxs26("div", { className: "relative z-10", children: [
|
|
3305
|
+
/* @__PURE__ */ jsx27("h3", { className: "text-xl font-bold text-[var(--brand-strong-text)]", children: title }),
|
|
3306
|
+
/* @__PURE__ */ jsx27("p", { className: "mt-2 max-w-md text-sm text-[var(--brand-strong-text-muted)]", children: description }),
|
|
3307
|
+
href && !disabled ? /* @__PURE__ */ jsx27("a", { href, target: "_blank", rel: "noopener noreferrer", onClick, className: buttonClasses, children: buttonContent }) : /* @__PURE__ */ jsx27("button", { type: "button", onClick, disabled, className: buttonClasses, children: buttonContent })
|
|
3283
3308
|
] }),
|
|
3284
|
-
icon && /* @__PURE__ */
|
|
3285
|
-
/* @__PURE__ */
|
|
3309
|
+
icon && /* @__PURE__ */ jsx27("div", { className: "relative z-10 mt-6 flex items-center md:mt-0", children: /* @__PURE__ */ jsx27("div", { className: "flex h-16 w-16 items-center justify-center rounded-2xl border border-white/10 bg-white/10", children: icon }) }),
|
|
3310
|
+
/* @__PURE__ */ jsx27("div", { className: "pointer-events-none absolute inset-y-0 right-0 w-1/3 bg-gradient-to-l from-white/5 to-transparent" })
|
|
3286
3311
|
] });
|
|
3287
3312
|
}
|
|
3288
3313
|
|
|
@@ -3294,6 +3319,7 @@ export {
|
|
|
3294
3319
|
SIDEBAR_RAIL_LABELED_WIDTH,
|
|
3295
3320
|
SidebarProvider,
|
|
3296
3321
|
useSidebar,
|
|
3322
|
+
RailTooltip,
|
|
3297
3323
|
RailThemeToggle,
|
|
3298
3324
|
RailCollapseToggle,
|
|
3299
3325
|
Sidebar,
|