@chaaskit/client 0.1.0 → 0.1.2
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/LICENSE +21 -0
- package/dist/lib/index.js +1023 -160
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/routes/AcceptInviteRoute.js +1 -1
- package/dist/lib/routes/AcceptInviteRoute.js.map +1 -1
- package/dist/lib/routes/AdminDashboardRoute.js +1 -1
- package/dist/lib/routes/AdminDashboardRoute.js.map +1 -1
- package/dist/lib/routes/AdminPromoCodesRoute.js +19 -0
- package/dist/lib/routes/AdminPromoCodesRoute.js.map +1 -0
- package/dist/lib/routes/AdminTeamRoute.js +1 -1
- package/dist/lib/routes/AdminTeamRoute.js.map +1 -1
- package/dist/lib/routes/AdminTeamsRoute.js +1 -1
- package/dist/lib/routes/AdminTeamsRoute.js.map +1 -1
- package/dist/lib/routes/AdminUsersRoute.js +1 -1
- package/dist/lib/routes/AdminUsersRoute.js.map +1 -1
- package/dist/lib/routes/AdminWaitlistRoute.js +19 -0
- package/dist/lib/routes/AdminWaitlistRoute.js.map +1 -0
- package/dist/lib/routes/ApiKeysRoute.js +1 -1
- package/dist/lib/routes/ApiKeysRoute.js.map +1 -1
- package/dist/lib/routes/AutomationsRoute.js +1 -1
- package/dist/lib/routes/AutomationsRoute.js.map +1 -1
- package/dist/lib/routes/ChatRoute.js +1 -1
- package/dist/lib/routes/ChatRoute.js.map +1 -1
- package/dist/lib/routes/DocumentsRoute.js +1 -1
- package/dist/lib/routes/DocumentsRoute.js.map +1 -1
- package/dist/lib/routes/OAuthConsentRoute.js +1 -1
- package/dist/lib/routes/OAuthConsentRoute.js.map +1 -1
- package/dist/lib/routes/PricingRoute.js +1 -1
- package/dist/lib/routes/PricingRoute.js.map +1 -1
- package/dist/lib/routes/PrivacyRoute.js +1 -1
- package/dist/lib/routes/PrivacyRoute.js.map +1 -1
- package/dist/lib/routes/TeamSettingsRoute.js +1 -1
- package/dist/lib/routes/TeamSettingsRoute.js.map +1 -1
- package/dist/lib/routes/TermsRoute.js +1 -1
- package/dist/lib/routes/TermsRoute.js.map +1 -1
- package/dist/lib/routes/VerifyEmailRoute.js +1 -1
- package/dist/lib/routes/VerifyEmailRoute.js.map +1 -1
- package/dist/lib/routes.js +47 -37
- package/dist/lib/routes.js.map +1 -1
- package/dist/lib/ssr-utils.js +64 -1
- package/dist/lib/ssr-utils.js.map +1 -1
- package/dist/lib/ssr.js +23 -0
- package/dist/lib/ssr.js.map +1 -1
- package/dist/lib/styles.css +58 -62
- package/dist/lib/useExtensions-B5nX_8XD.js.map +1 -1
- package/package.json +25 -12
- package/src/components/MessageItem.tsx +35 -4
- package/src/components/MessageList.tsx +51 -5
- package/src/components/OAuthAppsSection.tsx +1 -1
- package/src/components/Sidebar.tsx +1 -3
- package/src/components/ToolCallDisplay.tsx +102 -11
- package/src/components/tool-renderers/DocumentListRenderer.tsx +44 -0
- package/src/components/tool-renderers/DocumentReadRenderer.tsx +33 -0
- package/src/components/tool-renderers/DocumentSaveRenderer.tsx +32 -0
- package/src/components/tool-renderers/DocumentSearchRenderer.tsx +33 -0
- package/src/components/tool-renderers/index.ts +36 -0
- package/src/components/tool-renderers/utils.ts +7 -0
- package/src/contexts/AuthContext.tsx +16 -6
- package/src/contexts/ConfigContext.tsx +60 -28
- package/src/contexts/ThemeContext.tsx +39 -68
- package/src/extensions/registry.ts +2 -1
- package/src/hooks/__tests__/basePath.test.ts +42 -0
- package/src/index.tsx +11 -2
- package/src/pages/AdminDashboardPage.tsx +15 -1
- package/src/pages/AdminPromoCodesPage.tsx +378 -0
- package/src/pages/AdminTeamPage.tsx +29 -1
- package/src/pages/AdminTeamsPage.tsx +15 -1
- package/src/pages/AdminUsersPage.tsx +15 -1
- package/src/pages/AdminWaitlistPage.tsx +156 -0
- package/src/pages/RegisterPage.tsx +91 -9
- package/src/routes/AcceptInviteRoute.tsx +1 -1
- package/src/routes/AdminDashboardRoute.tsx +1 -1
- package/src/routes/AdminPromoCodesRoute.tsx +24 -0
- package/src/routes/AdminTeamRoute.tsx +1 -1
- package/src/routes/AdminTeamsRoute.tsx +1 -1
- package/src/routes/AdminUsersRoute.tsx +1 -1
- package/src/routes/AdminWaitlistRoute.tsx +24 -0
- package/src/routes/ApiKeysRoute.tsx +1 -1
- package/src/routes/AutomationsRoute.tsx +1 -1
- package/src/routes/ChatRoute.tsx +2 -1
- package/src/routes/DocumentsRoute.tsx +1 -1
- package/src/routes/OAuthConsentRoute.tsx +1 -1
- package/src/routes/PricingRoute.tsx +1 -1
- package/src/routes/PrivacyRoute.tsx +1 -1
- package/src/routes/TeamSettingsRoute.tsx +1 -1
- package/src/routes/TermsRoute.tsx +1 -1
- package/src/routes/VerifyEmailRoute.tsx +1 -1
- package/src/routes/index.ts +2 -0
- package/src/ssr-utils.tsx +100 -1
- package/src/ssr.ts +59 -0
- package/src/stores/chatStore.ts +5 -0
- package/src/styles/index.css +16 -63
- package/src/tailwind-preset.js +360 -0
- package/dist/favicon.svg +0 -11
- package/dist/index.html +0 -17
- package/dist/logo.svg +0 -12
package/dist/lib/index.js
CHANGED
|
@@ -1,11 +1,129 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { c as clientRegistry, a as useSidebarPages, b as useExtensionTools } from "./useExtensions-B5nX_8XD.js";
|
|
2
3
|
import { C, a, S } from "./LoadingSkeletons-IcIC2JPq.js";
|
|
3
4
|
import React, { createContext, useState, useEffect, useContext, useCallback, useRef, forwardRef, createElement as createElement$1, useMemo, useImperativeHandle } from "react";
|
|
4
5
|
import { useSearchParams, useNavigate, Link as Link$1, useMatch, useParams, Navigate } from "react-router";
|
|
5
6
|
import { S as S2, b, u, a as a2, c } from "./ServerThemeProvider-DNF0LAyk.js";
|
|
6
|
-
import { a as useSidebarPages } from "./useExtensions-B5nX_8XD.js";
|
|
7
|
-
import { c as c2 } from "./useExtensions-B5nX_8XD.js";
|
|
8
7
|
import { createPortal } from "react-dom";
|
|
8
|
+
function getTextContent(content2) {
|
|
9
|
+
if (!content2) return null;
|
|
10
|
+
const firstText = content2.find((item) => item.type === "text" && typeof item.text === "string");
|
|
11
|
+
return (firstText == null ? void 0 : firstText.text) ?? null;
|
|
12
|
+
}
|
|
13
|
+
function DocumentListRenderer({ toolCall, toolResult }) {
|
|
14
|
+
const structured = toolResult.structuredContent;
|
|
15
|
+
const documents = (structured == null ? void 0 : structured.documents) ?? [];
|
|
16
|
+
const fallback = getTextContent(toolResult.content);
|
|
17
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
18
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-text-primary", children: "Documents" }),
|
|
19
|
+
documents.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "space-y-2", children: documents.map((doc, index2) => /* @__PURE__ */ jsxs("li", { className: "rounded-md border border-border bg-background px-3 py-2", children: [
|
|
20
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-text-primary", children: doc.path ?? doc.name ?? "Untitled document" }),
|
|
21
|
+
/* @__PURE__ */ jsxs("div", { className: "text-xs text-text-muted", children: [
|
|
22
|
+
doc.mimeType ?? "text/plain",
|
|
23
|
+
typeof doc.charCount === "number" ? ` • ${doc.charCount} chars` : "",
|
|
24
|
+
doc.teamId ? " • team" : "",
|
|
25
|
+
doc.projectId ? " • project" : ""
|
|
26
|
+
] })
|
|
27
|
+
] }, doc.id ?? doc.path ?? index2)) }) : /* @__PURE__ */ jsx("div", { className: "text-sm text-text-secondary", children: fallback ?? "No documents found." }),
|
|
28
|
+
/* @__PURE__ */ jsxs("div", { className: "text-xs text-text-muted", children: [
|
|
29
|
+
"Tool: ",
|
|
30
|
+
toolCall.toolName
|
|
31
|
+
] })
|
|
32
|
+
] });
|
|
33
|
+
}
|
|
34
|
+
function DocumentReadRenderer({ toolCall, toolResult }) {
|
|
35
|
+
const structured = toolResult.structuredContent;
|
|
36
|
+
const fallback = getTextContent(toolResult.content);
|
|
37
|
+
const rangeText = structured ? `Lines ${Number(structured.offset ?? 0) + 1}-${Number(structured.offset ?? 0) + Number(structured.linesReturned ?? 0)} of ${structured.totalLines ?? "unknown"}` : null;
|
|
38
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
39
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-text-primary", children: "Document Preview" }),
|
|
40
|
+
structured ? /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-text-secondary", children: [
|
|
41
|
+
/* @__PURE__ */ jsx("div", { className: "font-medium text-text-primary", children: structured.path ?? "Document" }),
|
|
42
|
+
rangeText && /* @__PURE__ */ jsxs("div", { className: "text-xs text-text-muted", children: [
|
|
43
|
+
rangeText,
|
|
44
|
+
structured.truncated ? " (truncated)" : ""
|
|
45
|
+
] })
|
|
46
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "text-sm text-text-secondary", children: fallback ?? "No structured document details." }),
|
|
47
|
+
/* @__PURE__ */ jsxs("div", { className: "text-xs text-text-muted", children: [
|
|
48
|
+
"Tool: ",
|
|
49
|
+
toolCall.toolName
|
|
50
|
+
] })
|
|
51
|
+
] });
|
|
52
|
+
}
|
|
53
|
+
function DocumentSearchRenderer({ toolCall, toolResult }) {
|
|
54
|
+
const structured = toolResult.structuredContent;
|
|
55
|
+
const fallback = getTextContent(toolResult.content);
|
|
56
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
57
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-text-primary", children: "Document Search" }),
|
|
58
|
+
structured ? /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-text-secondary", children: [
|
|
59
|
+
/* @__PURE__ */ jsx("div", { className: "font-medium text-text-primary", children: structured.path ?? "Document" }),
|
|
60
|
+
/* @__PURE__ */ jsxs("div", { className: "text-xs text-text-muted", children: [
|
|
61
|
+
"Query: ",
|
|
62
|
+
structured.query ?? "unknown"
|
|
63
|
+
] }),
|
|
64
|
+
/* @__PURE__ */ jsxs("div", { className: "text-xs text-text-muted", children: [
|
|
65
|
+
"Matches: ",
|
|
66
|
+
structured.matchCount ?? 0
|
|
67
|
+
] }),
|
|
68
|
+
structured.matchLines && structured.matchLines.length > 0 && /* @__PURE__ */ jsxs("div", { className: "text-xs text-text-muted", children: [
|
|
69
|
+
"Lines: ",
|
|
70
|
+
structured.matchLines.join(", ")
|
|
71
|
+
] })
|
|
72
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "text-sm text-text-secondary", children: fallback ?? "No structured search data." }),
|
|
73
|
+
/* @__PURE__ */ jsxs("div", { className: "text-xs text-text-muted", children: [
|
|
74
|
+
"Tool: ",
|
|
75
|
+
toolCall.toolName
|
|
76
|
+
] })
|
|
77
|
+
] });
|
|
78
|
+
}
|
|
79
|
+
function DocumentSaveRenderer({ toolCall, toolResult }) {
|
|
80
|
+
const structured = toolResult.structuredContent;
|
|
81
|
+
const fallback = getTextContent(toolResult.content);
|
|
82
|
+
const success = (structured == null ? void 0 : structured.success) !== false && !toolResult.isError;
|
|
83
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
84
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-text-primary", children: "Save Document" }),
|
|
85
|
+
structured ? /* @__PURE__ */ jsxs("div", { className: `rounded-md border px-3 py-2 text-sm ${success ? "border-success/30 bg-success/10 text-success" : "border-error/30 bg-error/10 text-error"}`, children: [
|
|
86
|
+
/* @__PURE__ */ jsx("div", { className: "font-medium", children: success ? "Saved" : "Failed" }),
|
|
87
|
+
structured.path && /* @__PURE__ */ jsxs("div", { className: "text-xs", children: [
|
|
88
|
+
"Path: ",
|
|
89
|
+
structured.path
|
|
90
|
+
] }),
|
|
91
|
+
structured.id && /* @__PURE__ */ jsxs("div", { className: "text-xs", children: [
|
|
92
|
+
"ID: ",
|
|
93
|
+
structured.id
|
|
94
|
+
] }),
|
|
95
|
+
typeof structured.charCount === "number" && /* @__PURE__ */ jsxs("div", { className: "text-xs", children: [
|
|
96
|
+
"Size: ",
|
|
97
|
+
structured.charCount,
|
|
98
|
+
" chars"
|
|
99
|
+
] })
|
|
100
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "text-sm text-text-secondary", children: fallback ?? "No structured save data." }),
|
|
101
|
+
/* @__PURE__ */ jsxs("div", { className: "text-xs text-text-muted", children: [
|
|
102
|
+
"Tool: ",
|
|
103
|
+
toolCall.toolName
|
|
104
|
+
] })
|
|
105
|
+
] });
|
|
106
|
+
}
|
|
107
|
+
clientRegistry.registerTool({
|
|
108
|
+
name: "list_documents",
|
|
109
|
+
description: "Render document list results",
|
|
110
|
+
resultRenderer: DocumentListRenderer
|
|
111
|
+
});
|
|
112
|
+
clientRegistry.registerTool({
|
|
113
|
+
name: "read_document",
|
|
114
|
+
description: "Render document read results",
|
|
115
|
+
resultRenderer: DocumentReadRenderer
|
|
116
|
+
});
|
|
117
|
+
clientRegistry.registerTool({
|
|
118
|
+
name: "search_in_document",
|
|
119
|
+
description: "Render document search results",
|
|
120
|
+
resultRenderer: DocumentSearchRenderer
|
|
121
|
+
});
|
|
122
|
+
clientRegistry.registerTool({
|
|
123
|
+
name: "save_document",
|
|
124
|
+
description: "Render document save results",
|
|
125
|
+
resultRenderer: DocumentSaveRenderer
|
|
126
|
+
});
|
|
9
127
|
class ApiError extends Error {
|
|
10
128
|
constructor(status, message, code2) {
|
|
11
129
|
super(message);
|
|
@@ -85,8 +203,8 @@ function AuthProvider({ children }) {
|
|
|
85
203
|
setUser(response.user);
|
|
86
204
|
return { requiresVerification: response.requiresVerification ?? false };
|
|
87
205
|
}
|
|
88
|
-
async function register2(email, password, name2) {
|
|
89
|
-
const response = await api.post("/api/auth/register", { email, password, name: name2 });
|
|
206
|
+
async function register2(email, password, name2, options) {
|
|
207
|
+
const response = await api.post("/api/auth/register", { email, password, name: name2, ...options });
|
|
90
208
|
setUser(response.user);
|
|
91
209
|
return { requiresVerification: response.requiresVerification ?? false };
|
|
92
210
|
}
|
|
@@ -94,8 +212,8 @@ function AuthProvider({ children }) {
|
|
|
94
212
|
await api.post("/api/auth/logout", {});
|
|
95
213
|
setUser(null);
|
|
96
214
|
}
|
|
97
|
-
async function sendMagicLink(email) {
|
|
98
|
-
await api.post("/api/auth/magic-link", { email });
|
|
215
|
+
async function sendMagicLink(email, inviteToken) {
|
|
216
|
+
await api.post("/api/auth/magic-link", { email, inviteToken });
|
|
99
217
|
}
|
|
100
218
|
async function verifyEmail(code2) {
|
|
101
219
|
await api.post(
|
|
@@ -132,11 +250,54 @@ function useAuth() {
|
|
|
132
250
|
}
|
|
133
251
|
return context;
|
|
134
252
|
}
|
|
253
|
+
const ThemeContext = createContext(void 0);
|
|
254
|
+
const DEFAULT_THEMES = ["light", "dark"];
|
|
255
|
+
const DEFAULT_THEME = "dark";
|
|
256
|
+
function ThemeProvider({
|
|
257
|
+
children,
|
|
258
|
+
availableThemes = DEFAULT_THEMES,
|
|
259
|
+
defaultTheme = DEFAULT_THEME
|
|
260
|
+
}) {
|
|
261
|
+
const [theme, setThemeState] = useState(() => {
|
|
262
|
+
if (typeof window !== "undefined") {
|
|
263
|
+
const stored = localStorage.getItem("theme");
|
|
264
|
+
if (stored && availableThemes.includes(stored)) {
|
|
265
|
+
return stored;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return defaultTheme;
|
|
269
|
+
});
|
|
270
|
+
useEffect(() => {
|
|
271
|
+
document.documentElement.setAttribute("data-theme", theme);
|
|
272
|
+
localStorage.setItem("theme", theme);
|
|
273
|
+
document.cookie = `theme=${theme};path=/;max-age=31536000;SameSite=Lax`;
|
|
274
|
+
}, [theme]);
|
|
275
|
+
function setTheme(newTheme) {
|
|
276
|
+
if (availableThemes.includes(newTheme)) {
|
|
277
|
+
setThemeState(newTheme);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: { theme, setTheme, availableThemes }, children });
|
|
281
|
+
}
|
|
282
|
+
function useTheme() {
|
|
283
|
+
const context = useContext(ThemeContext);
|
|
284
|
+
if (context === void 0) {
|
|
285
|
+
throw new Error("useTheme must be used within a ThemeProvider");
|
|
286
|
+
}
|
|
287
|
+
return context;
|
|
288
|
+
}
|
|
289
|
+
function getInjectedConfig() {
|
|
290
|
+
if (typeof window !== "undefined" && window.__CHAASKIT_CONFIG__) {
|
|
291
|
+
return window.__CHAASKIT_CONFIG__;
|
|
292
|
+
}
|
|
293
|
+
return void 0;
|
|
294
|
+
}
|
|
135
295
|
const defaultConfig = {
|
|
136
296
|
app: {
|
|
137
297
|
name: "AI Chat",
|
|
138
298
|
description: "Your AI assistant",
|
|
139
|
-
url: "http://localhost:5173"
|
|
299
|
+
url: "http://localhost:5173",
|
|
300
|
+
basePath: "/chat"
|
|
140
301
|
},
|
|
141
302
|
ui: {
|
|
142
303
|
welcomeTitle: "Welcome to AI Chat",
|
|
@@ -219,28 +380,16 @@ const defaultConfig = {
|
|
|
219
380
|
magicLink: {
|
|
220
381
|
enabled: true,
|
|
221
382
|
expiresInMinutes: 15
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
systemPrompt: "You are a helpful AI assistant.",
|
|
229
|
-
maxTokens: 4096
|
|
383
|
+
},
|
|
384
|
+
gating: {
|
|
385
|
+
mode: "open",
|
|
386
|
+
waitlistEnabled: false
|
|
387
|
+
},
|
|
388
|
+
isAdmin: false
|
|
230
389
|
},
|
|
231
390
|
payments: {
|
|
232
391
|
enabled: false,
|
|
233
|
-
provider: "stripe"
|
|
234
|
-
plans: [
|
|
235
|
-
{
|
|
236
|
-
id: "free",
|
|
237
|
-
name: "Free",
|
|
238
|
-
type: "free",
|
|
239
|
-
params: {
|
|
240
|
-
monthlyMessageLimit: 20
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
]
|
|
392
|
+
provider: "stripe"
|
|
244
393
|
},
|
|
245
394
|
legal: {
|
|
246
395
|
privacyPolicyUrl: "/privacy",
|
|
@@ -269,7 +418,6 @@ const defaultConfig = {
|
|
|
269
418
|
},
|
|
270
419
|
promptTemplates: {
|
|
271
420
|
enabled: true,
|
|
272
|
-
builtIn: [],
|
|
273
421
|
allowUserTemplates: true
|
|
274
422
|
},
|
|
275
423
|
teams: {
|
|
@@ -277,9 +425,6 @@ const defaultConfig = {
|
|
|
277
425
|
},
|
|
278
426
|
documents: {
|
|
279
427
|
enabled: false,
|
|
280
|
-
storage: {
|
|
281
|
-
provider: "database"
|
|
282
|
-
},
|
|
283
428
|
maxFileSizeMB: 10,
|
|
284
429
|
hybridThreshold: 1e3,
|
|
285
430
|
acceptedTypes: ["text/plain", "text/markdown", "application/json"]
|
|
@@ -290,16 +435,30 @@ const defaultConfig = {
|
|
|
290
435
|
},
|
|
291
436
|
api: {
|
|
292
437
|
enabled: false
|
|
438
|
+
},
|
|
439
|
+
credits: {
|
|
440
|
+
enabled: false,
|
|
441
|
+
expiryEnabled: false,
|
|
442
|
+
promoEnabled: false
|
|
443
|
+
},
|
|
444
|
+
metering: {
|
|
445
|
+
enabled: false,
|
|
446
|
+
recordPromptCompletion: true
|
|
293
447
|
}
|
|
294
448
|
};
|
|
295
449
|
const ConfigContext = createContext({
|
|
296
450
|
config: defaultConfig,
|
|
297
451
|
configLoaded: false
|
|
298
452
|
});
|
|
299
|
-
function ConfigProvider({ children }) {
|
|
300
|
-
const
|
|
301
|
-
const
|
|
453
|
+
function ConfigProvider({ children, initialConfig }) {
|
|
454
|
+
const injectedConfig = getInjectedConfig();
|
|
455
|
+
const preloadedConfig = initialConfig || injectedConfig;
|
|
456
|
+
const [config, setConfig] = useState(
|
|
457
|
+
preloadedConfig ? { ...defaultConfig, ...preloadedConfig } : defaultConfig
|
|
458
|
+
);
|
|
459
|
+
const [configLoaded, setConfigLoaded] = useState(!!preloadedConfig);
|
|
302
460
|
useEffect(() => {
|
|
461
|
+
if (preloadedConfig) return;
|
|
303
462
|
async function loadConfig() {
|
|
304
463
|
try {
|
|
305
464
|
const response = await fetch("/api/config");
|
|
@@ -317,7 +476,7 @@ function ConfigProvider({ children }) {
|
|
|
317
476
|
}
|
|
318
477
|
}
|
|
319
478
|
loadConfig();
|
|
320
|
-
}, []);
|
|
479
|
+
}, [preloadedConfig]);
|
|
321
480
|
return /* @__PURE__ */ jsx(ConfigContext.Provider, { value: { config, configLoaded }, children });
|
|
322
481
|
}
|
|
323
482
|
function useConfig() {
|
|
@@ -326,80 +485,6 @@ function useConfig() {
|
|
|
326
485
|
function useConfigLoaded() {
|
|
327
486
|
return useContext(ConfigContext).configLoaded;
|
|
328
487
|
}
|
|
329
|
-
const ThemeContext = createContext(void 0);
|
|
330
|
-
function ThemeProvider({ children }) {
|
|
331
|
-
const config = useConfig();
|
|
332
|
-
const [theme, setThemeState] = useState(() => {
|
|
333
|
-
const stored = localStorage.getItem("theme");
|
|
334
|
-
if (stored && config.theming.themes[stored]) {
|
|
335
|
-
return stored;
|
|
336
|
-
}
|
|
337
|
-
return config.theming.defaultTheme;
|
|
338
|
-
});
|
|
339
|
-
const availableThemes = Object.keys(config.theming.themes);
|
|
340
|
-
useEffect(() => {
|
|
341
|
-
document.documentElement.setAttribute("data-theme", theme);
|
|
342
|
-
localStorage.setItem("theme", theme);
|
|
343
|
-
document.cookie = `theme=${theme};path=/;max-age=31536000;SameSite=Lax`;
|
|
344
|
-
const themeConfig = config.theming.themes[theme];
|
|
345
|
-
if (themeConfig) {
|
|
346
|
-
const root2 = document.documentElement;
|
|
347
|
-
const colors = themeConfig.colors;
|
|
348
|
-
Object.entries(colors).forEach(([key, value]) => {
|
|
349
|
-
const cssKey = `--color-${key.replace(/([A-Z])/g, "-$1").toLowerCase()}`;
|
|
350
|
-
const rgb = hexToRgb(value);
|
|
351
|
-
if (rgb) {
|
|
352
|
-
root2.style.setProperty(cssKey, `${rgb.r} ${rgb.g} ${rgb.b}`);
|
|
353
|
-
}
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
document.documentElement.style.setProperty(
|
|
357
|
-
"--font-sans",
|
|
358
|
-
config.theming.fonts.sans
|
|
359
|
-
);
|
|
360
|
-
document.documentElement.style.setProperty(
|
|
361
|
-
"--font-mono",
|
|
362
|
-
config.theming.fonts.mono
|
|
363
|
-
);
|
|
364
|
-
document.documentElement.style.setProperty(
|
|
365
|
-
"--radius-sm",
|
|
366
|
-
config.theming.borderRadius.sm
|
|
367
|
-
);
|
|
368
|
-
document.documentElement.style.setProperty(
|
|
369
|
-
"--radius-md",
|
|
370
|
-
config.theming.borderRadius.md
|
|
371
|
-
);
|
|
372
|
-
document.documentElement.style.setProperty(
|
|
373
|
-
"--radius-lg",
|
|
374
|
-
config.theming.borderRadius.lg
|
|
375
|
-
);
|
|
376
|
-
document.documentElement.style.setProperty(
|
|
377
|
-
"--radius-full",
|
|
378
|
-
config.theming.borderRadius.full
|
|
379
|
-
);
|
|
380
|
-
}, [theme, config.theming]);
|
|
381
|
-
function setTheme(newTheme) {
|
|
382
|
-
if (config.theming.themes[newTheme]) {
|
|
383
|
-
setThemeState(newTheme);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: { theme, setTheme, availableThemes }, children });
|
|
387
|
-
}
|
|
388
|
-
function useTheme() {
|
|
389
|
-
const context = useContext(ThemeContext);
|
|
390
|
-
if (context === void 0) {
|
|
391
|
-
throw new Error("useTheme must be used within a ThemeProvider");
|
|
392
|
-
}
|
|
393
|
-
return context;
|
|
394
|
-
}
|
|
395
|
-
function hexToRgb(hex) {
|
|
396
|
-
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
397
|
-
return result ? {
|
|
398
|
-
r: parseInt(result[1], 16),
|
|
399
|
-
g: parseInt(result[2], 16),
|
|
400
|
-
b: parseInt(result[3], 16)
|
|
401
|
-
} : null;
|
|
402
|
-
}
|
|
403
488
|
const TeamContext = createContext(void 0);
|
|
404
489
|
function TeamProvider({ children }) {
|
|
405
490
|
var _a;
|
|
@@ -1328,7 +1413,8 @@ ${mentions}` : mentions;
|
|
|
1328
1413
|
...pendingCall,
|
|
1329
1414
|
result: data2.content || [],
|
|
1330
1415
|
isError: data2.isError,
|
|
1331
|
-
uiResource: data2.uiResource
|
|
1416
|
+
uiResource: data2.uiResource,
|
|
1417
|
+
structuredContent: data2.structuredContent
|
|
1332
1418
|
} : {
|
|
1333
1419
|
// Fallback: create from tool_result event data (server now includes name/serverId/input)
|
|
1334
1420
|
id: data2.id,
|
|
@@ -1337,7 +1423,8 @@ ${mentions}` : mentions;
|
|
|
1337
1423
|
input: data2.input || {},
|
|
1338
1424
|
result: data2.content || [],
|
|
1339
1425
|
isError: data2.isError,
|
|
1340
|
-
uiResource: data2.uiResource
|
|
1426
|
+
uiResource: data2.uiResource,
|
|
1427
|
+
structuredContent: data2.structuredContent
|
|
1341
1428
|
};
|
|
1342
1429
|
return {
|
|
1343
1430
|
pendingToolCalls: state2.pendingToolCalls.filter((tc) => tc.id !== data2.id),
|
|
@@ -1409,7 +1496,8 @@ ${mentions}` : mentions;
|
|
|
1409
1496
|
toolCallId: tc.id,
|
|
1410
1497
|
content: tc.result,
|
|
1411
1498
|
isError: tc.isError,
|
|
1412
|
-
uiResource: tc.uiResource
|
|
1499
|
+
uiResource: tc.uiResource,
|
|
1500
|
+
structuredContent: tc.structuredContent
|
|
1413
1501
|
})) : void 0,
|
|
1414
1502
|
createdAt: /* @__PURE__ */ new Date()
|
|
1415
1503
|
};
|
|
@@ -27180,12 +27268,12 @@ function MCPCredentialsSection({ onCredentialChange }) {
|
|
|
27180
27268
|
] });
|
|
27181
27269
|
}
|
|
27182
27270
|
function OAuthAppsSection() {
|
|
27183
|
-
var _a, _b
|
|
27271
|
+
var _a, _b;
|
|
27184
27272
|
const config = useConfig();
|
|
27185
27273
|
const [apps, setApps] = useState([]);
|
|
27186
27274
|
const [isLoading, setIsLoading] = useState(false);
|
|
27187
27275
|
const [revokingId, setRevokingId] = useState(null);
|
|
27188
|
-
const oauthEnabled = (
|
|
27276
|
+
const oauthEnabled = (_b = (_a = config.mcp) == null ? void 0 : _a.servers) == null ? void 0 : _b.some((server) => server.authMode === "user-oauth");
|
|
27189
27277
|
useEffect(() => {
|
|
27190
27278
|
if (oauthEnabled) {
|
|
27191
27279
|
loadApps();
|
|
@@ -28006,16 +28094,16 @@ function ProjectModal({ isOpen, onClose, project }) {
|
|
|
28006
28094
|
] }),
|
|
28007
28095
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
28008
28096
|
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-text-secondary mb-2", children: "Color" }),
|
|
28009
|
-
/* @__PURE__ */ jsx("div", { className: "flex gap-2 flex-wrap", children: projectColors.map((
|
|
28097
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-2 flex-wrap", children: projectColors.map((c2) => /* @__PURE__ */ jsx(
|
|
28010
28098
|
"button",
|
|
28011
28099
|
{
|
|
28012
28100
|
type: "button",
|
|
28013
|
-
onClick: () => canEdit && setColor(
|
|
28014
|
-
className: `w-8 h-8 rounded-full border-2 transition-all ${color2 ===
|
|
28015
|
-
style: { backgroundColor:
|
|
28101
|
+
onClick: () => canEdit && setColor(c2),
|
|
28102
|
+
className: `w-8 h-8 rounded-full border-2 transition-all ${color2 === c2 ? "border-text-primary scale-110" : "border-transparent hover:scale-105"} ${!canEdit ? "cursor-not-allowed opacity-50" : ""}`,
|
|
28103
|
+
style: { backgroundColor: c2 },
|
|
28016
28104
|
disabled: !canEdit
|
|
28017
28105
|
},
|
|
28018
|
-
|
|
28106
|
+
c2
|
|
28019
28107
|
)) })
|
|
28020
28108
|
] }),
|
|
28021
28109
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -28537,7 +28625,7 @@ function getIconComponent(iconName) {
|
|
|
28537
28625
|
return Icon || Puzzle;
|
|
28538
28626
|
}
|
|
28539
28627
|
function Sidebar({ onClose, onOpenSearch }) {
|
|
28540
|
-
var _a, _b, _c, _d, _e
|
|
28628
|
+
var _a, _b, _c, _d, _e;
|
|
28541
28629
|
const navigate = useNavigate();
|
|
28542
28630
|
const appPath = useAppPath();
|
|
28543
28631
|
const basePath = useBasePath();
|
|
@@ -28787,12 +28875,7 @@ function Sidebar({ onClose, onOpenSearch }) {
|
|
|
28787
28875
|
]
|
|
28788
28876
|
}
|
|
28789
28877
|
),
|
|
28790
|
-
((user == null ? void 0 : user.isAdmin) || ((
|
|
28791
|
-
(email) => {
|
|
28792
|
-
var _a2;
|
|
28793
|
-
return email.toLowerCase() === ((_a2 = user == null ? void 0 : user.email) == null ? void 0 : _a2.toLowerCase());
|
|
28794
|
-
}
|
|
28795
|
-
))) && /* @__PURE__ */ jsxs(
|
|
28878
|
+
((user == null ? void 0 : user.isAdmin) || ((_c = config.auth) == null ? void 0 : _c.isAdmin)) && /* @__PURE__ */ jsxs(
|
|
28796
28879
|
Link$1,
|
|
28797
28880
|
{
|
|
28798
28881
|
to: appPath("/admin"),
|
|
@@ -28818,7 +28901,7 @@ function Sidebar({ onClose, onOpenSearch }) {
|
|
|
28818
28901
|
page.id
|
|
28819
28902
|
);
|
|
28820
28903
|
}),
|
|
28821
|
-
((
|
|
28904
|
+
((_d = config.documents) == null ? void 0 : _d.enabled) && /* @__PURE__ */ jsxs(
|
|
28822
28905
|
Link$1,
|
|
28823
28906
|
{
|
|
28824
28907
|
to: appPath("/documents"),
|
|
@@ -28829,7 +28912,7 @@ function Sidebar({ onClose, onOpenSearch }) {
|
|
|
28829
28912
|
]
|
|
28830
28913
|
}
|
|
28831
28914
|
),
|
|
28832
|
-
((
|
|
28915
|
+
((_e = config.scheduledPrompts) == null ? void 0 : _e.enabled) && /* @__PURE__ */ jsxs(
|
|
28833
28916
|
Link$1,
|
|
28834
28917
|
{
|
|
28835
28918
|
to: appPath("/automations"),
|
|
@@ -30418,11 +30501,11 @@ function index$1(style2, options) {
|
|
|
30418
30501
|
match(WHITESPACE_REGEX);
|
|
30419
30502
|
}
|
|
30420
30503
|
function comments(rules) {
|
|
30421
|
-
var
|
|
30504
|
+
var c2;
|
|
30422
30505
|
rules = rules || [];
|
|
30423
|
-
while (
|
|
30424
|
-
if (
|
|
30425
|
-
rules.push(
|
|
30506
|
+
while (c2 = comment()) {
|
|
30507
|
+
if (c2 !== false) {
|
|
30508
|
+
rules.push(c2);
|
|
30426
30509
|
}
|
|
30427
30510
|
}
|
|
30428
30511
|
return rules;
|
|
@@ -46243,10 +46326,10 @@ var hasRequiredC;
|
|
|
46243
46326
|
function requireC() {
|
|
46244
46327
|
if (hasRequiredC) return c_1;
|
|
46245
46328
|
hasRequiredC = 1;
|
|
46246
|
-
c_1 =
|
|
46247
|
-
|
|
46248
|
-
|
|
46249
|
-
function
|
|
46329
|
+
c_1 = c2;
|
|
46330
|
+
c2.displayName = "c";
|
|
46331
|
+
c2.aliases = [];
|
|
46332
|
+
function c2(Prism2) {
|
|
46250
46333
|
Prism2.languages.c = Prism2.languages.extend("clike", {
|
|
46251
46334
|
comment: {
|
|
46252
46335
|
pattern: /\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,
|
|
@@ -58775,7 +58858,7 @@ function requireNaniscript() {
|
|
|
58775
58858
|
var tokens = env2.tokens;
|
|
58776
58859
|
tokens.forEach(function(token) {
|
|
58777
58860
|
if (typeof token !== "string" && token.type === "generic-text") {
|
|
58778
|
-
var content2 =
|
|
58861
|
+
var content2 = getTextContent2(token);
|
|
58779
58862
|
if (!isBracketsBalanced(content2)) {
|
|
58780
58863
|
token.type = "bad-line";
|
|
58781
58864
|
token.content = content2;
|
|
@@ -58799,13 +58882,13 @@ function requireNaniscript() {
|
|
|
58799
58882
|
}
|
|
58800
58883
|
return stack.length === 0;
|
|
58801
58884
|
}
|
|
58802
|
-
function
|
|
58885
|
+
function getTextContent2(token) {
|
|
58803
58886
|
if (typeof token === "string") {
|
|
58804
58887
|
return token;
|
|
58805
58888
|
} else if (Array.isArray(token)) {
|
|
58806
|
-
return token.map(
|
|
58889
|
+
return token.map(getTextContent2).join("");
|
|
58807
58890
|
} else {
|
|
58808
|
-
return
|
|
58891
|
+
return getTextContent2(token.content);
|
|
58809
58892
|
}
|
|
58810
58893
|
}
|
|
58811
58894
|
})(Prism2);
|
|
@@ -67976,6 +68059,7 @@ const AUTO_APPROVE_LABELS = {
|
|
|
67976
68059
|
user_always: "You always allowed this tool",
|
|
67977
68060
|
thread_allowed: "Allowed for this chat"
|
|
67978
68061
|
};
|
|
68062
|
+
const TOOL_UI_MESSAGE_SOURCE = "chaaskit-tool-ui";
|
|
67979
68063
|
function generateOpenAiScript(toolInput, toolOutput, theme) {
|
|
67980
68064
|
const openAiTheme = theme === "dark" ? "dark" : "light";
|
|
67981
68065
|
const backgroundColor = theme === "dark" ? "#111827" : "#ffffff";
|
|
@@ -68018,6 +68102,46 @@ function generateOpenAiScript(toolInput, toolOutput, theme) {
|
|
|
68018
68102
|
</style>
|
|
68019
68103
|
<script>
|
|
68020
68104
|
(function() {
|
|
68105
|
+
const MESSAGE_SOURCE = '${TOOL_UI_MESSAGE_SOURCE}';
|
|
68106
|
+
let requestId = 0;
|
|
68107
|
+
const pending = new Map();
|
|
68108
|
+
|
|
68109
|
+
function resolvePending(id, data) {
|
|
68110
|
+
const entry = pending.get(id);
|
|
68111
|
+
if (!entry) return;
|
|
68112
|
+
pending.delete(id);
|
|
68113
|
+
if (data && data.ok) {
|
|
68114
|
+
entry.resolve(data.result);
|
|
68115
|
+
return;
|
|
68116
|
+
}
|
|
68117
|
+
entry.resolve({ error: (data && data.error) || 'Tool UI bridge error' });
|
|
68118
|
+
}
|
|
68119
|
+
|
|
68120
|
+
window.addEventListener('message', (event) => {
|
|
68121
|
+
const data = event.data || {};
|
|
68122
|
+
if (data.source !== MESSAGE_SOURCE || !data.id) return;
|
|
68123
|
+
resolvePending(data.id, data);
|
|
68124
|
+
});
|
|
68125
|
+
|
|
68126
|
+
function sendToParent(type, payload, timeoutMs = 15000) {
|
|
68127
|
+
return new Promise((resolve) => {
|
|
68128
|
+
const id = String(Date.now()) + '-' + String(requestId++);
|
|
68129
|
+
pending.set(id, { resolve });
|
|
68130
|
+
try {
|
|
68131
|
+
window.parent.postMessage({ source: MESSAGE_SOURCE, type, id, payload }, '*');
|
|
68132
|
+
} catch (err) {
|
|
68133
|
+
pending.delete(id);
|
|
68134
|
+
resolve({ error: 'Unable to reach host window' });
|
|
68135
|
+
return;
|
|
68136
|
+
}
|
|
68137
|
+
setTimeout(() => {
|
|
68138
|
+
if (!pending.has(id)) return;
|
|
68139
|
+
pending.delete(id);
|
|
68140
|
+
resolve({ error: 'Tool UI request timed out' });
|
|
68141
|
+
}, timeoutMs);
|
|
68142
|
+
});
|
|
68143
|
+
}
|
|
68144
|
+
|
|
68021
68145
|
// Initialize window.openai with the OpenAI Apps SDK spec
|
|
68022
68146
|
window.openai = {
|
|
68023
68147
|
// Core globals
|
|
@@ -68042,17 +68166,20 @@ function generateOpenAiScript(toolInput, toolOutput, theme) {
|
|
|
68042
68166
|
// API methods
|
|
68043
68167
|
callTool: async (name, args) => {
|
|
68044
68168
|
console.log('window.openai.callTool called:', { name, args });
|
|
68045
|
-
|
|
68046
|
-
|
|
68047
|
-
|
|
68048
|
-
|
|
68049
|
-
|
|
68169
|
+
const response = await sendToParent('callTool', { name, args });
|
|
68170
|
+
if (response && response.error) {
|
|
68171
|
+
return {
|
|
68172
|
+
content: [{ type: 'text', text: response.error }],
|
|
68173
|
+
isError: true
|
|
68174
|
+
};
|
|
68175
|
+
}
|
|
68176
|
+
return response || { content: [{ type: 'text', text: 'No response from host' }], isError: true };
|
|
68050
68177
|
},
|
|
68051
68178
|
|
|
68052
68179
|
sendFollowUpMessage: async (args) => {
|
|
68053
68180
|
console.log('window.openai.sendFollowUpMessage called:', args);
|
|
68054
|
-
|
|
68055
|
-
return {};
|
|
68181
|
+
const response = await sendToParent('sendFollowUpMessage', args);
|
|
68182
|
+
return response && response.error ? { error: response.error } : (response || {});
|
|
68056
68183
|
},
|
|
68057
68184
|
|
|
68058
68185
|
openExternal: (payload) => {
|
|
@@ -68064,27 +68191,41 @@ function generateOpenAiScript(toolInput, toolOutput, theme) {
|
|
|
68064
68191
|
|
|
68065
68192
|
requestDisplayMode: async (args) => {
|
|
68066
68193
|
console.log('window.openai.requestDisplayMode called:', args);
|
|
68067
|
-
|
|
68194
|
+
const response = await sendToParent('requestDisplayMode', args);
|
|
68195
|
+
if (response && response.error) {
|
|
68196
|
+
return { mode: args.mode };
|
|
68197
|
+
}
|
|
68198
|
+
return response || { mode: args.mode };
|
|
68068
68199
|
},
|
|
68069
68200
|
|
|
68070
68201
|
setWidgetState: async (state) => {
|
|
68071
68202
|
console.log('window.openai.setWidgetState called:', state);
|
|
68072
68203
|
window.openai.widgetState = state;
|
|
68073
|
-
|
|
68204
|
+
const response = await sendToParent('setWidgetState', state);
|
|
68205
|
+
return response && response.error ? {} : (response || {});
|
|
68074
68206
|
},
|
|
68075
68207
|
|
|
68076
68208
|
requestClose: () => {
|
|
68077
68209
|
console.log('window.openai.requestClose called');
|
|
68210
|
+
sendToParent('requestClose', {});
|
|
68078
68211
|
},
|
|
68079
68212
|
|
|
68080
68213
|
getFileDownloadUrl: async ({ fileId }) => {
|
|
68081
68214
|
console.log('window.openai.getFileDownloadUrl called:', fileId);
|
|
68082
|
-
|
|
68215
|
+
const response = await sendToParent('getFileDownloadUrl', { fileId });
|
|
68216
|
+
if (response && response.error) {
|
|
68217
|
+
return { url: '' };
|
|
68218
|
+
}
|
|
68219
|
+
return response || { url: '' };
|
|
68083
68220
|
},
|
|
68084
68221
|
|
|
68085
68222
|
uploadFile: async (file) => {
|
|
68086
68223
|
console.log('window.openai.uploadFile called:', file);
|
|
68087
|
-
|
|
68224
|
+
const response = await sendToParent('uploadFile', { file });
|
|
68225
|
+
if (response && response.error) {
|
|
68226
|
+
return { fileId: '' };
|
|
68227
|
+
}
|
|
68228
|
+
return response || { fileId: '' };
|
|
68088
68229
|
}
|
|
68089
68230
|
};
|
|
68090
68231
|
|
|
@@ -68136,6 +68277,31 @@ function UIResourceWidget({ uiResource, theme }) {
|
|
|
68136
68277
|
}
|
|
68137
68278
|
function ToolCallDisplay({ toolCall, toolResult, isPending, uiResource, hideUiResource, autoApproveReason }) {
|
|
68138
68279
|
var _a;
|
|
68280
|
+
useEffect(() => {
|
|
68281
|
+
async function handleMessage(event) {
|
|
68282
|
+
const data2 = event.data || {};
|
|
68283
|
+
if (data2.source !== TOOL_UI_MESSAGE_SOURCE || !data2.id) return;
|
|
68284
|
+
const targetOrigin = event.origin && event.origin !== "null" ? event.origin : "*";
|
|
68285
|
+
try {
|
|
68286
|
+
const handler = window.chaaskitToolUiHandler;
|
|
68287
|
+
const result = typeof handler === "function" ? await handler({ type: data2.type, payload: data2.payload }) : { error: "Tool UI bridge not configured" };
|
|
68288
|
+
const sourceWindow = event.source;
|
|
68289
|
+
sourceWindow == null ? void 0 : sourceWindow.postMessage(
|
|
68290
|
+
{ source: TOOL_UI_MESSAGE_SOURCE, id: data2.id, ok: true, result },
|
|
68291
|
+
targetOrigin
|
|
68292
|
+
);
|
|
68293
|
+
} catch (err) {
|
|
68294
|
+
const message = err instanceof Error ? err.message : "Tool UI bridge error";
|
|
68295
|
+
const sourceWindow = event.source;
|
|
68296
|
+
sourceWindow == null ? void 0 : sourceWindow.postMessage(
|
|
68297
|
+
{ source: TOOL_UI_MESSAGE_SOURCE, id: data2.id, ok: false, error: message },
|
|
68298
|
+
targetOrigin
|
|
68299
|
+
);
|
|
68300
|
+
}
|
|
68301
|
+
}
|
|
68302
|
+
window.addEventListener("message", handleMessage);
|
|
68303
|
+
return () => window.removeEventListener("message", handleMessage);
|
|
68304
|
+
}, []);
|
|
68139
68305
|
const hasHtmlResource = !hideUiResource && (uiResource == null ? void 0 : uiResource.text) && (((_a = uiResource.mimeType) == null ? void 0 : _a.includes("html")) || uiResource.text.trim().startsWith("<"));
|
|
68140
68306
|
const [isExpanded, setIsExpanded] = useState(hasHtmlResource);
|
|
68141
68307
|
const [showRawResult, setShowRawResult] = useState(false);
|
|
@@ -68469,6 +68635,12 @@ function MessageItem({ message, isStreaming, messageIndex = 0, previousMessage }
|
|
|
68469
68635
|
const config = useConfig();
|
|
68470
68636
|
const navigate = useNavigate();
|
|
68471
68637
|
const appPath = useAppPath();
|
|
68638
|
+
const extensionTools = useExtensionTools();
|
|
68639
|
+
const toolRendererMap = useMemo(() => {
|
|
68640
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
68641
|
+
extensionTools.forEach((tool) => map2.set(tool.name, tool));
|
|
68642
|
+
return map2;
|
|
68643
|
+
}, [extensionTools]);
|
|
68472
68644
|
const isUser = message.role === "user";
|
|
68473
68645
|
const showToolCalls = ((_a = config.mcp) == null ? void 0 : _a.showToolCalls) !== false;
|
|
68474
68646
|
const canBranch = messageIndex > 0;
|
|
@@ -68515,9 +68687,19 @@ function MessageItem({ message, isStreaming, messageIndex = 0, previousMessage }
|
|
|
68515
68687
|
toolResult: (_a2 = message.toolResults) == null ? void 0 : _a2.find((r) => r.toolCallId === toolCall.id)
|
|
68516
68688
|
};
|
|
68517
68689
|
})) || [];
|
|
68690
|
+
const renderedToolCalls = toolCallsWithResults.filter(
|
|
68691
|
+
({ toolCall, toolResult }) => {
|
|
68692
|
+
var _a2;
|
|
68693
|
+
return toolCall.serverId === "native" && !!toolResult && !!((_a2 = toolRendererMap.get(toolCall.toolName)) == null ? void 0 : _a2.resultRenderer);
|
|
68694
|
+
}
|
|
68695
|
+
).map(({ toolCall, toolResult }) => {
|
|
68696
|
+
const renderer = toolRendererMap.get(toolCall.toolName).resultRenderer;
|
|
68697
|
+
return { toolCall, toolResult, Renderer: renderer };
|
|
68698
|
+
});
|
|
68699
|
+
const renderedToolCallIds = new Set(renderedToolCalls.map((entry) => entry.toolCall.id));
|
|
68518
68700
|
const uiResources = toolCallsWithResults.filter((tc) => {
|
|
68519
68701
|
var _a2, _b2;
|
|
68520
|
-
return (_b2 = (_a2 = tc.toolResult) == null ? void 0 : _a2.uiResource) == null ? void 0 : _b2.text;
|
|
68702
|
+
return ((_b2 = (_a2 = tc.toolResult) == null ? void 0 : _a2.uiResource) == null ? void 0 : _b2.text) && !renderedToolCallIds.has(tc.toolCall.id);
|
|
68521
68703
|
}).map((tc) => tc.toolResult.uiResource);
|
|
68522
68704
|
if (!isUser && ((_c = message.toolCalls) == null ? void 0 : _c.length)) {
|
|
68523
68705
|
console.log("[MessageItem] Rendering message with toolCalls:", message.toolCalls.length);
|
|
@@ -68588,6 +68770,7 @@ function MessageItem({ message, isStreaming, messageIndex = 0, previousMessage }
|
|
|
68588
68770
|
},
|
|
68589
68771
|
toolCall.id
|
|
68590
68772
|
)) }),
|
|
68773
|
+
renderedToolCalls.length > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-3", children: renderedToolCalls.map(({ toolCall, toolResult, Renderer }) => /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-border bg-background-secondary/40 p-3", children: /* @__PURE__ */ jsx(Renderer, { toolCall, toolResult }) }, toolCall.id)) }),
|
|
68591
68774
|
uiResources.length > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-3", children: uiResources.map((uiResource, index2) => /* @__PURE__ */ jsx(UIResourceWidget, { uiResource, theme }, index2)) }),
|
|
68592
68775
|
(message.content || isStreaming) && /* @__PURE__ */ jsxs("div", { className: "group flex gap-3", children: [
|
|
68593
68776
|
/* @__PURE__ */ jsx("div", { className: "flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-secondary overflow-hidden", children: ((_f = config.ui) == null ? void 0 : _f.logo) ? /* @__PURE__ */ jsx("img", { src: typeof config.ui.logo === "string" ? config.ui.logo : theme === "dark" ? config.ui.logo.dark : config.ui.logo.light, alt: "", className: "h-full w-full object-cover" }) : /* @__PURE__ */ jsx(Bot, { size: 12, className: "text-white" }) }),
|
|
@@ -68678,6 +68861,12 @@ function MessageList({
|
|
|
68678
68861
|
const bottomRef = useRef(null);
|
|
68679
68862
|
const { theme } = useTheme();
|
|
68680
68863
|
const config = useConfig();
|
|
68864
|
+
const extensionTools = useExtensionTools();
|
|
68865
|
+
const toolRendererMap = useMemo(() => {
|
|
68866
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
68867
|
+
extensionTools.forEach((tool) => map2.set(tool.name, tool));
|
|
68868
|
+
return map2;
|
|
68869
|
+
}, [extensionTools]);
|
|
68681
68870
|
const showToolCalls = ((_a = config.mcp) == null ? void 0 : _a.showToolCalls) !== false;
|
|
68682
68871
|
useEffect(() => {
|
|
68683
68872
|
var _a2;
|
|
@@ -68685,9 +68874,33 @@ function MessageList({
|
|
|
68685
68874
|
}, [messages2, streamingContent, pendingToolCalls, completedToolCalls]);
|
|
68686
68875
|
const hasToolActivity = pendingToolCalls.length > 0 || completedToolCalls.length > 0;
|
|
68687
68876
|
const isStreaming = Boolean(streamingContent) || hasToolActivity;
|
|
68877
|
+
const renderedToolCalls = completedToolCalls.filter(
|
|
68878
|
+
(call) => {
|
|
68879
|
+
var _a2;
|
|
68880
|
+
return call.serverId === "native" && !!((_a2 = toolRendererMap.get(call.name)) == null ? void 0 : _a2.resultRenderer);
|
|
68881
|
+
}
|
|
68882
|
+
).map((call) => {
|
|
68883
|
+
const renderer = toolRendererMap.get(call.name).resultRenderer;
|
|
68884
|
+
const toolCall = {
|
|
68885
|
+
id: call.id,
|
|
68886
|
+
serverId: call.serverId,
|
|
68887
|
+
toolName: call.name,
|
|
68888
|
+
arguments: call.input,
|
|
68889
|
+
status: call.isError ? "error" : "completed"
|
|
68890
|
+
};
|
|
68891
|
+
const toolResult = {
|
|
68892
|
+
toolCallId: call.id,
|
|
68893
|
+
content: call.result,
|
|
68894
|
+
isError: call.isError,
|
|
68895
|
+
uiResource: call.uiResource,
|
|
68896
|
+
structuredContent: call.structuredContent
|
|
68897
|
+
};
|
|
68898
|
+
return { toolCall, toolResult, Renderer: renderer };
|
|
68899
|
+
});
|
|
68900
|
+
const renderedToolCallIds = new Set(renderedToolCalls.map((entry) => entry.toolCall.id));
|
|
68688
68901
|
const uiResources = completedToolCalls.filter((tc) => {
|
|
68689
68902
|
var _a2;
|
|
68690
|
-
return (_a2 = tc.uiResource) == null ? void 0 : _a2.text;
|
|
68903
|
+
return ((_a2 = tc.uiResource) == null ? void 0 : _a2.text) && !renderedToolCallIds.has(tc.id);
|
|
68691
68904
|
}).map((tc) => tc.uiResource);
|
|
68692
68905
|
console.log("[MessageList] Rendering messages:", messages2.length, "isStreaming:", isStreaming);
|
|
68693
68906
|
messages2.forEach((msg, i) => {
|
|
@@ -68734,7 +68947,8 @@ function MessageList({
|
|
|
68734
68947
|
toolResult: {
|
|
68735
68948
|
toolCallId: call.id,
|
|
68736
68949
|
content: call.result,
|
|
68737
|
-
isError: call.isError
|
|
68950
|
+
isError: call.isError,
|
|
68951
|
+
structuredContent: call.structuredContent
|
|
68738
68952
|
},
|
|
68739
68953
|
hideUiResource: true
|
|
68740
68954
|
},
|
|
@@ -68755,6 +68969,7 @@ function MessageList({
|
|
|
68755
68969
|
call.id
|
|
68756
68970
|
))
|
|
68757
68971
|
] }),
|
|
68972
|
+
renderedToolCalls.length > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-3", children: renderedToolCalls.map(({ toolCall, toolResult, Renderer }) => /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-border bg-background-secondary/40 p-3", children: /* @__PURE__ */ jsx(Renderer, { toolCall, toolResult }) }, toolCall.id)) }),
|
|
68758
68973
|
uiResources.length > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-3", children: uiResources.map((uiResource, index2) => /* @__PURE__ */ jsx(UIResourceWidget, { uiResource, theme }, index2)) }),
|
|
68759
68974
|
streamingContent && /* @__PURE__ */ jsxs("div", { className: "group flex gap-3", children: [
|
|
68760
68975
|
/* @__PURE__ */ jsx("div", { className: "flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-secondary", children: /* @__PURE__ */ jsx(Bot, { size: 12, className: "text-white" }) }),
|
|
@@ -69790,11 +70005,20 @@ function RegisterPage() {
|
|
|
69790
70005
|
const { register: register2 } = useAuth();
|
|
69791
70006
|
const config = useConfig();
|
|
69792
70007
|
const { theme } = useTheme();
|
|
70008
|
+
const [searchParams] = useSearchParams();
|
|
70009
|
+
const inviteToken = searchParams.get("invite") || void 0;
|
|
70010
|
+
const referralCode = searchParams.get("ref") || void 0;
|
|
70011
|
+
const gating = config.auth.gating;
|
|
70012
|
+
const signupsRestricted = (gating == null ? void 0 : gating.mode) && gating.mode !== "open" && !inviteToken;
|
|
70013
|
+
const waitlistEnabled = (gating == null ? void 0 : gating.waitlistEnabled) ?? false;
|
|
70014
|
+
const showWaitlist = !!signupsRestricted && waitlistEnabled;
|
|
70015
|
+
const showRestrictedMessage = !!signupsRestricted && !waitlistEnabled;
|
|
69793
70016
|
const [name2, setName] = useState("");
|
|
69794
70017
|
const [email, setEmail] = useState("");
|
|
69795
70018
|
const [password, setPassword] = useState("");
|
|
69796
70019
|
const [error, setError] = useState("");
|
|
69797
70020
|
const [isLoading, setIsLoading] = useState(false);
|
|
70021
|
+
const [waitlistStatus, setWaitlistStatus] = useState("idle");
|
|
69798
70022
|
async function handleSubmit(e) {
|
|
69799
70023
|
e.preventDefault();
|
|
69800
70024
|
setError("");
|
|
@@ -69804,7 +70028,10 @@ function RegisterPage() {
|
|
|
69804
70028
|
}
|
|
69805
70029
|
setIsLoading(true);
|
|
69806
70030
|
try {
|
|
69807
|
-
const { requiresVerification } = await register2(email, password, name2 || void 0
|
|
70031
|
+
const { requiresVerification } = await register2(email, password, name2 || void 0, {
|
|
70032
|
+
inviteToken,
|
|
70033
|
+
referralCode
|
|
70034
|
+
});
|
|
69808
70035
|
if (requiresVerification) {
|
|
69809
70036
|
navigate("/verify-email");
|
|
69810
70037
|
} else {
|
|
@@ -69816,6 +70043,16 @@ function RegisterPage() {
|
|
|
69816
70043
|
setIsLoading(false);
|
|
69817
70044
|
}
|
|
69818
70045
|
}
|
|
70046
|
+
async function handleWaitlistSubmit(e) {
|
|
70047
|
+
e.preventDefault();
|
|
70048
|
+
setError("");
|
|
70049
|
+
try {
|
|
70050
|
+
await api.post("/api/auth/waitlist", { email, name: name2 || void 0 });
|
|
70051
|
+
setWaitlistStatus("submitted");
|
|
70052
|
+
} catch (err) {
|
|
70053
|
+
setError(err instanceof Error ? err.message : "Failed to join waitlist");
|
|
70054
|
+
}
|
|
70055
|
+
}
|
|
69819
70056
|
return /* @__PURE__ */ jsx("div", { className: "flex min-h-screen items-center justify-center bg-background p-4", children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-md", children: [
|
|
69820
70057
|
/* @__PURE__ */ jsxs("div", { className: "mb-8 text-center", children: [
|
|
69821
70058
|
config.ui.logo && /* @__PURE__ */ jsx(
|
|
@@ -69833,7 +70070,46 @@ function RegisterPage() {
|
|
|
69833
70070
|
] })
|
|
69834
70071
|
] }),
|
|
69835
70072
|
error && /* @__PURE__ */ jsx("div", { className: "mb-4 rounded-lg bg-error/10 p-3 text-sm text-error", children: error }),
|
|
69836
|
-
/* @__PURE__ */
|
|
70073
|
+
showRestrictedMessage ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-border bg-background-secondary p-4 text-sm text-text-secondary", children: "Signups are currently closed. Please check back later." }) : showWaitlist ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-border bg-background-secondary p-4", children: [
|
|
70074
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary", children: "Signups are currently restricted. Join the waitlist to get an invite." }),
|
|
70075
|
+
waitlistStatus === "submitted" ? /* @__PURE__ */ jsx("div", { className: "mt-4 rounded-lg bg-success/10 p-3 text-sm text-success", children: "Thanks! You’re on the waitlist." }) : /* @__PURE__ */ jsxs("form", { onSubmit: handleWaitlistSubmit, className: "mt-4 space-y-3", children: [
|
|
70076
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
70077
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "waitlist-name", className: "block text-sm font-medium text-text-primary", children: "Name (optional)" }),
|
|
70078
|
+
/* @__PURE__ */ jsx(
|
|
70079
|
+
"input",
|
|
70080
|
+
{
|
|
70081
|
+
type: "text",
|
|
70082
|
+
id: "waitlist-name",
|
|
70083
|
+
value: name2,
|
|
70084
|
+
onChange: (e) => setName(e.target.value),
|
|
70085
|
+
className: "mt-1 w-full rounded-lg border border-input-border bg-input-background px-4 py-2 text-text-primary focus:border-primary focus:outline-none"
|
|
70086
|
+
}
|
|
70087
|
+
)
|
|
70088
|
+
] }),
|
|
70089
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
70090
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "waitlist-email", className: "block text-sm font-medium text-text-primary", children: "Email" }),
|
|
70091
|
+
/* @__PURE__ */ jsx(
|
|
70092
|
+
"input",
|
|
70093
|
+
{
|
|
70094
|
+
type: "email",
|
|
70095
|
+
id: "waitlist-email",
|
|
70096
|
+
value: email,
|
|
70097
|
+
onChange: (e) => setEmail(e.target.value),
|
|
70098
|
+
required: true,
|
|
70099
|
+
className: "mt-1 w-full rounded-lg border border-input-border bg-input-background px-4 py-2 text-text-primary focus:border-primary focus:outline-none"
|
|
70100
|
+
}
|
|
70101
|
+
)
|
|
70102
|
+
] }),
|
|
70103
|
+
/* @__PURE__ */ jsx(
|
|
70104
|
+
"button",
|
|
70105
|
+
{
|
|
70106
|
+
type: "submit",
|
|
70107
|
+
className: "w-full rounded-lg bg-primary px-4 py-2 font-medium text-white hover:bg-primary-hover",
|
|
70108
|
+
children: "Join waitlist"
|
|
70109
|
+
}
|
|
70110
|
+
)
|
|
70111
|
+
] })
|
|
70112
|
+
] }) : /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
|
|
69837
70113
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
69838
70114
|
/* @__PURE__ */ jsx(
|
|
69839
70115
|
"label",
|
|
@@ -69908,7 +70184,7 @@ function RegisterPage() {
|
|
|
69908
70184
|
}
|
|
69909
70185
|
)
|
|
69910
70186
|
] }),
|
|
69911
|
-
/* @__PURE__ */ jsxs("p", { className: "mt-6 text-center text-sm text-text-secondary", children: [
|
|
70187
|
+
!signupsRestricted && /* @__PURE__ */ jsxs("p", { className: "mt-6 text-center text-sm text-text-secondary", children: [
|
|
69912
70188
|
"Already have an account?",
|
|
69913
70189
|
" ",
|
|
69914
70190
|
/* @__PURE__ */ jsx(Link$1, { to: "/login", className: "text-primary hover:underline", children: "Sign in" })
|
|
@@ -73180,6 +73456,28 @@ function AdminDashboardPage() {
|
|
|
73180
73456
|
"Teams"
|
|
73181
73457
|
]
|
|
73182
73458
|
}
|
|
73459
|
+
),
|
|
73460
|
+
/* @__PURE__ */ jsxs(
|
|
73461
|
+
Link$1,
|
|
73462
|
+
{
|
|
73463
|
+
to: appPath("/admin/waitlist"),
|
|
73464
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
73465
|
+
children: [
|
|
73466
|
+
/* @__PURE__ */ jsx(Mail, { size: 16 }),
|
|
73467
|
+
"Waitlist"
|
|
73468
|
+
]
|
|
73469
|
+
}
|
|
73470
|
+
),
|
|
73471
|
+
/* @__PURE__ */ jsxs(
|
|
73472
|
+
Link$1,
|
|
73473
|
+
{
|
|
73474
|
+
to: appPath("/admin/promo-codes"),
|
|
73475
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
73476
|
+
children: [
|
|
73477
|
+
/* @__PURE__ */ jsx(Tag, { size: 16 }),
|
|
73478
|
+
"Promo Codes"
|
|
73479
|
+
]
|
|
73480
|
+
}
|
|
73183
73481
|
)
|
|
73184
73482
|
] }),
|
|
73185
73483
|
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-8", children: [
|
|
@@ -73454,6 +73752,28 @@ function AdminUsersPage() {
|
|
|
73454
73752
|
"Teams"
|
|
73455
73753
|
]
|
|
73456
73754
|
}
|
|
73755
|
+
),
|
|
73756
|
+
/* @__PURE__ */ jsxs(
|
|
73757
|
+
Link$1,
|
|
73758
|
+
{
|
|
73759
|
+
to: appPath("/admin/waitlist"),
|
|
73760
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
73761
|
+
children: [
|
|
73762
|
+
/* @__PURE__ */ jsx(Mail, { size: 16 }),
|
|
73763
|
+
"Waitlist"
|
|
73764
|
+
]
|
|
73765
|
+
}
|
|
73766
|
+
),
|
|
73767
|
+
/* @__PURE__ */ jsxs(
|
|
73768
|
+
Link$1,
|
|
73769
|
+
{
|
|
73770
|
+
to: appPath("/admin/promo-codes"),
|
|
73771
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
73772
|
+
children: [
|
|
73773
|
+
/* @__PURE__ */ jsx(Tag, { size: 16 }),
|
|
73774
|
+
"Promo Codes"
|
|
73775
|
+
]
|
|
73776
|
+
}
|
|
73457
73777
|
)
|
|
73458
73778
|
] }),
|
|
73459
73779
|
error && /* @__PURE__ */ jsx("div", { className: "mb-6 rounded-lg bg-error/10 p-4 text-sm text-error", children: error }),
|
|
@@ -73736,6 +74056,28 @@ function AdminTeamsPage() {
|
|
|
73736
74056
|
"Teams"
|
|
73737
74057
|
]
|
|
73738
74058
|
}
|
|
74059
|
+
),
|
|
74060
|
+
/* @__PURE__ */ jsxs(
|
|
74061
|
+
Link$1,
|
|
74062
|
+
{
|
|
74063
|
+
to: appPath("/admin/waitlist"),
|
|
74064
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
74065
|
+
children: [
|
|
74066
|
+
/* @__PURE__ */ jsx(Mail, { size: 16 }),
|
|
74067
|
+
"Waitlist"
|
|
74068
|
+
]
|
|
74069
|
+
}
|
|
74070
|
+
),
|
|
74071
|
+
/* @__PURE__ */ jsxs(
|
|
74072
|
+
Link$1,
|
|
74073
|
+
{
|
|
74074
|
+
to: appPath("/admin/promo-codes"),
|
|
74075
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
74076
|
+
children: [
|
|
74077
|
+
/* @__PURE__ */ jsx(Tag, { size: 16 }),
|
|
74078
|
+
"Promo Codes"
|
|
74079
|
+
]
|
|
74080
|
+
}
|
|
73739
74081
|
)
|
|
73740
74082
|
] }),
|
|
73741
74083
|
error && /* @__PURE__ */ jsx("div", { className: "mb-6 rounded-lg bg-error/10 p-4 text-sm text-error", children: error }),
|
|
@@ -73911,6 +74253,28 @@ function AdminTeamPage() {
|
|
|
73911
74253
|
"Teams"
|
|
73912
74254
|
]
|
|
73913
74255
|
}
|
|
74256
|
+
),
|
|
74257
|
+
/* @__PURE__ */ jsxs(
|
|
74258
|
+
Link$1,
|
|
74259
|
+
{
|
|
74260
|
+
to: appPath("/admin/waitlist"),
|
|
74261
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
74262
|
+
children: [
|
|
74263
|
+
/* @__PURE__ */ jsx(Mail, { size: 16 }),
|
|
74264
|
+
"Waitlist"
|
|
74265
|
+
]
|
|
74266
|
+
}
|
|
74267
|
+
),
|
|
74268
|
+
/* @__PURE__ */ jsxs(
|
|
74269
|
+
Link$1,
|
|
74270
|
+
{
|
|
74271
|
+
to: appPath("/admin/promo-codes"),
|
|
74272
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
74273
|
+
children: [
|
|
74274
|
+
/* @__PURE__ */ jsx(Tag, { size: 16 }),
|
|
74275
|
+
"Promo Codes"
|
|
74276
|
+
]
|
|
74277
|
+
}
|
|
73914
74278
|
)
|
|
73915
74279
|
] }),
|
|
73916
74280
|
/* @__PURE__ */ jsx("div", { className: "rounded-lg bg-error/10 p-4 text-sm text-error", children: error || "Team not found" }),
|
|
@@ -73970,6 +74334,28 @@ function AdminTeamPage() {
|
|
|
73970
74334
|
"Teams"
|
|
73971
74335
|
]
|
|
73972
74336
|
}
|
|
74337
|
+
),
|
|
74338
|
+
/* @__PURE__ */ jsxs(
|
|
74339
|
+
Link$1,
|
|
74340
|
+
{
|
|
74341
|
+
to: appPath("/admin/waitlist"),
|
|
74342
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
74343
|
+
children: [
|
|
74344
|
+
/* @__PURE__ */ jsx(Mail, { size: 16 }),
|
|
74345
|
+
"Waitlist"
|
|
74346
|
+
]
|
|
74347
|
+
}
|
|
74348
|
+
),
|
|
74349
|
+
/* @__PURE__ */ jsxs(
|
|
74350
|
+
Link$1,
|
|
74351
|
+
{
|
|
74352
|
+
to: appPath("/admin/promo-codes"),
|
|
74353
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
74354
|
+
children: [
|
|
74355
|
+
/* @__PURE__ */ jsx(Tag, { size: 16 }),
|
|
74356
|
+
"Promo Codes"
|
|
74357
|
+
]
|
|
74358
|
+
}
|
|
73973
74359
|
)
|
|
73974
74360
|
] }),
|
|
73975
74361
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 mb-6", children: [
|
|
@@ -74070,16 +74456,493 @@ function AdminTeamPage() {
|
|
|
74070
74456
|
] })
|
|
74071
74457
|
] }) });
|
|
74072
74458
|
}
|
|
74459
|
+
function AdminWaitlistPage() {
|
|
74460
|
+
var _a;
|
|
74461
|
+
const config = useConfig();
|
|
74462
|
+
const appPath = useAppPath();
|
|
74463
|
+
const [entries, setEntries] = useState([]);
|
|
74464
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
74465
|
+
const [error, setError] = useState("");
|
|
74466
|
+
const [success, setSuccess] = useState("");
|
|
74467
|
+
async function loadWaitlist() {
|
|
74468
|
+
setIsLoading(true);
|
|
74469
|
+
setError("");
|
|
74470
|
+
try {
|
|
74471
|
+
const response = await api.get("/api/admin/waitlist");
|
|
74472
|
+
setEntries(response.entries);
|
|
74473
|
+
} catch (err) {
|
|
74474
|
+
setError(err instanceof Error ? err.message : "Failed to load waitlist");
|
|
74475
|
+
} finally {
|
|
74476
|
+
setIsLoading(false);
|
|
74477
|
+
}
|
|
74478
|
+
}
|
|
74479
|
+
useEffect(() => {
|
|
74480
|
+
loadWaitlist();
|
|
74481
|
+
}, []);
|
|
74482
|
+
async function handleInvite(entryId, email) {
|
|
74483
|
+
setError("");
|
|
74484
|
+
setSuccess("");
|
|
74485
|
+
try {
|
|
74486
|
+
await api.post(`/api/admin/waitlist/${entryId}/invite`, {});
|
|
74487
|
+
setSuccess(`Invite sent to ${email}`);
|
|
74488
|
+
loadWaitlist();
|
|
74489
|
+
} catch (err) {
|
|
74490
|
+
setError(err instanceof Error ? err.message : "Failed to send invite");
|
|
74491
|
+
}
|
|
74492
|
+
}
|
|
74493
|
+
return /* @__PURE__ */ jsx("div", { className: "min-h-screen bg-background p-4 sm:p-8", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-6xl", children: [
|
|
74494
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
|
|
74495
|
+
/* @__PURE__ */ jsx("h1", { className: "text-xl sm:text-2xl font-bold text-text-primary", children: "Admin" }),
|
|
74496
|
+
/* @__PURE__ */ jsx(
|
|
74497
|
+
Link$1,
|
|
74498
|
+
{
|
|
74499
|
+
to: appPath("/"),
|
|
74500
|
+
className: "flex items-center justify-center rounded-lg p-2 text-text-muted hover:text-text-primary hover:bg-background-secondary",
|
|
74501
|
+
"aria-label": "Close",
|
|
74502
|
+
children: /* @__PURE__ */ jsx(X, { size: 20 })
|
|
74503
|
+
}
|
|
74504
|
+
)
|
|
74505
|
+
] }),
|
|
74506
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-6 sm:mb-8", children: [
|
|
74507
|
+
/* @__PURE__ */ jsxs(
|
|
74508
|
+
Link$1,
|
|
74509
|
+
{
|
|
74510
|
+
to: appPath("/admin"),
|
|
74511
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
74512
|
+
children: [
|
|
74513
|
+
/* @__PURE__ */ jsx(LayoutDashboard, { size: 16 }),
|
|
74514
|
+
"Overview"
|
|
74515
|
+
]
|
|
74516
|
+
}
|
|
74517
|
+
),
|
|
74518
|
+
/* @__PURE__ */ jsxs(
|
|
74519
|
+
Link$1,
|
|
74520
|
+
{
|
|
74521
|
+
to: appPath("/admin/users"),
|
|
74522
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
74523
|
+
children: [
|
|
74524
|
+
/* @__PURE__ */ jsx(Users, { size: 16 }),
|
|
74525
|
+
"Users"
|
|
74526
|
+
]
|
|
74527
|
+
}
|
|
74528
|
+
),
|
|
74529
|
+
((_a = config.teams) == null ? void 0 : _a.enabled) && /* @__PURE__ */ jsxs(
|
|
74530
|
+
Link$1,
|
|
74531
|
+
{
|
|
74532
|
+
to: appPath("/admin/teams"),
|
|
74533
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
74534
|
+
children: [
|
|
74535
|
+
/* @__PURE__ */ jsx(Building2, { size: 16 }),
|
|
74536
|
+
"Teams"
|
|
74537
|
+
]
|
|
74538
|
+
}
|
|
74539
|
+
),
|
|
74540
|
+
/* @__PURE__ */ jsxs(
|
|
74541
|
+
Link$1,
|
|
74542
|
+
{
|
|
74543
|
+
to: appPath("/admin/promo-codes"),
|
|
74544
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
74545
|
+
children: [
|
|
74546
|
+
/* @__PURE__ */ jsx(Tag, { size: 16 }),
|
|
74547
|
+
"Promo Codes"
|
|
74548
|
+
]
|
|
74549
|
+
}
|
|
74550
|
+
),
|
|
74551
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 rounded-full bg-primary px-4 py-2 text-sm font-medium text-white", children: [
|
|
74552
|
+
/* @__PURE__ */ jsx(Mail, { size: 16 }),
|
|
74553
|
+
"Waitlist"
|
|
74554
|
+
] })
|
|
74555
|
+
] }),
|
|
74556
|
+
error && /* @__PURE__ */ jsx("div", { className: "mb-6 rounded-lg bg-error/10 p-4 text-sm text-error", children: error }),
|
|
74557
|
+
success && /* @__PURE__ */ jsx("div", { className: "mb-6 rounded-lg bg-success/10 p-4 text-sm text-success", children: success }),
|
|
74558
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-lg bg-background-secondary overflow-hidden", children: [
|
|
74559
|
+
/* @__PURE__ */ jsx("div", { className: "hidden md:block px-4 py-3 bg-background", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-12 gap-4 text-sm font-medium text-text-muted", children: [
|
|
74560
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-4", children: "Email" }),
|
|
74561
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: "Name" }),
|
|
74562
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: "Status" }),
|
|
74563
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: "Joined" }),
|
|
74564
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: "Action" })
|
|
74565
|
+
] }) }),
|
|
74566
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y divide-background", children: isLoading ? /* @__PURE__ */ jsx("div", { className: "px-4 py-8 text-center text-text-muted", children: "Loading..." }) : entries.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-8 text-center text-text-muted", children: "No waitlist entries" }) : entries.map((entry) => /* @__PURE__ */ jsx("div", { className: "px-4 py-3 hover:bg-background/50", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-12 gap-2 md:gap-4 text-sm", children: [
|
|
74567
|
+
/* @__PURE__ */ jsx("div", { className: "md:col-span-4 text-text-primary", children: entry.email }),
|
|
74568
|
+
/* @__PURE__ */ jsx("div", { className: "md:col-span-2 text-text-secondary", children: entry.name || "-" }),
|
|
74569
|
+
/* @__PURE__ */ jsx("div", { className: "md:col-span-2 capitalize text-text-secondary", children: entry.status.replace("_", " ") }),
|
|
74570
|
+
/* @__PURE__ */ jsx("div", { className: "md:col-span-2 text-text-muted", children: new Date(entry.createdAt).toLocaleDateString() }),
|
|
74571
|
+
/* @__PURE__ */ jsx("div", { className: "md:col-span-2", children: /* @__PURE__ */ jsx(
|
|
74572
|
+
"button",
|
|
74573
|
+
{
|
|
74574
|
+
type: "button",
|
|
74575
|
+
onClick: () => handleInvite(entry.id, entry.email),
|
|
74576
|
+
disabled: entry.status === "invited",
|
|
74577
|
+
className: "rounded-lg bg-primary px-3 py-1.5 text-xs font-medium text-white hover:bg-primary-hover disabled:opacity-50",
|
|
74578
|
+
children: entry.status === "invited" ? "Invited" : "Invite"
|
|
74579
|
+
}
|
|
74580
|
+
) })
|
|
74581
|
+
] }) }, entry.id)) })
|
|
74582
|
+
] })
|
|
74583
|
+
] }) });
|
|
74584
|
+
}
|
|
74585
|
+
function AdminPromoCodesPage() {
|
|
74586
|
+
var _a, _b, _c;
|
|
74587
|
+
const config = useConfig();
|
|
74588
|
+
const appPath = useAppPath();
|
|
74589
|
+
const [promoCodes, setPromoCodes] = useState([]);
|
|
74590
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
74591
|
+
const [error, setError] = useState("");
|
|
74592
|
+
const [success, setSuccess] = useState("");
|
|
74593
|
+
const [search2, setSearch] = useState("");
|
|
74594
|
+
const [statusFilter, setStatusFilter] = useState("all");
|
|
74595
|
+
const [copiedCode, setCopiedCode] = useState(null);
|
|
74596
|
+
const [form, setForm] = useState({
|
|
74597
|
+
code: "",
|
|
74598
|
+
credits: 10,
|
|
74599
|
+
maxUses: 100,
|
|
74600
|
+
startsAt: "",
|
|
74601
|
+
endsAt: "",
|
|
74602
|
+
creditsExpiresAt: ""
|
|
74603
|
+
});
|
|
74604
|
+
async function loadPromoCodes() {
|
|
74605
|
+
setIsLoading(true);
|
|
74606
|
+
setError("");
|
|
74607
|
+
try {
|
|
74608
|
+
const params = new URLSearchParams();
|
|
74609
|
+
if (search2.trim()) {
|
|
74610
|
+
params.set("search", search2.trim());
|
|
74611
|
+
}
|
|
74612
|
+
if (statusFilter !== "all") {
|
|
74613
|
+
params.set("status", statusFilter);
|
|
74614
|
+
}
|
|
74615
|
+
const query = params.toString();
|
|
74616
|
+
const response = await api.get(`/api/admin/promo-codes${query ? `?${query}` : ""}`);
|
|
74617
|
+
setPromoCodes(response.promoCodes);
|
|
74618
|
+
} catch (err) {
|
|
74619
|
+
setError(err instanceof Error ? err.message : "Failed to load promo codes");
|
|
74620
|
+
} finally {
|
|
74621
|
+
setIsLoading(false);
|
|
74622
|
+
}
|
|
74623
|
+
}
|
|
74624
|
+
useEffect(() => {
|
|
74625
|
+
loadPromoCodes();
|
|
74626
|
+
}, [search2, statusFilter]);
|
|
74627
|
+
async function handleCreatePromoCode(e) {
|
|
74628
|
+
e.preventDefault();
|
|
74629
|
+
setError("");
|
|
74630
|
+
setSuccess("");
|
|
74631
|
+
try {
|
|
74632
|
+
const payload = {
|
|
74633
|
+
code: form.code.trim(),
|
|
74634
|
+
credits: Number(form.credits),
|
|
74635
|
+
maxUses: Number(form.maxUses),
|
|
74636
|
+
startsAt: form.startsAt || void 0,
|
|
74637
|
+
endsAt: form.endsAt || void 0,
|
|
74638
|
+
creditsExpiresAt: form.creditsExpiresAt || void 0
|
|
74639
|
+
};
|
|
74640
|
+
const response = await api.post("/api/admin/promo-codes", payload);
|
|
74641
|
+
setPromoCodes((prev) => [response.promoCode, ...prev]);
|
|
74642
|
+
setSuccess(`Promo code ${response.promoCode.code} created`);
|
|
74643
|
+
setForm({
|
|
74644
|
+
code: "",
|
|
74645
|
+
credits: 10,
|
|
74646
|
+
maxUses: 100,
|
|
74647
|
+
startsAt: "",
|
|
74648
|
+
endsAt: "",
|
|
74649
|
+
creditsExpiresAt: ""
|
|
74650
|
+
});
|
|
74651
|
+
} catch (err) {
|
|
74652
|
+
setError(err instanceof Error ? err.message : "Failed to create promo code");
|
|
74653
|
+
}
|
|
74654
|
+
}
|
|
74655
|
+
const promoEnabled = ((_a = config.credits) == null ? void 0 : _a.enabled) && ((_b = config.credits) == null ? void 0 : _b.promoEnabled) !== false;
|
|
74656
|
+
async function handleDeactivate(promo) {
|
|
74657
|
+
setError("");
|
|
74658
|
+
setSuccess("");
|
|
74659
|
+
try {
|
|
74660
|
+
const response = await api.patch(`/api/admin/promo-codes/${promo.id}`, {
|
|
74661
|
+
endsAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
74662
|
+
});
|
|
74663
|
+
setPromoCodes((prev) => prev.map((p) => p.id === promo.id ? response.promoCode : p));
|
|
74664
|
+
setSuccess(`Promo code ${promo.code} deactivated`);
|
|
74665
|
+
} catch (err) {
|
|
74666
|
+
setError(err instanceof Error ? err.message : "Failed to deactivate promo code");
|
|
74667
|
+
}
|
|
74668
|
+
}
|
|
74669
|
+
async function handleReactivate(promo) {
|
|
74670
|
+
setError("");
|
|
74671
|
+
setSuccess("");
|
|
74672
|
+
try {
|
|
74673
|
+
const response = await api.patch(`/api/admin/promo-codes/${promo.id}`, {
|
|
74674
|
+
endsAt: null
|
|
74675
|
+
});
|
|
74676
|
+
setPromoCodes((prev) => prev.map((p) => p.id === promo.id ? response.promoCode : p));
|
|
74677
|
+
setSuccess(`Promo code ${promo.code} reactivated`);
|
|
74678
|
+
} catch (err) {
|
|
74679
|
+
setError(err instanceof Error ? err.message : "Failed to reactivate promo code");
|
|
74680
|
+
}
|
|
74681
|
+
}
|
|
74682
|
+
async function handleCopy(code2) {
|
|
74683
|
+
try {
|
|
74684
|
+
await navigator.clipboard.writeText(code2);
|
|
74685
|
+
setCopiedCode(code2);
|
|
74686
|
+
setTimeout(() => setCopiedCode((current) => current === code2 ? null : current), 1500);
|
|
74687
|
+
} catch (err) {
|
|
74688
|
+
setError(err instanceof Error ? err.message : "Failed to copy code");
|
|
74689
|
+
}
|
|
74690
|
+
}
|
|
74691
|
+
return /* @__PURE__ */ jsx("div", { className: "min-h-screen bg-background p-4 sm:p-8", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-6xl", children: [
|
|
74692
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
|
|
74693
|
+
/* @__PURE__ */ jsx("h1", { className: "text-xl sm:text-2xl font-bold text-text-primary", children: "Admin" }),
|
|
74694
|
+
/* @__PURE__ */ jsx(
|
|
74695
|
+
Link$1,
|
|
74696
|
+
{
|
|
74697
|
+
to: appPath("/"),
|
|
74698
|
+
className: "flex items-center justify-center rounded-lg p-2 text-text-muted hover:text-text-primary hover:bg-background-secondary",
|
|
74699
|
+
"aria-label": "Close",
|
|
74700
|
+
children: /* @__PURE__ */ jsx(X, { size: 20 })
|
|
74701
|
+
}
|
|
74702
|
+
)
|
|
74703
|
+
] }),
|
|
74704
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-6 sm:mb-8", children: [
|
|
74705
|
+
/* @__PURE__ */ jsxs(
|
|
74706
|
+
Link$1,
|
|
74707
|
+
{
|
|
74708
|
+
to: appPath("/admin"),
|
|
74709
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
74710
|
+
children: [
|
|
74711
|
+
/* @__PURE__ */ jsx(LayoutDashboard, { size: 16 }),
|
|
74712
|
+
"Overview"
|
|
74713
|
+
]
|
|
74714
|
+
}
|
|
74715
|
+
),
|
|
74716
|
+
/* @__PURE__ */ jsxs(
|
|
74717
|
+
Link$1,
|
|
74718
|
+
{
|
|
74719
|
+
to: appPath("/admin/users"),
|
|
74720
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
74721
|
+
children: [
|
|
74722
|
+
/* @__PURE__ */ jsx(Users, { size: 16 }),
|
|
74723
|
+
"Users"
|
|
74724
|
+
]
|
|
74725
|
+
}
|
|
74726
|
+
),
|
|
74727
|
+
((_c = config.teams) == null ? void 0 : _c.enabled) && /* @__PURE__ */ jsxs(
|
|
74728
|
+
Link$1,
|
|
74729
|
+
{
|
|
74730
|
+
to: appPath("/admin/teams"),
|
|
74731
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
74732
|
+
children: [
|
|
74733
|
+
/* @__PURE__ */ jsx(Building2, { size: 16 }),
|
|
74734
|
+
"Teams"
|
|
74735
|
+
]
|
|
74736
|
+
}
|
|
74737
|
+
),
|
|
74738
|
+
/* @__PURE__ */ jsxs(
|
|
74739
|
+
Link$1,
|
|
74740
|
+
{
|
|
74741
|
+
to: appPath("/admin/waitlist"),
|
|
74742
|
+
className: "flex items-center gap-1.5 rounded-full bg-background-secondary px-4 py-2 text-sm font-medium text-text-secondary hover:bg-background-secondary/80",
|
|
74743
|
+
children: [
|
|
74744
|
+
/* @__PURE__ */ jsx(Mail, { size: 16 }),
|
|
74745
|
+
"Waitlist"
|
|
74746
|
+
]
|
|
74747
|
+
}
|
|
74748
|
+
),
|
|
74749
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 rounded-full bg-primary px-4 py-2 text-sm font-medium text-white", children: [
|
|
74750
|
+
/* @__PURE__ */ jsx(Tag, { size: 16 }),
|
|
74751
|
+
"Promo Codes"
|
|
74752
|
+
] })
|
|
74753
|
+
] }),
|
|
74754
|
+
!promoEnabled && /* @__PURE__ */ jsx("div", { className: "mb-6 rounded-lg bg-warning/10 p-4 text-sm text-warning", children: "Promo codes are disabled in config. Enable `credits.promoEnabled` to use this page." }),
|
|
74755
|
+
error && /* @__PURE__ */ jsx("div", { className: "mb-6 rounded-lg bg-error/10 p-4 text-sm text-error", children: error }),
|
|
74756
|
+
success && /* @__PURE__ */ jsx("div", { className: "mb-6 rounded-lg bg-success/10 p-4 text-sm text-success", children: success }),
|
|
74757
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-6", children: [
|
|
74758
|
+
/* @__PURE__ */ jsxs("div", { className: "lg:col-span-1 rounded-lg bg-background-secondary p-4", children: [
|
|
74759
|
+
/* @__PURE__ */ jsx("h2", { className: "text-base font-semibold text-text-primary mb-4", children: "Create Promo Code" }),
|
|
74760
|
+
/* @__PURE__ */ jsxs("form", { onSubmit: handleCreatePromoCode, className: "space-y-3", children: [
|
|
74761
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
74762
|
+
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-text-primary", htmlFor: "promo-code", children: "Code" }),
|
|
74763
|
+
/* @__PURE__ */ jsx(
|
|
74764
|
+
"input",
|
|
74765
|
+
{
|
|
74766
|
+
id: "promo-code",
|
|
74767
|
+
value: form.code,
|
|
74768
|
+
onChange: (e) => setForm((prev) => ({ ...prev, code: e.target.value })),
|
|
74769
|
+
className: "mt-1 w-full rounded-lg border border-input-border bg-input-background px-3 py-2 text-text-primary focus:border-primary focus:outline-none",
|
|
74770
|
+
placeholder: "WELCOME10",
|
|
74771
|
+
required: true
|
|
74772
|
+
}
|
|
74773
|
+
)
|
|
74774
|
+
] }),
|
|
74775
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
74776
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
74777
|
+
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-text-primary", htmlFor: "promo-credits", children: "Credits" }),
|
|
74778
|
+
/* @__PURE__ */ jsx(
|
|
74779
|
+
"input",
|
|
74780
|
+
{
|
|
74781
|
+
id: "promo-credits",
|
|
74782
|
+
type: "number",
|
|
74783
|
+
min: 1,
|
|
74784
|
+
value: form.credits,
|
|
74785
|
+
onChange: (e) => setForm((prev) => ({ ...prev, credits: Number(e.target.value) })),
|
|
74786
|
+
className: "mt-1 w-full rounded-lg border border-input-border bg-input-background px-3 py-2 text-text-primary focus:border-primary focus:outline-none",
|
|
74787
|
+
required: true
|
|
74788
|
+
}
|
|
74789
|
+
)
|
|
74790
|
+
] }),
|
|
74791
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
74792
|
+
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-text-primary", htmlFor: "promo-uses", children: "Max Uses" }),
|
|
74793
|
+
/* @__PURE__ */ jsx(
|
|
74794
|
+
"input",
|
|
74795
|
+
{
|
|
74796
|
+
id: "promo-uses",
|
|
74797
|
+
type: "number",
|
|
74798
|
+
min: 1,
|
|
74799
|
+
value: form.maxUses,
|
|
74800
|
+
onChange: (e) => setForm((prev) => ({ ...prev, maxUses: Number(e.target.value) })),
|
|
74801
|
+
className: "mt-1 w-full rounded-lg border border-input-border bg-input-background px-3 py-2 text-text-primary focus:border-primary focus:outline-none",
|
|
74802
|
+
required: true
|
|
74803
|
+
}
|
|
74804
|
+
)
|
|
74805
|
+
] })
|
|
74806
|
+
] }),
|
|
74807
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
74808
|
+
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-text-primary", htmlFor: "promo-start", children: "Starts At (optional)" }),
|
|
74809
|
+
/* @__PURE__ */ jsx(
|
|
74810
|
+
"input",
|
|
74811
|
+
{
|
|
74812
|
+
id: "promo-start",
|
|
74813
|
+
type: "datetime-local",
|
|
74814
|
+
value: form.startsAt,
|
|
74815
|
+
onChange: (e) => setForm((prev) => ({ ...prev, startsAt: e.target.value })),
|
|
74816
|
+
className: "mt-1 w-full rounded-lg border border-input-border bg-input-background px-3 py-2 text-text-primary focus:border-primary focus:outline-none"
|
|
74817
|
+
}
|
|
74818
|
+
)
|
|
74819
|
+
] }),
|
|
74820
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
74821
|
+
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-text-primary", htmlFor: "promo-end", children: "Ends At (optional)" }),
|
|
74822
|
+
/* @__PURE__ */ jsx(
|
|
74823
|
+
"input",
|
|
74824
|
+
{
|
|
74825
|
+
id: "promo-end",
|
|
74826
|
+
type: "datetime-local",
|
|
74827
|
+
value: form.endsAt,
|
|
74828
|
+
onChange: (e) => setForm((prev) => ({ ...prev, endsAt: e.target.value })),
|
|
74829
|
+
className: "mt-1 w-full rounded-lg border border-input-border bg-input-background px-3 py-2 text-text-primary focus:border-primary focus:outline-none"
|
|
74830
|
+
}
|
|
74831
|
+
)
|
|
74832
|
+
] }),
|
|
74833
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
74834
|
+
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-text-primary", htmlFor: "promo-expires", children: "Credits Expire At (optional)" }),
|
|
74835
|
+
/* @__PURE__ */ jsx(
|
|
74836
|
+
"input",
|
|
74837
|
+
{
|
|
74838
|
+
id: "promo-expires",
|
|
74839
|
+
type: "datetime-local",
|
|
74840
|
+
value: form.creditsExpiresAt,
|
|
74841
|
+
onChange: (e) => setForm((prev) => ({ ...prev, creditsExpiresAt: e.target.value })),
|
|
74842
|
+
className: "mt-1 w-full rounded-lg border border-input-border bg-input-background px-3 py-2 text-text-primary focus:border-primary focus:outline-none"
|
|
74843
|
+
}
|
|
74844
|
+
)
|
|
74845
|
+
] }),
|
|
74846
|
+
/* @__PURE__ */ jsx(
|
|
74847
|
+
"button",
|
|
74848
|
+
{
|
|
74849
|
+
type: "submit",
|
|
74850
|
+
disabled: !promoEnabled,
|
|
74851
|
+
className: "w-full rounded-lg bg-primary px-4 py-2 font-medium text-white hover:bg-primary-hover disabled:opacity-50",
|
|
74852
|
+
children: "Create promo code"
|
|
74853
|
+
}
|
|
74854
|
+
)
|
|
74855
|
+
] })
|
|
74856
|
+
] }),
|
|
74857
|
+
/* @__PURE__ */ jsxs("div", { className: "lg:col-span-2 rounded-lg bg-background-secondary overflow-hidden", children: [
|
|
74858
|
+
/* @__PURE__ */ jsxs("div", { className: "px-4 py-3 bg-background flex flex-wrap items-center gap-3", children: [
|
|
74859
|
+
/* @__PURE__ */ jsx(
|
|
74860
|
+
"input",
|
|
74861
|
+
{
|
|
74862
|
+
type: "text",
|
|
74863
|
+
placeholder: "Search code...",
|
|
74864
|
+
value: search2,
|
|
74865
|
+
onChange: (e) => setSearch(e.target.value),
|
|
74866
|
+
className: "flex-1 min-w-[160px] rounded-lg border border-input-border bg-input-background px-3 py-2 text-sm text-text-primary focus:border-primary focus:outline-none"
|
|
74867
|
+
}
|
|
74868
|
+
),
|
|
74869
|
+
/* @__PURE__ */ jsxs(
|
|
74870
|
+
"select",
|
|
74871
|
+
{
|
|
74872
|
+
value: statusFilter,
|
|
74873
|
+
onChange: (e) => setStatusFilter(e.target.value),
|
|
74874
|
+
className: "rounded-lg border border-input-border bg-input-background px-3 py-2 text-sm text-text-primary focus:border-primary focus:outline-none",
|
|
74875
|
+
children: [
|
|
74876
|
+
/* @__PURE__ */ jsx("option", { value: "all", children: "All" }),
|
|
74877
|
+
/* @__PURE__ */ jsx("option", { value: "active", children: "Active" }),
|
|
74878
|
+
/* @__PURE__ */ jsx("option", { value: "scheduled", children: "Scheduled" }),
|
|
74879
|
+
/* @__PURE__ */ jsx("option", { value: "expired", children: "Expired" })
|
|
74880
|
+
]
|
|
74881
|
+
}
|
|
74882
|
+
)
|
|
74883
|
+
] }),
|
|
74884
|
+
/* @__PURE__ */ jsx("div", { className: "hidden md:block px-4 py-3 bg-background", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-12 gap-4 text-sm font-medium text-text-muted", children: [
|
|
74885
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-3", children: "Code" }),
|
|
74886
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: "Credits" }),
|
|
74887
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: "Uses" }),
|
|
74888
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: "Active" }),
|
|
74889
|
+
/* @__PURE__ */ jsx("div", { className: "col-span-3", children: "Actions" })
|
|
74890
|
+
] }) }),
|
|
74891
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y divide-background", children: isLoading ? /* @__PURE__ */ jsx("div", { className: "px-4 py-8 text-center text-text-muted", children: "Loading..." }) : promoCodes.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-8 text-center text-text-muted", children: "No promo codes yet" }) : promoCodes.map((promo) => {
|
|
74892
|
+
const now = /* @__PURE__ */ new Date();
|
|
74893
|
+
const startsAt = promo.startsAt ? new Date(promo.startsAt) : null;
|
|
74894
|
+
const endsAt = promo.endsAt ? new Date(promo.endsAt) : null;
|
|
74895
|
+
const active = (!startsAt || startsAt <= now) && (!endsAt || endsAt >= now);
|
|
74896
|
+
return /* @__PURE__ */ jsx("div", { className: "px-4 py-3 hover:bg-background/50", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-12 gap-2 md:gap-4 text-sm", children: [
|
|
74897
|
+
/* @__PURE__ */ jsxs("div", { className: "md:col-span-3 font-medium text-text-primary flex items-center gap-2", children: [
|
|
74898
|
+
/* @__PURE__ */ jsx("span", { children: promo.code }),
|
|
74899
|
+
/* @__PURE__ */ jsx(
|
|
74900
|
+
"button",
|
|
74901
|
+
{
|
|
74902
|
+
type: "button",
|
|
74903
|
+
onClick: () => handleCopy(promo.code),
|
|
74904
|
+
className: "text-xs text-primary hover:underline",
|
|
74905
|
+
children: copiedCode === promo.code ? "Copied" : "Copy"
|
|
74906
|
+
}
|
|
74907
|
+
)
|
|
74908
|
+
] }),
|
|
74909
|
+
/* @__PURE__ */ jsx("div", { className: "md:col-span-2 text-text-secondary", children: promo.credits }),
|
|
74910
|
+
/* @__PURE__ */ jsxs("div", { className: "md:col-span-2 text-text-secondary", children: [
|
|
74911
|
+
promo.redeemedCount,
|
|
74912
|
+
" / ",
|
|
74913
|
+
promo.maxUses
|
|
74914
|
+
] }),
|
|
74915
|
+
/* @__PURE__ */ jsx("div", { className: `md:col-span-2 ${active ? "text-success" : "text-text-muted"}`, children: active ? "Active" : "Inactive" }),
|
|
74916
|
+
/* @__PURE__ */ jsxs("div", { className: "md:col-span-3 text-text-muted flex items-center gap-2", children: [
|
|
74917
|
+
/* @__PURE__ */ jsx("span", { children: new Date(promo.createdAt).toLocaleDateString() }),
|
|
74918
|
+
/* @__PURE__ */ jsx(
|
|
74919
|
+
"button",
|
|
74920
|
+
{
|
|
74921
|
+
type: "button",
|
|
74922
|
+
onClick: () => active ? handleDeactivate(promo) : handleReactivate(promo),
|
|
74923
|
+
className: "rounded-lg border border-input-border px-2 py-1 text-xs text-text-primary hover:bg-background",
|
|
74924
|
+
children: active ? "Deactivate" : "Reactivate"
|
|
74925
|
+
}
|
|
74926
|
+
)
|
|
74927
|
+
] })
|
|
74928
|
+
] }) }, promo.id);
|
|
74929
|
+
}) })
|
|
74930
|
+
] })
|
|
74931
|
+
] })
|
|
74932
|
+
] }) });
|
|
74933
|
+
}
|
|
74073
74934
|
const styles = "@chaaskit/client/src/styles/index.css";
|
|
74074
|
-
function ChatProviders({ children }) {
|
|
74075
|
-
return /* @__PURE__ */ jsx(ConfigProvider, { children: /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(AuthProvider, { children: /* @__PURE__ */ jsx(TeamProvider, { children: /* @__PURE__ */ jsx(ProjectProvider, { children }) }) }) }) });
|
|
74935
|
+
function ChatProviders({ children, initialConfig }) {
|
|
74936
|
+
return /* @__PURE__ */ jsx(ConfigProvider, { initialConfig, children: /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(AuthProvider, { children: /* @__PURE__ */ jsx(TeamProvider, { children: /* @__PURE__ */ jsx(ProjectProvider, { children }) }) }) }) });
|
|
74076
74937
|
}
|
|
74077
74938
|
export {
|
|
74078
74939
|
AcceptInvitePage,
|
|
74079
74940
|
AdminDashboardPage,
|
|
74941
|
+
AdminPromoCodesPage,
|
|
74080
74942
|
AdminTeamPage,
|
|
74081
74943
|
AdminTeamsPage,
|
|
74082
74944
|
AdminUsersPage,
|
|
74945
|
+
AdminWaitlistPage,
|
|
74083
74946
|
ApiKeysPage,
|
|
74084
74947
|
AuthProvider,
|
|
74085
74948
|
C as ChatLoadingSkeleton,
|
|
@@ -74108,7 +74971,7 @@ export {
|
|
|
74108
74971
|
TermsPage,
|
|
74109
74972
|
ThemeProvider,
|
|
74110
74973
|
VerifyEmailPage,
|
|
74111
|
-
|
|
74974
|
+
clientRegistry,
|
|
74112
74975
|
styles,
|
|
74113
74976
|
useAppPath,
|
|
74114
74977
|
useAuth,
|