@howone/sdk 0.3.21 → 0.3.23
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/index.d.mts +30 -2
- package/dist/index.d.ts +30 -2
- package/dist/index.js +1020 -794
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +997 -776
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -258,6 +258,69 @@ var init_auth = __esm({
|
|
|
258
258
|
}
|
|
259
259
|
});
|
|
260
260
|
|
|
261
|
+
// src/utils/session.ts
|
|
262
|
+
var session_exports = {};
|
|
263
|
+
__export(session_exports, {
|
|
264
|
+
clearGuestSession: () => clearGuestSession,
|
|
265
|
+
consumeGuestSession: () => consumeGuestSession,
|
|
266
|
+
getExistingSessionId: () => getExistingSessionId,
|
|
267
|
+
getGuestSessionId: () => getGuestSessionId,
|
|
268
|
+
isGuestMode: () => isGuestMode
|
|
269
|
+
});
|
|
270
|
+
function getGuestSessionId() {
|
|
271
|
+
if (typeof window === "undefined") return null;
|
|
272
|
+
try {
|
|
273
|
+
let sessionId = localStorage.getItem(GUEST_SESSION_KEY);
|
|
274
|
+
if (!sessionId) {
|
|
275
|
+
sessionId = crypto.randomUUID();
|
|
276
|
+
localStorage.setItem(GUEST_SESSION_KEY, sessionId);
|
|
277
|
+
}
|
|
278
|
+
return sessionId;
|
|
279
|
+
} catch {
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function clearGuestSession() {
|
|
284
|
+
if (typeof window === "undefined") return;
|
|
285
|
+
try {
|
|
286
|
+
localStorage.removeItem(GUEST_SESSION_KEY);
|
|
287
|
+
} catch {
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
function isGuestMode() {
|
|
291
|
+
if (typeof window === "undefined") return false;
|
|
292
|
+
const hasAuthToken = !!localStorage.getItem("auth_token");
|
|
293
|
+
const hasSession = !!localStorage.getItem(GUEST_SESSION_KEY);
|
|
294
|
+
return !hasAuthToken && hasSession;
|
|
295
|
+
}
|
|
296
|
+
function getExistingSessionId() {
|
|
297
|
+
if (typeof window === "undefined") return null;
|
|
298
|
+
try {
|
|
299
|
+
return localStorage.getItem(GUEST_SESSION_KEY);
|
|
300
|
+
} catch {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
function consumeGuestSession() {
|
|
305
|
+
if (typeof window === "undefined") return null;
|
|
306
|
+
try {
|
|
307
|
+
const sessionId = localStorage.getItem(GUEST_SESSION_KEY);
|
|
308
|
+
if (sessionId) {
|
|
309
|
+
localStorage.removeItem(GUEST_SESSION_KEY);
|
|
310
|
+
}
|
|
311
|
+
return sessionId;
|
|
312
|
+
} catch {
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
var GUEST_SESSION_KEY;
|
|
317
|
+
var init_session = __esm({
|
|
318
|
+
"src/utils/session.ts"() {
|
|
319
|
+
"use strict";
|
|
320
|
+
GUEST_SESSION_KEY = "howone_guest_session";
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
|
|
261
324
|
// src/components/FloatingButton.tsx
|
|
262
325
|
import { Icon } from "@iconify/react/dist/iconify.js";
|
|
263
326
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -951,7 +1014,7 @@ var LoginForm = ({
|
|
|
951
1014
|
|
|
952
1015
|
// src/components/auth/HowoneProvider.tsx
|
|
953
1016
|
init_auth();
|
|
954
|
-
import { createContext as createContext2, useContext as useContext2, useState as
|
|
1017
|
+
import { createContext as createContext2, useContext as useContext2, useState as useState8, useEffect as useEffect7, useMemo, useCallback as useCallback5 } from "react";
|
|
955
1018
|
|
|
956
1019
|
// src/components/theme/ThemeProvider.tsx
|
|
957
1020
|
import { createContext, useContext, useEffect as useEffect3, useState as useState3 } from "react";
|
|
@@ -1249,666 +1312,176 @@ var ElementSelectorProvider = ({ children }) => {
|
|
|
1249
1312
|
|
|
1250
1313
|
// src/components/auth/HowoneProvider.tsx
|
|
1251
1314
|
init_config();
|
|
1252
|
-
|
|
1253
|
-
var HowoneContext = createContext2(null);
|
|
1254
|
-
var redirectOverlayStylesInjected = false;
|
|
1255
|
-
var injectRedirectOverlayStyles = () => {
|
|
1256
|
-
if (redirectOverlayStylesInjected || typeof document === "undefined") return;
|
|
1257
|
-
const style = document.createElement("style");
|
|
1258
|
-
style.setAttribute("data-howone-auth-overlay", "true");
|
|
1259
|
-
style.textContent = `
|
|
1260
|
-
@keyframes howone-logo-pulse {
|
|
1261
|
-
0%, 100% {
|
|
1262
|
-
opacity: 0.2;
|
|
1263
|
-
transform: scale(0.95);
|
|
1264
|
-
filter: drop-shadow(0 0 0 rgba(255, 255, 255, 0.2));
|
|
1265
|
-
}
|
|
1266
|
-
50% {
|
|
1267
|
-
opacity: 1;
|
|
1268
|
-
transform: scale(1.03);
|
|
1269
|
-
filter: drop-shadow(0 0 28px rgba(255, 255, 255, 0.55));
|
|
1270
|
-
}
|
|
1271
|
-
}
|
|
1315
|
+
init_session();
|
|
1272
1316
|
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
}
|
|
1278
|
-
50% {
|
|
1279
|
-
opacity: 0.42;
|
|
1280
|
-
transform: scale(1.05);
|
|
1281
|
-
}
|
|
1282
|
-
}
|
|
1317
|
+
// src/components/ui/Toast/ClayxToast.tsx
|
|
1318
|
+
import React5, { useCallback as useCallback4 } from "react";
|
|
1319
|
+
import { Bounce, toast } from "react-toastify";
|
|
1320
|
+
import { Icon as Icon4 } from "@iconify/react";
|
|
1283
1321
|
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
height: 100vh;
|
|
1294
|
-
color: #ffffff;
|
|
1295
|
-
background: rgba(0, 0, 0, 0.65);
|
|
1296
|
-
backdrop-filter: blur(6px);
|
|
1297
|
-
-webkit-backdrop-filter: blur(6px);
|
|
1298
|
-
text-align: center;
|
|
1299
|
-
}
|
|
1300
|
-
`;
|
|
1301
|
-
document.head.appendChild(style);
|
|
1302
|
-
redirectOverlayStylesInjected = true;
|
|
1303
|
-
};
|
|
1304
|
-
var HowOneProvider = ({
|
|
1305
|
-
children,
|
|
1306
|
-
showFloatingButton = true,
|
|
1307
|
-
projectId,
|
|
1308
|
-
defaultTheme = "system",
|
|
1309
|
-
themeStorageKey = "howone-theme",
|
|
1310
|
-
forceDefaultTheme = false,
|
|
1311
|
-
redirectOnUnauthenticated = true
|
|
1312
|
-
}) => {
|
|
1313
|
-
const [user, setUser] = useState7(() => parseUserFromToken(getToken()));
|
|
1314
|
-
const [token, setTokenState] = useState7(() => getToken());
|
|
1315
|
-
const [hasCheckedUrlToken, setHasCheckedUrlToken] = useState7(false);
|
|
1316
|
-
const [pendingRedirect, setPendingRedirect] = useState7(false);
|
|
1317
|
-
useEffect6(() => {
|
|
1318
|
-
try {
|
|
1319
|
-
const params = new URLSearchParams(window.location.search);
|
|
1320
|
-
let urlToken = params.get("access_token") || params.get("token");
|
|
1321
|
-
if (!urlToken && window.location.hash) {
|
|
1322
|
-
const hashParams = new URLSearchParams(window.location.hash.slice(1));
|
|
1323
|
-
urlToken = hashParams.get("access_token") || hashParams.get("token");
|
|
1324
|
-
}
|
|
1325
|
-
if (urlToken) {
|
|
1326
|
-
setToken(urlToken);
|
|
1327
|
-
setTokenState(urlToken);
|
|
1328
|
-
setUser(parseUserFromToken(urlToken));
|
|
1329
|
-
params.delete("access_token");
|
|
1330
|
-
params.delete("token");
|
|
1331
|
-
params.delete("project_id");
|
|
1332
|
-
const newSearch = params.toString();
|
|
1333
|
-
const newUrl = window.location.pathname + (newSearch ? "?" + newSearch : "");
|
|
1334
|
-
window.history.replaceState({}, "", newUrl);
|
|
1335
|
-
}
|
|
1336
|
-
} catch (e) {
|
|
1337
|
-
console.error("[HowOneProvider] Failed to capture token from URL:", e);
|
|
1338
|
-
} finally {
|
|
1339
|
-
setHasCheckedUrlToken(true);
|
|
1340
|
-
}
|
|
1341
|
-
}, []);
|
|
1342
|
-
const resolvedAuthUrl = useMemo(() => {
|
|
1343
|
-
const env3 = getGlobalEnvironment() ?? "dev";
|
|
1344
|
-
switch (env3) {
|
|
1345
|
-
case "local":
|
|
1346
|
-
return "http://localhost:3000/auth";
|
|
1347
|
-
case "prod":
|
|
1348
|
-
return "https://howone.ai/auth";
|
|
1349
|
-
case "dev":
|
|
1350
|
-
default:
|
|
1351
|
-
return "https://howone.dev/auth";
|
|
1352
|
-
}
|
|
1322
|
+
// src/components/theme/ThemeToggle.tsx
|
|
1323
|
+
import * as React4 from "react";
|
|
1324
|
+
import { Icon as Icon3 } from "@iconify/react";
|
|
1325
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1326
|
+
function ThemeToggle({ className }) {
|
|
1327
|
+
const { setTheme, theme } = useTheme();
|
|
1328
|
+
const [mounted, setMounted] = React4.useState(false);
|
|
1329
|
+
React4.useEffect(() => {
|
|
1330
|
+
setMounted(true);
|
|
1353
1331
|
}, []);
|
|
1354
|
-
|
|
1355
|
-
if (
|
|
1356
|
-
|
|
1357
|
-
}
|
|
1358
|
-
|
|
1359
|
-
useEffect6(() => {
|
|
1360
|
-
if (pendingRedirect) {
|
|
1361
|
-
injectRedirectOverlayStyles();
|
|
1362
|
-
}
|
|
1363
|
-
}, [pendingRedirect]);
|
|
1364
|
-
const redirectToAuth = useCallback4(() => {
|
|
1365
|
-
if (!redirectOnUnauthenticated || typeof window === "undefined") return;
|
|
1366
|
-
const activeProjectId = projectId ?? getDefaultProjectId();
|
|
1367
|
-
const navigateToResolvedAuth = () => {
|
|
1368
|
-
setPendingRedirect(true);
|
|
1369
|
-
requestAnimationFrame(() => {
|
|
1370
|
-
if (activeProjectId) {
|
|
1371
|
-
try {
|
|
1372
|
-
const url = new URL(resolvedAuthUrl);
|
|
1373
|
-
url.searchParams.set("redirect_uri", window.location.href);
|
|
1374
|
-
url.searchParams.set("project_id", activeProjectId);
|
|
1375
|
-
window.location.href = url.toString();
|
|
1376
|
-
return;
|
|
1377
|
-
} catch (error) {
|
|
1378
|
-
console.error("[HowOneProvider] Failed to attach project_id to auth URL:", error);
|
|
1379
|
-
}
|
|
1380
|
-
}
|
|
1381
|
-
window.location.href = resolvedAuthUrl;
|
|
1382
|
-
});
|
|
1383
|
-
};
|
|
1384
|
-
try {
|
|
1385
|
-
const currentUrl = new URL(window.location.href);
|
|
1386
|
-
if (currentUrl.pathname.includes("/auth")) return;
|
|
1387
|
-
try {
|
|
1388
|
-
const authUrlObj = new URL(resolvedAuthUrl);
|
|
1389
|
-
authUrlObj.searchParams.set("redirect_uri", window.location.href);
|
|
1390
|
-
if (activeProjectId) {
|
|
1391
|
-
authUrlObj.searchParams.set("project_id", activeProjectId);
|
|
1392
|
-
}
|
|
1393
|
-
setPendingRedirect(true);
|
|
1394
|
-
requestAnimationFrame(() => {
|
|
1395
|
-
window.location.href = authUrlObj.toString();
|
|
1396
|
-
});
|
|
1397
|
-
return;
|
|
1398
|
-
} catch (error) {
|
|
1399
|
-
console.error("[HowOneProvider] Failed to build auth URL:", error);
|
|
1400
|
-
}
|
|
1401
|
-
navigateToResolvedAuth();
|
|
1402
|
-
} catch {
|
|
1403
|
-
navigateToResolvedAuth();
|
|
1404
|
-
}
|
|
1405
|
-
}, [redirectOnUnauthenticated, resolvedAuthUrl, projectId]);
|
|
1406
|
-
useEffect6(() => {
|
|
1407
|
-
if (!hasCheckedUrlToken) return;
|
|
1408
|
-
if (!token && !user) {
|
|
1409
|
-
redirectToAuth();
|
|
1410
|
-
}
|
|
1411
|
-
}, [token, user, hasCheckedUrlToken, redirectToAuth]);
|
|
1412
|
-
const logout = () => {
|
|
1413
|
-
try {
|
|
1414
|
-
setToken(null);
|
|
1415
|
-
} catch {
|
|
1332
|
+
const handleToggle = () => {
|
|
1333
|
+
if (theme === "dark") {
|
|
1334
|
+
setTheme("light");
|
|
1335
|
+
} else {
|
|
1336
|
+
setTheme("dark");
|
|
1416
1337
|
}
|
|
1417
|
-
setTokenState(null);
|
|
1418
|
-
setUser(null);
|
|
1419
|
-
redirectToAuth();
|
|
1420
|
-
};
|
|
1421
|
-
const value = {
|
|
1422
|
-
user,
|
|
1423
|
-
token,
|
|
1424
|
-
isAuthenticated: hasCheckedUrlToken && !!token,
|
|
1425
|
-
logout
|
|
1426
1338
|
};
|
|
1427
|
-
if (!
|
|
1428
|
-
|
|
1429
|
-
|
|
1339
|
+
if (!mounted) {
|
|
1340
|
+
return /* @__PURE__ */ jsx7(Icon3, { icon: "solar:sun-bold", width: 20, height: 20 });
|
|
1341
|
+
}
|
|
1342
|
+
return /* @__PURE__ */ jsx7(
|
|
1343
|
+
"div",
|
|
1430
1344
|
{
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
children: [
|
|
1435
|
-
/* @__PURE__ */ jsx7(ElementSelectorProvider, { children: /* @__PURE__ */ jsxs5(HowoneContext.Provider, { value, children: [
|
|
1436
|
-
children,
|
|
1437
|
-
showFloatingButton && /* @__PURE__ */ jsx7(FloatingButton, { onClick: () => window.open("https://howone.ai", "_blank") }),
|
|
1438
|
-
pendingRedirect && /* @__PURE__ */ jsx7(
|
|
1439
|
-
"div",
|
|
1440
|
-
{
|
|
1441
|
-
"data-howone-auth-overlay-root": true,
|
|
1442
|
-
className: "fixed inset-0 z-[100000] h-full w-full flex flex-col items-center justify-center bg-black/65 backdrop-blur-sm text-white",
|
|
1443
|
-
children: /* @__PURE__ */ jsxs5("div", { className: "relative mt-6 flex h-[220px] w-[220px] items-center justify-center", children: [
|
|
1444
|
-
/* @__PURE__ */ jsx7(
|
|
1445
|
-
"div",
|
|
1446
|
-
{
|
|
1447
|
-
className: "absolute inset-0 rounded-full bg-white/20",
|
|
1448
|
-
style: { animation: "howone-glow-ring 2.4s ease-in-out infinite" }
|
|
1449
|
-
}
|
|
1450
|
-
),
|
|
1451
|
-
/* @__PURE__ */ jsx7("div", { className: "absolute inset-0 rounded-full bg-gradient-to-br from-white/10 via-white/25 to-white/10 blur-2xl" }),
|
|
1452
|
-
/* @__PURE__ */ jsx7(
|
|
1453
|
-
"img",
|
|
1454
|
-
{
|
|
1455
|
-
style: { width: 250, animation: "howone-logo-pulse 2s ease-in-out infinite" },
|
|
1456
|
-
src: "https://sxwxqoixnnklnpeutjrj.supabase.co/storage/v1/object/public/create-x/logo/logo.svg",
|
|
1457
|
-
alt: "HowOne"
|
|
1458
|
-
}
|
|
1459
|
-
)
|
|
1460
|
-
] })
|
|
1461
|
-
}
|
|
1462
|
-
)
|
|
1463
|
-
] }) }),
|
|
1464
|
-
/* @__PURE__ */ jsx7(GlobalToastContainer, {})
|
|
1465
|
-
]
|
|
1345
|
+
className: `cursor-pointer ${className || ""}`,
|
|
1346
|
+
onClick: handleToggle,
|
|
1347
|
+
children: theme === "light" ? /* @__PURE__ */ jsx7(Icon3, { icon: "solar:sun-bold", width: 20, height: 20 }) : /* @__PURE__ */ jsx7(Icon3, { icon: "solar:moon-linear", width: 20, height: 20 })
|
|
1466
1348
|
}
|
|
1467
1349
|
);
|
|
1468
|
-
};
|
|
1469
|
-
function useHowoneContext() {
|
|
1470
|
-
const ctx = useContext2(HowoneContext);
|
|
1471
|
-
if (!ctx) {
|
|
1472
|
-
const t = getToken();
|
|
1473
|
-
return {
|
|
1474
|
-
user: parseUserFromToken(t),
|
|
1475
|
-
token: t,
|
|
1476
|
-
isAuthenticated: !!t,
|
|
1477
|
-
logout: () => {
|
|
1478
|
-
try {
|
|
1479
|
-
setToken(null);
|
|
1480
|
-
} catch {
|
|
1481
|
-
}
|
|
1482
|
-
}
|
|
1483
|
-
};
|
|
1484
|
-
}
|
|
1485
|
-
return ctx;
|
|
1486
1350
|
}
|
|
1487
1351
|
|
|
1488
|
-
// src/components/
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1352
|
+
// src/components/ui/Toast/ClayxToast.tsx
|
|
1353
|
+
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1354
|
+
var TOAST_ICONS = {
|
|
1355
|
+
success: {
|
|
1356
|
+
icon: "mdi:success",
|
|
1357
|
+
color: "text-green-400",
|
|
1358
|
+
className: "text-green-400",
|
|
1359
|
+
// 深色主题配置
|
|
1360
|
+
dark: {
|
|
1361
|
+
bgGradient: "bg-[#14181d]",
|
|
1362
|
+
// 移除透明度 f2
|
|
1363
|
+
gradientColor: "#389726",
|
|
1364
|
+
borderGradient: "border-[#389726]",
|
|
1365
|
+
borderGradientColor: "#389726"
|
|
1366
|
+
},
|
|
1367
|
+
// 浅色主题配置
|
|
1368
|
+
light: {
|
|
1369
|
+
bgGradient: "bg-[#fafafa]",
|
|
1370
|
+
// 移除透明度 ff
|
|
1371
|
+
gradientColor: "#22c55e",
|
|
1372
|
+
borderGradient: "border-[#22c55e]",
|
|
1373
|
+
borderGradientColor: "#22c55e"
|
|
1510
1374
|
}
|
|
1511
|
-
}
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1375
|
+
},
|
|
1376
|
+
error: {
|
|
1377
|
+
icon: "ic:outline-close",
|
|
1378
|
+
color: "text-red-400",
|
|
1379
|
+
className: "text-red-400",
|
|
1380
|
+
dark: {
|
|
1381
|
+
bgGradient: "bg-[#14181d]",
|
|
1382
|
+
// 移除透明度 f2
|
|
1383
|
+
gradientColor: "#ef4444",
|
|
1384
|
+
borderGradient: "border-[#ef4444]",
|
|
1385
|
+
borderGradientColor: "#ef4444"
|
|
1386
|
+
},
|
|
1387
|
+
light: {
|
|
1388
|
+
bgGradient: "bg-[#fafafa]",
|
|
1389
|
+
// 移除透明度 ff
|
|
1390
|
+
gradientColor: "#f87171",
|
|
1391
|
+
borderGradient: "border-[#f87171]",
|
|
1392
|
+
borderGradientColor: "#f87171"
|
|
1518
1393
|
}
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1394
|
+
},
|
|
1395
|
+
warning: {
|
|
1396
|
+
icon: "mi:warning",
|
|
1397
|
+
color: "text-yellow-400",
|
|
1398
|
+
className: "text-yellow-400",
|
|
1399
|
+
dark: {
|
|
1400
|
+
bgGradient: "bg-[#14181d]",
|
|
1401
|
+
// 移除透明度 f2
|
|
1402
|
+
gradientColor: "#facc15",
|
|
1403
|
+
borderGradient: "border-[#facc15]",
|
|
1404
|
+
borderGradientColor: "#facc15"
|
|
1405
|
+
},
|
|
1406
|
+
light: {
|
|
1407
|
+
bgGradient: "bg-[#fafafa]",
|
|
1408
|
+
// 移除透明度 ff
|
|
1409
|
+
gradientColor: "#f59e0b",
|
|
1410
|
+
borderGradient: "border-[#f59e0b]",
|
|
1411
|
+
borderGradientColor: "#f59e0b"
|
|
1412
|
+
}
|
|
1413
|
+
},
|
|
1414
|
+
info: {
|
|
1415
|
+
icon: "ic:outline-info",
|
|
1416
|
+
color: "text-blue-400",
|
|
1417
|
+
className: "text-blue-400",
|
|
1418
|
+
dark: {
|
|
1419
|
+
bgGradient: "bg-[#14181d]",
|
|
1420
|
+
// 移除透明度 f2
|
|
1421
|
+
gradientColor: "#60a5fa",
|
|
1422
|
+
borderGradient: "border-[#60a5fa]",
|
|
1423
|
+
borderGradientColor: "#f0f0f0"
|
|
1424
|
+
},
|
|
1425
|
+
light: {
|
|
1426
|
+
bgGradient: "bg-[#fafafa]",
|
|
1427
|
+
// 移除透明度 ff
|
|
1428
|
+
gradientColor: "#3b82f6",
|
|
1429
|
+
borderGradient: "border-[#3b82f6]",
|
|
1430
|
+
borderGradientColor: "#3b82f6"
|
|
1431
|
+
}
|
|
1432
|
+
},
|
|
1433
|
+
default: {
|
|
1434
|
+
icon: "ic:round-notifications",
|
|
1435
|
+
color: "text-gray-400",
|
|
1436
|
+
className: "text-gray-400",
|
|
1437
|
+
dark: {
|
|
1438
|
+
bgGradient: "bg-[#14181d]",
|
|
1439
|
+
// 移除透明度 f2
|
|
1440
|
+
gradientColor: "#9ca3af",
|
|
1441
|
+
borderGradient: "border-[#9ca3af]",
|
|
1442
|
+
borderGradientColor: "#9ca3af"
|
|
1443
|
+
},
|
|
1444
|
+
light: {
|
|
1445
|
+
bgGradient: "bg-[#fafafa]",
|
|
1446
|
+
// 移除透明度 ff
|
|
1447
|
+
gradientColor: "#6b7280",
|
|
1448
|
+
borderGradient: "border-[#6b7280]",
|
|
1449
|
+
borderGradientColor: "#6b7280"
|
|
1553
1450
|
}
|
|
1554
|
-
}
|
|
1555
|
-
logout() {
|
|
1556
|
-
setToken(null);
|
|
1557
|
-
this.emit();
|
|
1558
|
-
}
|
|
1559
|
-
getUser() {
|
|
1560
|
-
return parseUserFromToken(getToken());
|
|
1561
|
-
}
|
|
1562
|
-
// helper to programmatically set token (e.g., after callback handling)
|
|
1563
|
-
setToken(token) {
|
|
1564
|
-
setToken(token);
|
|
1565
|
-
this.emit();
|
|
1566
1451
|
}
|
|
1567
1452
|
};
|
|
1568
|
-
var
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
className = "",
|
|
1579
|
-
fullScreen = false
|
|
1580
|
-
}) => {
|
|
1581
|
-
const sizeClasses = {
|
|
1582
|
-
sm: "h-4 w-4",
|
|
1583
|
-
md: "h-8 w-8",
|
|
1584
|
-
lg: "h-12 w-12"
|
|
1453
|
+
var CloseButton = React5.memo(({ closeToast }) => {
|
|
1454
|
+
const { theme } = useTheme();
|
|
1455
|
+
const handleClick = useCallback4((e) => {
|
|
1456
|
+
e.preventDefault();
|
|
1457
|
+
e.stopPropagation();
|
|
1458
|
+
closeToast?.();
|
|
1459
|
+
}, [closeToast]);
|
|
1460
|
+
const getCloseButtonColor = () => {
|
|
1461
|
+
const actualTheme = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
|
|
1462
|
+
return actualTheme === "dark" ? "#b4b4b4" : "#6b7280";
|
|
1585
1463
|
};
|
|
1586
|
-
const
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
"div",
|
|
1590
|
-
{
|
|
1591
|
-
className: `animate-spin rounded-full border-2 border-gray-300 border-t-blue-600 mx-auto ${sizeClasses[size]}`
|
|
1592
|
-
}
|
|
1593
|
-
),
|
|
1594
|
-
text && /* @__PURE__ */ jsx8("p", { className: "mt-2 text-sm text-gray-600", children: text })
|
|
1595
|
-
] }) });
|
|
1596
|
-
};
|
|
1597
|
-
var LoadingSpinner = ({
|
|
1598
|
-
size = "md",
|
|
1599
|
-
className = ""
|
|
1600
|
-
}) => {
|
|
1601
|
-
const sizeClasses = {
|
|
1602
|
-
sm: "h-4 w-4",
|
|
1603
|
-
md: "h-8 w-8",
|
|
1604
|
-
lg: "h-12 w-12"
|
|
1464
|
+
const getCloseButtonHoverColor = () => {
|
|
1465
|
+
const actualTheme = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
|
|
1466
|
+
return actualTheme === "dark" ? "white" : "#374151";
|
|
1605
1467
|
};
|
|
1606
1468
|
return /* @__PURE__ */ jsx8(
|
|
1607
|
-
|
|
1469
|
+
Icon4,
|
|
1608
1470
|
{
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
this.state = { hasError: false };
|
|
1624
|
-
}
|
|
1625
|
-
static getDerivedStateFromError(error) {
|
|
1626
|
-
return { hasError: true, error };
|
|
1627
|
-
}
|
|
1628
|
-
componentDidCatch(error, errorInfo) {
|
|
1629
|
-
this.setState({
|
|
1630
|
-
error,
|
|
1631
|
-
errorInfo
|
|
1632
|
-
});
|
|
1633
|
-
this.props.onError?.(error, errorInfo);
|
|
1634
|
-
}
|
|
1635
|
-
render() {
|
|
1636
|
-
if (this.state.hasError) {
|
|
1637
|
-
if (this.props.fallback) {
|
|
1638
|
-
const FallbackComponent = this.props.fallback;
|
|
1639
|
-
return /* @__PURE__ */ jsx9(FallbackComponent, { error: this.state.error, retry: this.handleRetry });
|
|
1640
|
-
}
|
|
1641
|
-
return /* @__PURE__ */ jsx9("div", { className: "min-h-[400px] flex items-center justify-center p-4", children: /* @__PURE__ */ jsxs7("div", { className: "text-center max-w-md", children: [
|
|
1642
|
-
/* @__PURE__ */ jsx9("div", { className: "text-red-500 text-6xl mb-4", children: "\u26A0\uFE0F" }),
|
|
1643
|
-
/* @__PURE__ */ jsx9("h2", { className: "text-xl font-semibold text-gray-900 mb-2", children: "Something went wrong" }),
|
|
1644
|
-
/* @__PURE__ */ jsx9("p", { className: "text-gray-600 mb-4", children: "An unexpected error occurred. Please try refreshing the page." }),
|
|
1645
|
-
/* @__PURE__ */ jsx9(
|
|
1646
|
-
"button",
|
|
1647
|
-
{
|
|
1648
|
-
onClick: this.handleRetry,
|
|
1649
|
-
className: "px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors",
|
|
1650
|
-
children: "Try Again"
|
|
1651
|
-
}
|
|
1652
|
-
),
|
|
1653
|
-
false
|
|
1654
|
-
] }) });
|
|
1655
|
-
}
|
|
1656
|
-
return this.props.children;
|
|
1657
|
-
}
|
|
1658
|
-
};
|
|
1659
|
-
var DefaultErrorFallback = ({ retry }) => /* @__PURE__ */ jsx9("div", { className: "min-h-[200px] flex items-center justify-center p-4", children: /* @__PURE__ */ jsxs7("div", { className: "text-center", children: [
|
|
1660
|
-
/* @__PURE__ */ jsx9("div", { className: "text-red-500 text-4xl mb-2", children: "\u26A0\uFE0F" }),
|
|
1661
|
-
/* @__PURE__ */ jsx9("p", { className: "text-gray-600 mb-2", children: "Something went wrong" }),
|
|
1662
|
-
retry && /* @__PURE__ */ jsx9(
|
|
1663
|
-
"button",
|
|
1664
|
-
{
|
|
1665
|
-
onClick: retry,
|
|
1666
|
-
className: "px-3 py-1 bg-blue-600 text-white text-sm rounded hover:bg-blue-700 transition-colors",
|
|
1667
|
-
children: "Retry"
|
|
1668
|
-
}
|
|
1669
|
-
)
|
|
1670
|
-
] }) });
|
|
1671
|
-
|
|
1672
|
-
// src/components/ui/ClayxButton.tsx
|
|
1673
|
-
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1674
|
-
var getSizeClasses = (size, isIconOnly) => {
|
|
1675
|
-
if (isIconOnly) {
|
|
1676
|
-
switch (size) {
|
|
1677
|
-
case "sm":
|
|
1678
|
-
return "h-8 w-8 min-w-8 p-0";
|
|
1679
|
-
case "md":
|
|
1680
|
-
return "h-10 w-10 min-w-10 p-0";
|
|
1681
|
-
case "lg":
|
|
1682
|
-
return "h-12 w-12 min-w-12 p-0";
|
|
1683
|
-
default:
|
|
1684
|
-
return "h-10 w-10 min-w-10 p-0";
|
|
1685
|
-
}
|
|
1686
|
-
}
|
|
1687
|
-
switch (size) {
|
|
1688
|
-
case "sm":
|
|
1689
|
-
return "h-8 px-3 text-sm";
|
|
1690
|
-
case "md":
|
|
1691
|
-
return "h-10 px-4 text-base";
|
|
1692
|
-
case "lg":
|
|
1693
|
-
return "h-12 px-6 text-lg";
|
|
1694
|
-
default:
|
|
1695
|
-
return "h-10 px-4 text-base";
|
|
1696
|
-
}
|
|
1697
|
-
};
|
|
1698
|
-
var getVariantClasses = (variant) => {
|
|
1699
|
-
switch (variant) {
|
|
1700
|
-
case "solid":
|
|
1701
|
-
return "bg-primary text-white hover:bg-primary/90";
|
|
1702
|
-
case "ghost":
|
|
1703
|
-
return "bg-transparent hover:bg-white/10";
|
|
1704
|
-
case "flat":
|
|
1705
|
-
return "bg-white/5 hover:bg-white/10";
|
|
1706
|
-
default:
|
|
1707
|
-
return "";
|
|
1708
|
-
}
|
|
1709
|
-
};
|
|
1710
|
-
var ClayxButton = ({
|
|
1711
|
-
isIconOnly = false,
|
|
1712
|
-
size = "md",
|
|
1713
|
-
variant = "solid",
|
|
1714
|
-
className = "",
|
|
1715
|
-
children,
|
|
1716
|
-
disabled = false,
|
|
1717
|
-
...props
|
|
1718
|
-
}) => {
|
|
1719
|
-
const sizeClasses = getSizeClasses(size, isIconOnly);
|
|
1720
|
-
const variantClasses = getVariantClasses(variant);
|
|
1721
|
-
const baseClasses = `
|
|
1722
|
-
inline-flex items-center justify-center
|
|
1723
|
-
rounded-md font-medium
|
|
1724
|
-
transition-all duration-200
|
|
1725
|
-
focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-transparent
|
|
1726
|
-
disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none
|
|
1727
|
-
`.replace(/\s+/g, " ").trim();
|
|
1728
|
-
const combinedClasses = `${baseClasses} ${sizeClasses} ${variantClasses} ${className}`.trim();
|
|
1729
|
-
return /* @__PURE__ */ jsx10(
|
|
1730
|
-
"button",
|
|
1731
|
-
{
|
|
1732
|
-
className: combinedClasses,
|
|
1733
|
-
disabled,
|
|
1734
|
-
...props,
|
|
1735
|
-
children
|
|
1736
|
-
}
|
|
1737
|
-
);
|
|
1738
|
-
};
|
|
1739
|
-
|
|
1740
|
-
// src/components/ui/LimitUpgradeToast.tsx
|
|
1741
|
-
import React8 from "react";
|
|
1742
|
-
import { Icon as Icon5 } from "@iconify/react";
|
|
1743
|
-
|
|
1744
|
-
// src/components/ui/Toast/ClayxToast.tsx
|
|
1745
|
-
import React7, { useCallback as useCallback5 } from "react";
|
|
1746
|
-
import { Bounce, toast } from "react-toastify";
|
|
1747
|
-
import { Icon as Icon4 } from "@iconify/react";
|
|
1748
|
-
|
|
1749
|
-
// src/components/theme/ThemeToggle.tsx
|
|
1750
|
-
import * as React6 from "react";
|
|
1751
|
-
import { Icon as Icon3 } from "@iconify/react";
|
|
1752
|
-
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1753
|
-
function ThemeToggle({ className }) {
|
|
1754
|
-
const { setTheme, theme } = useTheme();
|
|
1755
|
-
const [mounted, setMounted] = React6.useState(false);
|
|
1756
|
-
React6.useEffect(() => {
|
|
1757
|
-
setMounted(true);
|
|
1758
|
-
}, []);
|
|
1759
|
-
const handleToggle = () => {
|
|
1760
|
-
if (theme === "dark") {
|
|
1761
|
-
setTheme("light");
|
|
1762
|
-
} else {
|
|
1763
|
-
setTheme("dark");
|
|
1764
|
-
}
|
|
1765
|
-
};
|
|
1766
|
-
if (!mounted) {
|
|
1767
|
-
return /* @__PURE__ */ jsx11(Icon3, { icon: "solar:sun-bold", width: 20, height: 20 });
|
|
1768
|
-
}
|
|
1769
|
-
return /* @__PURE__ */ jsx11(
|
|
1770
|
-
"div",
|
|
1771
|
-
{
|
|
1772
|
-
className: `cursor-pointer ${className || ""}`,
|
|
1773
|
-
onClick: handleToggle,
|
|
1774
|
-
children: theme === "light" ? /* @__PURE__ */ jsx11(Icon3, { icon: "solar:sun-bold", width: 20, height: 20 }) : /* @__PURE__ */ jsx11(Icon3, { icon: "solar:moon-linear", width: 20, height: 20 })
|
|
1775
|
-
}
|
|
1776
|
-
);
|
|
1777
|
-
}
|
|
1778
|
-
|
|
1779
|
-
// src/components/ui/Toast/ClayxToast.tsx
|
|
1780
|
-
import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1781
|
-
var TOAST_ICONS = {
|
|
1782
|
-
success: {
|
|
1783
|
-
icon: "mdi:success",
|
|
1784
|
-
color: "text-green-400",
|
|
1785
|
-
className: "text-green-400",
|
|
1786
|
-
// 深色主题配置
|
|
1787
|
-
dark: {
|
|
1788
|
-
bgGradient: "bg-[#14181d]",
|
|
1789
|
-
// 移除透明度 f2
|
|
1790
|
-
gradientColor: "#389726",
|
|
1791
|
-
borderGradient: "border-[#389726]",
|
|
1792
|
-
borderGradientColor: "#389726"
|
|
1793
|
-
},
|
|
1794
|
-
// 浅色主题配置
|
|
1795
|
-
light: {
|
|
1796
|
-
bgGradient: "bg-[#fafafa]",
|
|
1797
|
-
// 移除透明度 ff
|
|
1798
|
-
gradientColor: "#22c55e",
|
|
1799
|
-
borderGradient: "border-[#22c55e]",
|
|
1800
|
-
borderGradientColor: "#22c55e"
|
|
1801
|
-
}
|
|
1802
|
-
},
|
|
1803
|
-
error: {
|
|
1804
|
-
icon: "ic:outline-close",
|
|
1805
|
-
color: "text-red-400",
|
|
1806
|
-
className: "text-red-400",
|
|
1807
|
-
dark: {
|
|
1808
|
-
bgGradient: "bg-[#14181d]",
|
|
1809
|
-
// 移除透明度 f2
|
|
1810
|
-
gradientColor: "#ef4444",
|
|
1811
|
-
borderGradient: "border-[#ef4444]",
|
|
1812
|
-
borderGradientColor: "#ef4444"
|
|
1813
|
-
},
|
|
1814
|
-
light: {
|
|
1815
|
-
bgGradient: "bg-[#fafafa]",
|
|
1816
|
-
// 移除透明度 ff
|
|
1817
|
-
gradientColor: "#f87171",
|
|
1818
|
-
borderGradient: "border-[#f87171]",
|
|
1819
|
-
borderGradientColor: "#f87171"
|
|
1820
|
-
}
|
|
1821
|
-
},
|
|
1822
|
-
warning: {
|
|
1823
|
-
icon: "mi:warning",
|
|
1824
|
-
color: "text-yellow-400",
|
|
1825
|
-
className: "text-yellow-400",
|
|
1826
|
-
dark: {
|
|
1827
|
-
bgGradient: "bg-[#14181d]",
|
|
1828
|
-
// 移除透明度 f2
|
|
1829
|
-
gradientColor: "#facc15",
|
|
1830
|
-
borderGradient: "border-[#facc15]",
|
|
1831
|
-
borderGradientColor: "#facc15"
|
|
1832
|
-
},
|
|
1833
|
-
light: {
|
|
1834
|
-
bgGradient: "bg-[#fafafa]",
|
|
1835
|
-
// 移除透明度 ff
|
|
1836
|
-
gradientColor: "#f59e0b",
|
|
1837
|
-
borderGradient: "border-[#f59e0b]",
|
|
1838
|
-
borderGradientColor: "#f59e0b"
|
|
1839
|
-
}
|
|
1840
|
-
},
|
|
1841
|
-
info: {
|
|
1842
|
-
icon: "ic:outline-info",
|
|
1843
|
-
color: "text-blue-400",
|
|
1844
|
-
className: "text-blue-400",
|
|
1845
|
-
dark: {
|
|
1846
|
-
bgGradient: "bg-[#14181d]",
|
|
1847
|
-
// 移除透明度 f2
|
|
1848
|
-
gradientColor: "#60a5fa",
|
|
1849
|
-
borderGradient: "border-[#60a5fa]",
|
|
1850
|
-
borderGradientColor: "#f0f0f0"
|
|
1851
|
-
},
|
|
1852
|
-
light: {
|
|
1853
|
-
bgGradient: "bg-[#fafafa]",
|
|
1854
|
-
// 移除透明度 ff
|
|
1855
|
-
gradientColor: "#3b82f6",
|
|
1856
|
-
borderGradient: "border-[#3b82f6]",
|
|
1857
|
-
borderGradientColor: "#3b82f6"
|
|
1858
|
-
}
|
|
1859
|
-
},
|
|
1860
|
-
default: {
|
|
1861
|
-
icon: "ic:round-notifications",
|
|
1862
|
-
color: "text-gray-400",
|
|
1863
|
-
className: "text-gray-400",
|
|
1864
|
-
dark: {
|
|
1865
|
-
bgGradient: "bg-[#14181d]",
|
|
1866
|
-
// 移除透明度 f2
|
|
1867
|
-
gradientColor: "#9ca3af",
|
|
1868
|
-
borderGradient: "border-[#9ca3af]",
|
|
1869
|
-
borderGradientColor: "#9ca3af"
|
|
1870
|
-
},
|
|
1871
|
-
light: {
|
|
1872
|
-
bgGradient: "bg-[#fafafa]",
|
|
1873
|
-
// 移除透明度 ff
|
|
1874
|
-
gradientColor: "#6b7280",
|
|
1875
|
-
borderGradient: "border-[#6b7280]",
|
|
1876
|
-
borderGradientColor: "#6b7280"
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1879
|
-
};
|
|
1880
|
-
var CloseButton = React7.memo(({ closeToast }) => {
|
|
1881
|
-
const { theme } = useTheme();
|
|
1882
|
-
const handleClick = useCallback5((e) => {
|
|
1883
|
-
e.preventDefault();
|
|
1884
|
-
e.stopPropagation();
|
|
1885
|
-
closeToast?.();
|
|
1886
|
-
}, [closeToast]);
|
|
1887
|
-
const getCloseButtonColor = () => {
|
|
1888
|
-
const actualTheme = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
|
|
1889
|
-
return actualTheme === "dark" ? "#b4b4b4" : "#6b7280";
|
|
1890
|
-
};
|
|
1891
|
-
const getCloseButtonHoverColor = () => {
|
|
1892
|
-
const actualTheme = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
|
|
1893
|
-
return actualTheme === "dark" ? "white" : "#374151";
|
|
1894
|
-
};
|
|
1895
|
-
return /* @__PURE__ */ jsx12(
|
|
1896
|
-
Icon4,
|
|
1897
|
-
{
|
|
1898
|
-
icon: "vaadin:close",
|
|
1899
|
-
className: "flex items-center justify-center rounded-full relative z-10 flex-shrink-0 cursor-pointer \n transition-colors duration-200 drop-shadow-sm",
|
|
1900
|
-
onClick: handleClick,
|
|
1901
|
-
width: 14,
|
|
1902
|
-
height: 14,
|
|
1903
|
-
style: {
|
|
1904
|
-
color: getCloseButtonColor()
|
|
1905
|
-
},
|
|
1906
|
-
onMouseEnter: (e) => {
|
|
1907
|
-
e.currentTarget.style.color = getCloseButtonHoverColor();
|
|
1908
|
-
},
|
|
1909
|
-
onMouseLeave: (e) => {
|
|
1910
|
-
e.currentTarget.style.color = getCloseButtonColor();
|
|
1911
|
-
}
|
|
1471
|
+
icon: "vaadin:close",
|
|
1472
|
+
className: "flex items-center justify-center rounded-full relative z-10 flex-shrink-0 cursor-pointer \n transition-colors duration-200 drop-shadow-sm",
|
|
1473
|
+
onClick: handleClick,
|
|
1474
|
+
width: 14,
|
|
1475
|
+
height: 14,
|
|
1476
|
+
style: {
|
|
1477
|
+
color: getCloseButtonColor()
|
|
1478
|
+
},
|
|
1479
|
+
onMouseEnter: (e) => {
|
|
1480
|
+
e.currentTarget.style.color = getCloseButtonHoverColor();
|
|
1481
|
+
},
|
|
1482
|
+
onMouseLeave: (e) => {
|
|
1483
|
+
e.currentTarget.style.color = getCloseButtonColor();
|
|
1484
|
+
}
|
|
1912
1485
|
}
|
|
1913
1486
|
);
|
|
1914
1487
|
});
|
|
@@ -1916,7 +1489,7 @@ CloseButton.displayName = "CloseButton";
|
|
|
1916
1489
|
var ToastContent = ({ type, title, message, component, closeToast }) => {
|
|
1917
1490
|
const iconConfig = TOAST_ICONS[type];
|
|
1918
1491
|
const { theme } = useTheme();
|
|
1919
|
-
const handleClose =
|
|
1492
|
+
const handleClose = useCallback4(() => {
|
|
1920
1493
|
closeToast?.();
|
|
1921
1494
|
}, [closeToast]);
|
|
1922
1495
|
const getTextColor = () => {
|
|
@@ -1941,13 +1514,13 @@ var ToastContent = ({ type, title, message, component, closeToast }) => {
|
|
|
1941
1514
|
// gray-50
|
|
1942
1515
|
};
|
|
1943
1516
|
if (component) {
|
|
1944
|
-
return /* @__PURE__ */
|
|
1945
|
-
/* @__PURE__ */
|
|
1946
|
-
/* @__PURE__ */
|
|
1517
|
+
return /* @__PURE__ */ jsxs5("div", { className: `flex items-start gap-3 !min-h-[90px] w-full backdrop-blur-md p-4 shadow-2xl overflow-hidden ${themeConfig.bgGradient}`, children: [
|
|
1518
|
+
/* @__PURE__ */ jsx8("div", { className: "flex-1 relative z-10", children: component }),
|
|
1519
|
+
/* @__PURE__ */ jsx8("div", { className: "relative z-10", children: /* @__PURE__ */ jsx8(CloseButton, { closeToast: handleClose }) })
|
|
1947
1520
|
] });
|
|
1948
1521
|
}
|
|
1949
|
-
return /* @__PURE__ */
|
|
1950
|
-
/* @__PURE__ */
|
|
1522
|
+
return /* @__PURE__ */ jsxs5("div", { className: `flex items-start gap-3 !min-h-[90px] w-full backdrop-blur-md p-4 shadow-2xl relative overflow-hidden ${themeConfig.bgGradient}`, children: [
|
|
1523
|
+
/* @__PURE__ */ jsx8(
|
|
1951
1524
|
"div",
|
|
1952
1525
|
{
|
|
1953
1526
|
className: "absolute left-0 top-0 w-full h-full rounded-xl",
|
|
@@ -1957,7 +1530,7 @@ var ToastContent = ({ type, title, message, component, closeToast }) => {
|
|
|
1957
1530
|
}
|
|
1958
1531
|
}
|
|
1959
1532
|
),
|
|
1960
|
-
/* @__PURE__ */
|
|
1533
|
+
/* @__PURE__ */ jsx8(
|
|
1961
1534
|
"div",
|
|
1962
1535
|
{
|
|
1963
1536
|
className: "absolute left-0 top-0 w-full h-full pointer-events-none rounded-xl",
|
|
@@ -1967,133 +1540,716 @@ var ToastContent = ({ type, title, message, component, closeToast }) => {
|
|
|
1967
1540
|
}
|
|
1968
1541
|
}
|
|
1969
1542
|
),
|
|
1970
|
-
/* @__PURE__ */
|
|
1543
|
+
/* @__PURE__ */ jsx8(
|
|
1544
|
+
"div",
|
|
1545
|
+
{
|
|
1546
|
+
className: "absolute left-0 top-0 w-full h-full pointer-events-none rounded-xl",
|
|
1547
|
+
style: {
|
|
1548
|
+
border: "2px solid transparent",
|
|
1549
|
+
backgroundImage: theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches ? `linear-gradient(135deg, ${themeConfig.borderGradientColor}60 0%, ${themeConfig.borderGradientColor}40 5%, transparent 22%)` : `linear-gradient(135deg, ${themeConfig.borderGradientColor}99 0%, ${themeConfig.borderGradientColor}66 5%, transparent 22%)`,
|
|
1550
|
+
backgroundOrigin: "border-box",
|
|
1551
|
+
backgroundClip: "border-box",
|
|
1552
|
+
WebkitMask: "linear-gradient(#ffffff 0 0) padding-box, linear-gradient(#ffffff 0 0)",
|
|
1553
|
+
WebkitMaskComposite: "xor",
|
|
1554
|
+
zIndex: 0
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
),
|
|
1558
|
+
/* @__PURE__ */ jsx8("div", { className: "flex-shrink-0 flex-grow-0 mt-0.5 relative z-10", children: /* @__PURE__ */ jsx8(
|
|
1559
|
+
"div",
|
|
1560
|
+
{
|
|
1561
|
+
className: "backdrop-blur-sm rounded-full flex items-center justify-center overflow-hidden flex-shrink-0 flex-grow-0",
|
|
1562
|
+
style: {
|
|
1563
|
+
backgroundColor: theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.05)",
|
|
1564
|
+
width: "28px",
|
|
1565
|
+
height: "28px"
|
|
1566
|
+
},
|
|
1567
|
+
children: /* @__PURE__ */ jsx8("div", { className: "rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsx8(
|
|
1568
|
+
Icon4,
|
|
1569
|
+
{
|
|
1570
|
+
icon: iconConfig.icon,
|
|
1571
|
+
width: 16,
|
|
1572
|
+
height: 16,
|
|
1573
|
+
className: `flex-shrink-0`,
|
|
1574
|
+
style: {
|
|
1575
|
+
color: themeConfig.gradientColor,
|
|
1576
|
+
display: "block"
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
) })
|
|
1580
|
+
}
|
|
1581
|
+
) }),
|
|
1582
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-1 flex-1 relative z-10", children: [
|
|
1583
|
+
title && /* @__PURE__ */ jsx8(
|
|
1584
|
+
"div",
|
|
1585
|
+
{
|
|
1586
|
+
className: "text-[16px] font-semibold leading-tight drop-shadow-sm",
|
|
1587
|
+
style: {
|
|
1588
|
+
color: getTextColor(),
|
|
1589
|
+
backgroundClip: "text"
|
|
1590
|
+
},
|
|
1591
|
+
children: title
|
|
1592
|
+
}
|
|
1593
|
+
),
|
|
1594
|
+
message && /* @__PURE__ */ jsx8(
|
|
1595
|
+
"div",
|
|
1596
|
+
{
|
|
1597
|
+
className: "text-[13px] font-normal leading-relaxed drop-shadow-sm",
|
|
1598
|
+
style: {
|
|
1599
|
+
color: getTextColor(),
|
|
1600
|
+
backgroundClip: "text"
|
|
1601
|
+
},
|
|
1602
|
+
children: message
|
|
1603
|
+
}
|
|
1604
|
+
)
|
|
1605
|
+
] }),
|
|
1606
|
+
/* @__PURE__ */ jsx8("div", { className: "relative z-10", children: /* @__PURE__ */ jsx8(CloseButton, { closeToast: handleClose }) })
|
|
1607
|
+
] });
|
|
1608
|
+
};
|
|
1609
|
+
var defaultToastOptions = {
|
|
1610
|
+
position: "bottom-right",
|
|
1611
|
+
autoClose: 1500,
|
|
1612
|
+
hideProgressBar: true,
|
|
1613
|
+
closeOnClick: false,
|
|
1614
|
+
pauseOnHover: true,
|
|
1615
|
+
draggable: true,
|
|
1616
|
+
pauseOnFocusLoss: false,
|
|
1617
|
+
transition: Bounce
|
|
1618
|
+
};
|
|
1619
|
+
var getToastifyTheme = () => {
|
|
1620
|
+
if (typeof window !== "undefined") {
|
|
1621
|
+
const root = document.documentElement;
|
|
1622
|
+
if (root.classList.contains("dark")) return "dark";
|
|
1623
|
+
if (root.classList.contains("light")) return "light";
|
|
1624
|
+
return window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
1625
|
+
}
|
|
1626
|
+
return "light";
|
|
1627
|
+
};
|
|
1628
|
+
var createToast = (type) => {
|
|
1629
|
+
return (params) => {
|
|
1630
|
+
const { title, message, component, options } = params;
|
|
1631
|
+
toast(
|
|
1632
|
+
({ closeToast }) => {
|
|
1633
|
+
if (params.render) return params.render(closeToast);
|
|
1634
|
+
return /* @__PURE__ */ jsx8(
|
|
1635
|
+
ToastContent,
|
|
1636
|
+
{
|
|
1637
|
+
type,
|
|
1638
|
+
title,
|
|
1639
|
+
message: message || "",
|
|
1640
|
+
component,
|
|
1641
|
+
closeToast
|
|
1642
|
+
}
|
|
1643
|
+
);
|
|
1644
|
+
},
|
|
1645
|
+
{
|
|
1646
|
+
...defaultToastOptions,
|
|
1647
|
+
...options,
|
|
1648
|
+
theme: getToastifyTheme(),
|
|
1649
|
+
// 确保圆角样式不被覆盖,添加 rounded-xl 类
|
|
1650
|
+
className: "!p-0 !shadow-none !rounded-xl",
|
|
1651
|
+
style: { padding: 0, borderRadius: "0.75rem", backgroundColor: "transparent" }
|
|
1652
|
+
}
|
|
1653
|
+
);
|
|
1654
|
+
};
|
|
1655
|
+
};
|
|
1656
|
+
var ClayxToast = {
|
|
1657
|
+
success: createToast("success"),
|
|
1658
|
+
error: createToast("error"),
|
|
1659
|
+
warning: createToast("warning"),
|
|
1660
|
+
info: createToast("info"),
|
|
1661
|
+
default: createToast("default")
|
|
1662
|
+
};
|
|
1663
|
+
|
|
1664
|
+
// src/components/auth/HowoneProvider.tsx
|
|
1665
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1666
|
+
var HowoneContext = createContext2(null);
|
|
1667
|
+
var redirectOverlayStylesInjected = false;
|
|
1668
|
+
var injectRedirectOverlayStyles = () => {
|
|
1669
|
+
if (redirectOverlayStylesInjected || typeof document === "undefined") return;
|
|
1670
|
+
const style = document.createElement("style");
|
|
1671
|
+
style.setAttribute("data-howone-auth-overlay", "true");
|
|
1672
|
+
style.textContent = `
|
|
1673
|
+
@keyframes howone-logo-pulse {
|
|
1674
|
+
0%, 100% {
|
|
1675
|
+
opacity: 0.2;
|
|
1676
|
+
transform: scale(0.95);
|
|
1677
|
+
filter: drop-shadow(0 0 0 rgba(255, 255, 255, 0.2));
|
|
1678
|
+
}
|
|
1679
|
+
50% {
|
|
1680
|
+
opacity: 1;
|
|
1681
|
+
transform: scale(1.03);
|
|
1682
|
+
filter: drop-shadow(0 0 28px rgba(255, 255, 255, 0.55));
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
@keyframes howone-glow-ring {
|
|
1687
|
+
0%, 100% {
|
|
1688
|
+
opacity: 0.12;
|
|
1689
|
+
transform: scale(0.85);
|
|
1690
|
+
}
|
|
1691
|
+
50% {
|
|
1692
|
+
opacity: 0.42;
|
|
1693
|
+
transform: scale(1.05);
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
[data-howone-auth-overlay-root] {
|
|
1698
|
+
position: fixed;
|
|
1699
|
+
inset: 0;
|
|
1700
|
+
z-index: 2147483646;
|
|
1701
|
+
display: flex;
|
|
1702
|
+
flex-direction: column;
|
|
1703
|
+
align-items: center;
|
|
1704
|
+
justify-content: center;
|
|
1705
|
+
width: 100vw;
|
|
1706
|
+
height: 100vh;
|
|
1707
|
+
color: #ffffff;
|
|
1708
|
+
background: rgba(0, 0, 0, 0.65);
|
|
1709
|
+
backdrop-filter: blur(6px);
|
|
1710
|
+
-webkit-backdrop-filter: blur(6px);
|
|
1711
|
+
text-align: center;
|
|
1712
|
+
}
|
|
1713
|
+
`;
|
|
1714
|
+
document.head.appendChild(style);
|
|
1715
|
+
redirectOverlayStylesInjected = true;
|
|
1716
|
+
};
|
|
1717
|
+
var HowOneProvider = ({
|
|
1718
|
+
children,
|
|
1719
|
+
showFloatingButton = true,
|
|
1720
|
+
projectId,
|
|
1721
|
+
defaultTheme = "system",
|
|
1722
|
+
themeStorageKey = "howone-theme",
|
|
1723
|
+
forceDefaultTheme = false,
|
|
1724
|
+
redirectOnUnauthenticated = false
|
|
1725
|
+
}) => {
|
|
1726
|
+
const [user, setUser] = useState8(() => parseUserFromToken(getToken()));
|
|
1727
|
+
const [token, setTokenState] = useState8(() => getToken());
|
|
1728
|
+
const [hasCheckedUrlToken, setHasCheckedUrlToken] = useState8(false);
|
|
1729
|
+
const [pendingRedirect, setPendingRedirect] = useState8(false);
|
|
1730
|
+
const [isGuest, setIsGuest] = useState8(false);
|
|
1731
|
+
useEffect7(() => {
|
|
1732
|
+
try {
|
|
1733
|
+
const params = new URLSearchParams(window.location.search);
|
|
1734
|
+
let urlToken = params.get("access_token") || params.get("token");
|
|
1735
|
+
if (!urlToken && window.location.hash) {
|
|
1736
|
+
const hashParams = new URLSearchParams(window.location.hash.slice(1));
|
|
1737
|
+
urlToken = hashParams.get("access_token") || hashParams.get("token");
|
|
1738
|
+
}
|
|
1739
|
+
if (urlToken) {
|
|
1740
|
+
setToken(urlToken);
|
|
1741
|
+
setTokenState(urlToken);
|
|
1742
|
+
setUser(parseUserFromToken(urlToken));
|
|
1743
|
+
params.delete("access_token");
|
|
1744
|
+
params.delete("token");
|
|
1745
|
+
params.delete("project_id");
|
|
1746
|
+
const newSearch = params.toString();
|
|
1747
|
+
const newUrl = window.location.pathname + (newSearch ? "?" + newSearch : "");
|
|
1748
|
+
window.history.replaceState({}, "", newUrl);
|
|
1749
|
+
}
|
|
1750
|
+
} catch (e) {
|
|
1751
|
+
console.error("[HowOneProvider] Failed to capture token from URL:", e);
|
|
1752
|
+
} finally {
|
|
1753
|
+
setHasCheckedUrlToken(true);
|
|
1754
|
+
}
|
|
1755
|
+
}, []);
|
|
1756
|
+
const resolvedAuthUrl = useMemo(() => {
|
|
1757
|
+
const env3 = getGlobalEnvironment() ?? "dev";
|
|
1758
|
+
switch (env3) {
|
|
1759
|
+
case "local":
|
|
1760
|
+
return "http://localhost:3000/auth";
|
|
1761
|
+
case "prod":
|
|
1762
|
+
return "https://howone.ai/auth";
|
|
1763
|
+
case "dev":
|
|
1764
|
+
default:
|
|
1765
|
+
return "https://howone.dev/auth";
|
|
1766
|
+
}
|
|
1767
|
+
}, []);
|
|
1768
|
+
useEffect7(() => {
|
|
1769
|
+
if (pendingRedirect) {
|
|
1770
|
+
injectRedirectOverlayStyles();
|
|
1771
|
+
}
|
|
1772
|
+
}, [pendingRedirect]);
|
|
1773
|
+
useEffect7(() => {
|
|
1774
|
+
if (pendingRedirect) {
|
|
1775
|
+
injectRedirectOverlayStyles();
|
|
1776
|
+
}
|
|
1777
|
+
}, [pendingRedirect]);
|
|
1778
|
+
const redirectToAuth = useCallback5(() => {
|
|
1779
|
+
if (!redirectOnUnauthenticated || typeof window === "undefined") return;
|
|
1780
|
+
const activeProjectId = projectId ?? getDefaultProjectId();
|
|
1781
|
+
const navigateToResolvedAuth = () => {
|
|
1782
|
+
setPendingRedirect(true);
|
|
1783
|
+
requestAnimationFrame(() => {
|
|
1784
|
+
if (activeProjectId) {
|
|
1785
|
+
try {
|
|
1786
|
+
const url = new URL(resolvedAuthUrl);
|
|
1787
|
+
url.searchParams.set("redirect_uri", window.location.origin);
|
|
1788
|
+
url.searchParams.set("project_id", activeProjectId);
|
|
1789
|
+
window.location.href = url.toString();
|
|
1790
|
+
return;
|
|
1791
|
+
} catch (error) {
|
|
1792
|
+
console.error("[HowOneProvider] Failed to attach project_id to auth URL:", error);
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
window.location.href = resolvedAuthUrl;
|
|
1796
|
+
});
|
|
1797
|
+
};
|
|
1798
|
+
try {
|
|
1799
|
+
const currentUrl = new URL(window.location.href);
|
|
1800
|
+
if (currentUrl.pathname.includes("/auth")) return;
|
|
1801
|
+
try {
|
|
1802
|
+
const authUrlObj = new URL(resolvedAuthUrl);
|
|
1803
|
+
authUrlObj.searchParams.set("redirect_uri", window.location.origin);
|
|
1804
|
+
if (activeProjectId) {
|
|
1805
|
+
authUrlObj.searchParams.set("project_id", activeProjectId);
|
|
1806
|
+
}
|
|
1807
|
+
setPendingRedirect(true);
|
|
1808
|
+
requestAnimationFrame(() => {
|
|
1809
|
+
window.location.href = authUrlObj.toString();
|
|
1810
|
+
});
|
|
1811
|
+
return;
|
|
1812
|
+
} catch (error) {
|
|
1813
|
+
console.error("[HowOneProvider] Failed to build auth URL:", error);
|
|
1814
|
+
}
|
|
1815
|
+
navigateToResolvedAuth();
|
|
1816
|
+
} catch {
|
|
1817
|
+
navigateToResolvedAuth();
|
|
1818
|
+
}
|
|
1819
|
+
}, [redirectOnUnauthenticated, resolvedAuthUrl, projectId]);
|
|
1820
|
+
useEffect7(() => {
|
|
1821
|
+
if (!hasCheckedUrlToken) return;
|
|
1822
|
+
const guestMode = isGuestMode() || !!getExistingSessionId();
|
|
1823
|
+
setIsGuest(guestMode);
|
|
1824
|
+
if (token || user || guestMode) {
|
|
1825
|
+
return;
|
|
1826
|
+
}
|
|
1827
|
+
redirectToAuth();
|
|
1828
|
+
}, [token, user, hasCheckedUrlToken, redirectToAuth]);
|
|
1829
|
+
useEffect7(() => {
|
|
1830
|
+
if (!hasCheckedUrlToken || !token || !user) return;
|
|
1831
|
+
const migrateGuestData = async () => {
|
|
1832
|
+
try {
|
|
1833
|
+
const guestSessionId = getExistingSessionId();
|
|
1834
|
+
if (!guestSessionId) return;
|
|
1835
|
+
const activeProjectId = projectId ?? getDefaultProjectId();
|
|
1836
|
+
if (!activeProjectId) {
|
|
1837
|
+
console.warn("[HowOneProvider] No projectId available for guest data migration");
|
|
1838
|
+
return;
|
|
1839
|
+
}
|
|
1840
|
+
const baseUrl = getEnvs().baseUrl;
|
|
1841
|
+
const response = await fetch(
|
|
1842
|
+
`${baseUrl}/entities/apps/${activeProjectId}/migrate-guest-data`,
|
|
1843
|
+
{
|
|
1844
|
+
method: "POST",
|
|
1845
|
+
headers: {
|
|
1846
|
+
"Content-Type": "application/json",
|
|
1847
|
+
"Authorization": `Bearer ${token}`
|
|
1848
|
+
},
|
|
1849
|
+
body: JSON.stringify({ guestSessionId })
|
|
1850
|
+
}
|
|
1851
|
+
);
|
|
1852
|
+
if (response.ok) {
|
|
1853
|
+
const result = await response.json();
|
|
1854
|
+
console.log("[HowOneProvider] Guest data migration result:", result);
|
|
1855
|
+
clearGuestSession();
|
|
1856
|
+
setIsGuest(false);
|
|
1857
|
+
if (result.totalCount > 0) {
|
|
1858
|
+
const entityList = result.details?.map((d) => `${d.entityName} (${d.count})`).join(", ") || "";
|
|
1859
|
+
ClayxToast.success({
|
|
1860
|
+
title: "Data Synced",
|
|
1861
|
+
message: `Migrated ${result.totalCount} records${entityList ? `: ${entityList}` : ""}`
|
|
1862
|
+
});
|
|
1863
|
+
}
|
|
1864
|
+
} else {
|
|
1865
|
+
console.error("[HowOneProvider] Guest data migration failed:", response.status);
|
|
1866
|
+
}
|
|
1867
|
+
} catch (error) {
|
|
1868
|
+
console.error("[HowOneProvider] Failed to migrate guest data:", error);
|
|
1869
|
+
}
|
|
1870
|
+
};
|
|
1871
|
+
migrateGuestData();
|
|
1872
|
+
}, [token, user, hasCheckedUrlToken, projectId]);
|
|
1873
|
+
const logout = () => {
|
|
1874
|
+
try {
|
|
1875
|
+
setToken(null);
|
|
1876
|
+
} catch {
|
|
1877
|
+
}
|
|
1878
|
+
setTokenState(null);
|
|
1879
|
+
setUser(null);
|
|
1880
|
+
redirectToAuth();
|
|
1881
|
+
};
|
|
1882
|
+
const value = {
|
|
1883
|
+
user,
|
|
1884
|
+
token,
|
|
1885
|
+
isAuthenticated: hasCheckedUrlToken && (!!token || isGuest),
|
|
1886
|
+
isGuest,
|
|
1887
|
+
logout
|
|
1888
|
+
};
|
|
1889
|
+
if (!hasCheckedUrlToken) return null;
|
|
1890
|
+
return /* @__PURE__ */ jsxs6(
|
|
1891
|
+
ThemeProvider,
|
|
1892
|
+
{
|
|
1893
|
+
defaultTheme,
|
|
1894
|
+
storageKey: themeStorageKey,
|
|
1895
|
+
forceDefault: forceDefaultTheme,
|
|
1896
|
+
children: [
|
|
1897
|
+
/* @__PURE__ */ jsx9(ElementSelectorProvider, { children: /* @__PURE__ */ jsxs6(HowoneContext.Provider, { value, children: [
|
|
1898
|
+
children,
|
|
1899
|
+
showFloatingButton && /* @__PURE__ */ jsx9(FloatingButton, { onClick: () => window.open("https://howone.ai", "_blank") }),
|
|
1900
|
+
pendingRedirect && /* @__PURE__ */ jsx9(
|
|
1901
|
+
"div",
|
|
1902
|
+
{
|
|
1903
|
+
"data-howone-auth-overlay-root": true,
|
|
1904
|
+
className: "fixed inset-0 z-[100000] h-full w-full flex flex-col items-center justify-center bg-black/65 backdrop-blur-sm text-white",
|
|
1905
|
+
children: /* @__PURE__ */ jsxs6("div", { className: "relative mt-6 flex h-[220px] w-[220px] items-center justify-center", children: [
|
|
1906
|
+
/* @__PURE__ */ jsx9(
|
|
1907
|
+
"div",
|
|
1908
|
+
{
|
|
1909
|
+
className: "absolute inset-0 rounded-full bg-white/20",
|
|
1910
|
+
style: { animation: "howone-glow-ring 2.4s ease-in-out infinite" }
|
|
1911
|
+
}
|
|
1912
|
+
),
|
|
1913
|
+
/* @__PURE__ */ jsx9("div", { className: "absolute inset-0 rounded-full bg-gradient-to-br from-white/10 via-white/25 to-white/10 blur-2xl" }),
|
|
1914
|
+
/* @__PURE__ */ jsx9(
|
|
1915
|
+
"img",
|
|
1916
|
+
{
|
|
1917
|
+
style: { width: 250, animation: "howone-logo-pulse 2s ease-in-out infinite" },
|
|
1918
|
+
src: "https://sxwxqoixnnklnpeutjrj.supabase.co/storage/v1/object/public/create-x/logo/logo.svg",
|
|
1919
|
+
alt: "HowOne"
|
|
1920
|
+
}
|
|
1921
|
+
)
|
|
1922
|
+
] })
|
|
1923
|
+
}
|
|
1924
|
+
)
|
|
1925
|
+
] }) }),
|
|
1926
|
+
/* @__PURE__ */ jsx9(GlobalToastContainer, {})
|
|
1927
|
+
]
|
|
1928
|
+
}
|
|
1929
|
+
);
|
|
1930
|
+
};
|
|
1931
|
+
function useHowoneContext() {
|
|
1932
|
+
const ctx = useContext2(HowoneContext);
|
|
1933
|
+
if (!ctx) {
|
|
1934
|
+
const t = getToken();
|
|
1935
|
+
const guestMode = isGuestMode() || !!getExistingSessionId();
|
|
1936
|
+
return {
|
|
1937
|
+
user: parseUserFromToken(t),
|
|
1938
|
+
token: t,
|
|
1939
|
+
isAuthenticated: !!t || guestMode,
|
|
1940
|
+
isGuest: guestMode,
|
|
1941
|
+
logout: () => {
|
|
1942
|
+
try {
|
|
1943
|
+
setToken(null);
|
|
1944
|
+
} catch {
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
};
|
|
1948
|
+
}
|
|
1949
|
+
return ctx;
|
|
1950
|
+
}
|
|
1951
|
+
|
|
1952
|
+
// src/components/index.ts
|
|
1953
|
+
init_auth();
|
|
1954
|
+
|
|
1955
|
+
// src/howone/client.ts
|
|
1956
|
+
init_auth();
|
|
1957
|
+
init_config();
|
|
1958
|
+
var HowoneAuthClient = class {
|
|
1959
|
+
constructor() {
|
|
1960
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
1961
|
+
this.loading = false;
|
|
1962
|
+
}
|
|
1963
|
+
emit() {
|
|
1964
|
+
const state = {
|
|
1965
|
+
user: parseUserFromToken(getToken()),
|
|
1966
|
+
isLoading: this.loading
|
|
1967
|
+
};
|
|
1968
|
+
for (const l of this.listeners) {
|
|
1969
|
+
try {
|
|
1970
|
+
l(state);
|
|
1971
|
+
} catch (e) {
|
|
1972
|
+
void e;
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
onAuthStateChanged(listener) {
|
|
1977
|
+
this.listeners.add(listener);
|
|
1978
|
+
try {
|
|
1979
|
+
listener({ user: parseUserFromToken(getToken()), isLoading: this.loading });
|
|
1980
|
+
} catch (e) {
|
|
1981
|
+
void e;
|
|
1982
|
+
}
|
|
1983
|
+
return () => {
|
|
1984
|
+
this.listeners.delete(listener);
|
|
1985
|
+
};
|
|
1986
|
+
}
|
|
1987
|
+
// Simple redirect-based login trigger (consumer can override)
|
|
1988
|
+
login() {
|
|
1989
|
+
const root = getEnvs().AUTH_ROOT_VALUE;
|
|
1990
|
+
try {
|
|
1991
|
+
const loc = window.location.href;
|
|
1992
|
+
const authUrl = new URL("/auth", String(root));
|
|
1993
|
+
authUrl.searchParams.set("redirect_uri", String(loc));
|
|
1994
|
+
try {
|
|
1995
|
+
const cfg = (init_config(), __toCommonJS(config_exports));
|
|
1996
|
+
const pid = cfg.getDefaultProjectId && cfg.getDefaultProjectId();
|
|
1997
|
+
if (pid) authUrl.searchParams.set("project_id", String(pid));
|
|
1998
|
+
} catch {
|
|
1999
|
+
}
|
|
2000
|
+
try {
|
|
2001
|
+
if (window.top && window.top !== window) {
|
|
2002
|
+
window.top.location.replace(authUrl.toString());
|
|
2003
|
+
} else {
|
|
2004
|
+
window.location.replace(authUrl.toString());
|
|
2005
|
+
}
|
|
2006
|
+
} catch {
|
|
2007
|
+
try {
|
|
2008
|
+
window.location.replace(String(root));
|
|
2009
|
+
} catch {
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
2012
|
+
} catch {
|
|
2013
|
+
try {
|
|
2014
|
+
window.location.replace(String(root));
|
|
2015
|
+
} catch {
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
logout() {
|
|
2020
|
+
setToken(null);
|
|
2021
|
+
this.emit();
|
|
2022
|
+
}
|
|
2023
|
+
getUser() {
|
|
2024
|
+
return parseUserFromToken(getToken());
|
|
2025
|
+
}
|
|
2026
|
+
// helper to programmatically set token (e.g., after callback handling)
|
|
2027
|
+
setToken(token) {
|
|
2028
|
+
setToken(token);
|
|
2029
|
+
this.emit();
|
|
2030
|
+
}
|
|
2031
|
+
};
|
|
2032
|
+
var howone = {
|
|
2033
|
+
auth: new HowoneAuthClient()
|
|
2034
|
+
};
|
|
2035
|
+
var client_default = howone;
|
|
2036
|
+
|
|
2037
|
+
// src/components/ui/Loading.tsx
|
|
2038
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2039
|
+
var Loading = ({
|
|
2040
|
+
size = "md",
|
|
2041
|
+
text = "Loading...",
|
|
2042
|
+
className = "",
|
|
2043
|
+
fullScreen = false
|
|
2044
|
+
}) => {
|
|
2045
|
+
const sizeClasses = {
|
|
2046
|
+
sm: "h-4 w-4",
|
|
2047
|
+
md: "h-8 w-8",
|
|
2048
|
+
lg: "h-12 w-12"
|
|
2049
|
+
};
|
|
2050
|
+
const containerClasses = fullScreen ? "fixed inset-0 flex items-center justify-center bg-white/80 backdrop-blur-sm z-50" : "flex items-center justify-center p-4";
|
|
2051
|
+
return /* @__PURE__ */ jsx10("div", { className: `${containerClasses} ${className}`, children: /* @__PURE__ */ jsxs7("div", { className: "text-center", children: [
|
|
2052
|
+
/* @__PURE__ */ jsx10(
|
|
1971
2053
|
"div",
|
|
1972
2054
|
{
|
|
1973
|
-
className:
|
|
1974
|
-
style: {
|
|
1975
|
-
border: "2px solid transparent",
|
|
1976
|
-
backgroundImage: theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches ? `linear-gradient(135deg, ${themeConfig.borderGradientColor}60 0%, ${themeConfig.borderGradientColor}40 5%, transparent 22%)` : `linear-gradient(135deg, ${themeConfig.borderGradientColor}99 0%, ${themeConfig.borderGradientColor}66 5%, transparent 22%)`,
|
|
1977
|
-
backgroundOrigin: "border-box",
|
|
1978
|
-
backgroundClip: "border-box",
|
|
1979
|
-
WebkitMask: "linear-gradient(#ffffff 0 0) padding-box, linear-gradient(#ffffff 0 0)",
|
|
1980
|
-
WebkitMaskComposite: "xor",
|
|
1981
|
-
zIndex: 0
|
|
1982
|
-
}
|
|
2055
|
+
className: `animate-spin rounded-full border-2 border-gray-300 border-t-blue-600 mx-auto ${sizeClasses[size]}`
|
|
1983
2056
|
}
|
|
1984
2057
|
),
|
|
1985
|
-
/* @__PURE__ */
|
|
1986
|
-
|
|
1987
|
-
{
|
|
1988
|
-
className: "backdrop-blur-sm rounded-full flex items-center justify-center overflow-hidden flex-shrink-0 flex-grow-0",
|
|
1989
|
-
style: {
|
|
1990
|
-
backgroundColor: theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.05)",
|
|
1991
|
-
width: "28px",
|
|
1992
|
-
height: "28px"
|
|
1993
|
-
},
|
|
1994
|
-
children: /* @__PURE__ */ jsx12("div", { className: "rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsx12(
|
|
1995
|
-
Icon4,
|
|
1996
|
-
{
|
|
1997
|
-
icon: iconConfig.icon,
|
|
1998
|
-
width: 16,
|
|
1999
|
-
height: 16,
|
|
2000
|
-
className: `flex-shrink-0`,
|
|
2001
|
-
style: {
|
|
2002
|
-
color: themeConfig.gradientColor,
|
|
2003
|
-
display: "block"
|
|
2004
|
-
}
|
|
2005
|
-
}
|
|
2006
|
-
) })
|
|
2007
|
-
}
|
|
2008
|
-
) }),
|
|
2009
|
-
/* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-1 flex-1 relative z-10", children: [
|
|
2010
|
-
title && /* @__PURE__ */ jsx12(
|
|
2011
|
-
"div",
|
|
2012
|
-
{
|
|
2013
|
-
className: "text-[16px] font-semibold leading-tight drop-shadow-sm",
|
|
2014
|
-
style: {
|
|
2015
|
-
color: getTextColor(),
|
|
2016
|
-
backgroundClip: "text"
|
|
2017
|
-
},
|
|
2018
|
-
children: title
|
|
2019
|
-
}
|
|
2020
|
-
),
|
|
2021
|
-
message && /* @__PURE__ */ jsx12(
|
|
2022
|
-
"div",
|
|
2023
|
-
{
|
|
2024
|
-
className: "text-[13px] font-normal leading-relaxed drop-shadow-sm",
|
|
2025
|
-
style: {
|
|
2026
|
-
color: getTextColor(),
|
|
2027
|
-
backgroundClip: "text"
|
|
2028
|
-
},
|
|
2029
|
-
children: message
|
|
2030
|
-
}
|
|
2031
|
-
)
|
|
2032
|
-
] }),
|
|
2033
|
-
/* @__PURE__ */ jsx12("div", { className: "relative z-10", children: /* @__PURE__ */ jsx12(CloseButton, { closeToast: handleClose }) })
|
|
2034
|
-
] });
|
|
2058
|
+
text && /* @__PURE__ */ jsx10("p", { className: "mt-2 text-sm text-gray-600", children: text })
|
|
2059
|
+
] }) });
|
|
2035
2060
|
};
|
|
2036
|
-
var
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2061
|
+
var LoadingSpinner = ({
|
|
2062
|
+
size = "md",
|
|
2063
|
+
className = ""
|
|
2064
|
+
}) => {
|
|
2065
|
+
const sizeClasses = {
|
|
2066
|
+
sm: "h-4 w-4",
|
|
2067
|
+
md: "h-8 w-8",
|
|
2068
|
+
lg: "h-12 w-12"
|
|
2069
|
+
};
|
|
2070
|
+
return /* @__PURE__ */ jsx10(
|
|
2071
|
+
"div",
|
|
2072
|
+
{
|
|
2073
|
+
className: `animate-spin rounded-full border-2 border-gray-300 border-t-blue-600 ${sizeClasses[size]} ${className}`
|
|
2074
|
+
}
|
|
2075
|
+
);
|
|
2045
2076
|
};
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2077
|
+
|
|
2078
|
+
// src/components/ui/ErrorBoundary.tsx
|
|
2079
|
+
import { Component } from "react";
|
|
2080
|
+
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2081
|
+
var ErrorBoundary = class extends Component {
|
|
2082
|
+
constructor(props) {
|
|
2083
|
+
super(props);
|
|
2084
|
+
this.handleRetry = () => {
|
|
2085
|
+
this.setState({ hasError: false, error: void 0, errorInfo: void 0 });
|
|
2086
|
+
};
|
|
2087
|
+
this.state = { hasError: false };
|
|
2052
2088
|
}
|
|
2053
|
-
|
|
2054
|
-
};
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2089
|
+
static getDerivedStateFromError(error) {
|
|
2090
|
+
return { hasError: true, error };
|
|
2091
|
+
}
|
|
2092
|
+
componentDidCatch(error, errorInfo) {
|
|
2093
|
+
this.setState({
|
|
2094
|
+
error,
|
|
2095
|
+
errorInfo
|
|
2096
|
+
});
|
|
2097
|
+
this.props.onError?.(error, errorInfo);
|
|
2098
|
+
}
|
|
2099
|
+
render() {
|
|
2100
|
+
if (this.state.hasError) {
|
|
2101
|
+
if (this.props.fallback) {
|
|
2102
|
+
const FallbackComponent = this.props.fallback;
|
|
2103
|
+
return /* @__PURE__ */ jsx11(FallbackComponent, { error: this.state.error, retry: this.handleRetry });
|
|
2104
|
+
}
|
|
2105
|
+
return /* @__PURE__ */ jsx11("div", { className: "min-h-[400px] flex items-center justify-center p-4", children: /* @__PURE__ */ jsxs8("div", { className: "text-center max-w-md", children: [
|
|
2106
|
+
/* @__PURE__ */ jsx11("div", { className: "text-red-500 text-6xl mb-4", children: "\u26A0\uFE0F" }),
|
|
2107
|
+
/* @__PURE__ */ jsx11("h2", { className: "text-xl font-semibold text-gray-900 mb-2", children: "Something went wrong" }),
|
|
2108
|
+
/* @__PURE__ */ jsx11("p", { className: "text-gray-600 mb-4", children: "An unexpected error occurred. Please try refreshing the page." }),
|
|
2109
|
+
/* @__PURE__ */ jsx11(
|
|
2110
|
+
"button",
|
|
2063
2111
|
{
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
component,
|
|
2068
|
-
closeToast
|
|
2112
|
+
onClick: this.handleRetry,
|
|
2113
|
+
className: "px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors",
|
|
2114
|
+
children: "Try Again"
|
|
2069
2115
|
}
|
|
2070
|
-
)
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
// 确保圆角样式不被覆盖,添加 rounded-xl 类
|
|
2077
|
-
className: "!p-0 !shadow-none !rounded-xl",
|
|
2078
|
-
style: { padding: 0, borderRadius: "0.75rem", backgroundColor: "transparent" }
|
|
2079
|
-
}
|
|
2080
|
-
);
|
|
2081
|
-
};
|
|
2116
|
+
),
|
|
2117
|
+
false
|
|
2118
|
+
] }) });
|
|
2119
|
+
}
|
|
2120
|
+
return this.props.children;
|
|
2121
|
+
}
|
|
2082
2122
|
};
|
|
2083
|
-
var
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2123
|
+
var DefaultErrorFallback = ({ retry }) => /* @__PURE__ */ jsx11("div", { className: "min-h-[200px] flex items-center justify-center p-4", children: /* @__PURE__ */ jsxs8("div", { className: "text-center", children: [
|
|
2124
|
+
/* @__PURE__ */ jsx11("div", { className: "text-red-500 text-4xl mb-2", children: "\u26A0\uFE0F" }),
|
|
2125
|
+
/* @__PURE__ */ jsx11("p", { className: "text-gray-600 mb-2", children: "Something went wrong" }),
|
|
2126
|
+
retry && /* @__PURE__ */ jsx11(
|
|
2127
|
+
"button",
|
|
2128
|
+
{
|
|
2129
|
+
onClick: retry,
|
|
2130
|
+
className: "px-3 py-1 bg-blue-600 text-white text-sm rounded hover:bg-blue-700 transition-colors",
|
|
2131
|
+
children: "Retry"
|
|
2132
|
+
}
|
|
2133
|
+
)
|
|
2134
|
+
] }) });
|
|
2135
|
+
|
|
2136
|
+
// src/components/ui/ClayxButton.tsx
|
|
2137
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
2138
|
+
var getSizeClasses = (size, isIconOnly) => {
|
|
2139
|
+
if (isIconOnly) {
|
|
2140
|
+
switch (size) {
|
|
2141
|
+
case "sm":
|
|
2142
|
+
return "h-8 w-8 min-w-8 p-0";
|
|
2143
|
+
case "md":
|
|
2144
|
+
return "h-10 w-10 min-w-10 p-0";
|
|
2145
|
+
case "lg":
|
|
2146
|
+
return "h-12 w-12 min-w-12 p-0";
|
|
2147
|
+
default:
|
|
2148
|
+
return "h-10 w-10 min-w-10 p-0";
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
switch (size) {
|
|
2152
|
+
case "sm":
|
|
2153
|
+
return "h-8 px-3 text-sm";
|
|
2154
|
+
case "md":
|
|
2155
|
+
return "h-10 px-4 text-base";
|
|
2156
|
+
case "lg":
|
|
2157
|
+
return "h-12 px-6 text-lg";
|
|
2158
|
+
default:
|
|
2159
|
+
return "h-10 px-4 text-base";
|
|
2160
|
+
}
|
|
2161
|
+
};
|
|
2162
|
+
var getVariantClasses = (variant) => {
|
|
2163
|
+
switch (variant) {
|
|
2164
|
+
case "solid":
|
|
2165
|
+
return "bg-primary text-white hover:bg-primary/90";
|
|
2166
|
+
case "ghost":
|
|
2167
|
+
return "bg-transparent hover:bg-white/10";
|
|
2168
|
+
case "flat":
|
|
2169
|
+
return "bg-white/5 hover:bg-white/10";
|
|
2170
|
+
default:
|
|
2171
|
+
return "";
|
|
2172
|
+
}
|
|
2173
|
+
};
|
|
2174
|
+
var ClayxButton = ({
|
|
2175
|
+
isIconOnly = false,
|
|
2176
|
+
size = "md",
|
|
2177
|
+
variant = "solid",
|
|
2178
|
+
className = "",
|
|
2179
|
+
children,
|
|
2180
|
+
disabled = false,
|
|
2181
|
+
...props
|
|
2182
|
+
}) => {
|
|
2183
|
+
const sizeClasses = getSizeClasses(size, isIconOnly);
|
|
2184
|
+
const variantClasses = getVariantClasses(variant);
|
|
2185
|
+
const baseClasses = `
|
|
2186
|
+
inline-flex items-center justify-center
|
|
2187
|
+
rounded-md font-medium
|
|
2188
|
+
transition-all duration-200
|
|
2189
|
+
focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-transparent
|
|
2190
|
+
disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none
|
|
2191
|
+
`.replace(/\s+/g, " ").trim();
|
|
2192
|
+
const combinedClasses = `${baseClasses} ${sizeClasses} ${variantClasses} ${className}`.trim();
|
|
2193
|
+
return /* @__PURE__ */ jsx12(
|
|
2194
|
+
"button",
|
|
2195
|
+
{
|
|
2196
|
+
className: combinedClasses,
|
|
2197
|
+
disabled,
|
|
2198
|
+
...props,
|
|
2199
|
+
children
|
|
2200
|
+
}
|
|
2201
|
+
);
|
|
2089
2202
|
};
|
|
2090
2203
|
|
|
2091
2204
|
// src/components/ui/LimitUpgradeToast.tsx
|
|
2205
|
+
import React8 from "react";
|
|
2206
|
+
import { Icon as Icon5 } from "@iconify/react";
|
|
2092
2207
|
import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2093
|
-
var
|
|
2208
|
+
var PremiumActionToast = ({
|
|
2209
|
+
message,
|
|
2210
|
+
onAction,
|
|
2211
|
+
closeToast,
|
|
2212
|
+
buttonText = "Upgrade Now",
|
|
2213
|
+
title = "Information",
|
|
2214
|
+
variant = "purple"
|
|
2215
|
+
}) => {
|
|
2094
2216
|
const [hover, setHover] = React8.useState(false);
|
|
2095
2217
|
const [closeHover, setCloseHover] = React8.useState(false);
|
|
2096
|
-
|
|
2218
|
+
const colors = {
|
|
2219
|
+
purple: {
|
|
2220
|
+
gradient1: "rgba(168,85,247,0.3)",
|
|
2221
|
+
gradient2: "rgba(168,85,247,0.2)",
|
|
2222
|
+
borderStart: "rgba(168,85,247,0.8)",
|
|
2223
|
+
borderEnd: "rgba(168,85,247,0.5)",
|
|
2224
|
+
bgGlow1: "from-purple-500/20 via-pink-500/10",
|
|
2225
|
+
bgGlow2: "from-blue-500/10",
|
|
2226
|
+
tagBg: "bg-purple-500/30",
|
|
2227
|
+
tagText: "text-white",
|
|
2228
|
+
tagBorder: "border border-purple-400/50",
|
|
2229
|
+
borderColor: "#a855f7",
|
|
2230
|
+
btnGradient: hover ? "linear-gradient(to right, #9333ea, #db2777)" : "linear-gradient(to right, #a855f7, #ec4899)",
|
|
2231
|
+
btnShadow: "0 10px 15px -3px rgba(168,85,247,0.3), 0 4px 6px -2px rgba(168,85,247,0.3)",
|
|
2232
|
+
shadow: "0_20px_60px_rgba(168,85,247,0.2)",
|
|
2233
|
+
badge: "Premium"
|
|
2234
|
+
},
|
|
2235
|
+
blue: {
|
|
2236
|
+
gradient1: "rgba(59,130,246,0.3)",
|
|
2237
|
+
gradient2: "rgba(59,130,246,0.2)",
|
|
2238
|
+
borderStart: "rgba(59,130,246,0.8)",
|
|
2239
|
+
borderEnd: "rgba(59,130,246,0.5)",
|
|
2240
|
+
bgGlow1: "from-blue-500/20 via-cyan-500/10",
|
|
2241
|
+
bgGlow2: "from-indigo-500/10",
|
|
2242
|
+
tagBg: "bg-blue-500/30",
|
|
2243
|
+
tagText: "text-white",
|
|
2244
|
+
tagBorder: "border border-blue-400/50",
|
|
2245
|
+
borderColor: "#3b82f6",
|
|
2246
|
+
btnGradient: hover ? "linear-gradient(to right, #1d4ed8, #0ea5e9)" : "linear-gradient(to right, #3b82f6, #06b6d4)",
|
|
2247
|
+
btnShadow: "0 10px 15px -3px rgba(59,130,246,0.3), 0 4px 6px -2px rgba(59,130,246,0.3)",
|
|
2248
|
+
shadow: "0_20px_60px_rgba(59,130,246,0.2)",
|
|
2249
|
+
badge: "Secure"
|
|
2250
|
+
}
|
|
2251
|
+
}[variant];
|
|
2252
|
+
return /* @__PURE__ */ jsxs9("div", { className: `relative w-full max-w-[420px] overflow-hidden rounded-md bg-gradient-to-br from-[#1A1A1A] via-[#151515] to-[#1A1A1A] shadow-[${colors.shadow}] backdrop-blur-sm`, children: [
|
|
2097
2253
|
/* @__PURE__ */ jsx13(
|
|
2098
2254
|
"div",
|
|
2099
2255
|
{
|
|
@@ -2109,7 +2265,7 @@ var LimitToastContainer = ({ message, onUpgrade, closeToast }) => {
|
|
|
2109
2265
|
{
|
|
2110
2266
|
className: "absolute left-0 top-0 w-full h-full pointer-events-none rounded-md",
|
|
2111
2267
|
style: {
|
|
2112
|
-
background: `linear-gradient(135deg,
|
|
2268
|
+
background: `linear-gradient(135deg, ${colors.gradient1} 0%, ${colors.gradient2} 15%, #1A1A1A 30%)`,
|
|
2113
2269
|
zIndex: -1
|
|
2114
2270
|
}
|
|
2115
2271
|
}
|
|
@@ -2120,7 +2276,7 @@ var LimitToastContainer = ({ message, onUpgrade, closeToast }) => {
|
|
|
2120
2276
|
className: "absolute left-0 top-0 w-full h-full pointer-events-none rounded-md",
|
|
2121
2277
|
style: {
|
|
2122
2278
|
border: "2px solid transparent",
|
|
2123
|
-
backgroundImage: `linear-gradient(135deg,
|
|
2279
|
+
backgroundImage: `linear-gradient(135deg, ${colors.borderStart} 0%, ${colors.borderEnd} 5%, transparent 22%)`,
|
|
2124
2280
|
backgroundOrigin: "border-box",
|
|
2125
2281
|
backgroundClip: "border-box",
|
|
2126
2282
|
WebkitMask: "linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0)",
|
|
@@ -2130,13 +2286,20 @@ var LimitToastContainer = ({ message, onUpgrade, closeToast }) => {
|
|
|
2130
2286
|
}
|
|
2131
2287
|
}
|
|
2132
2288
|
),
|
|
2133
|
-
/* @__PURE__ */ jsx13("div", { className:
|
|
2134
|
-
/* @__PURE__ */ jsx13("div", { className:
|
|
2289
|
+
/* @__PURE__ */ jsx13("div", { className: `absolute -top-16 -right-16 h-32 w-32 rounded-full bg-gradient-to-br ${colors.bgGlow1} to-transparent blur-3xl animate-pulse` }),
|
|
2290
|
+
/* @__PURE__ */ jsx13("div", { className: `absolute -bottom-16 -left-16 h-32 w-32 rounded-full bg-gradient-to-tr ${colors.bgGlow2} to-transparent blur-2xl animate-pulse`, style: { animationDelay: "1s" } }),
|
|
2135
2291
|
/* @__PURE__ */ jsx13("div", { className: "relative z-10 flex items-start gap-4 p-4", children: /* @__PURE__ */ jsxs9("div", { className: "flex flex-1 flex-col gap-3", children: [
|
|
2136
2292
|
/* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between", children: [
|
|
2137
2293
|
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
2138
|
-
/* @__PURE__ */ jsx13("div", { className: "text-lg font-bold text-white", children:
|
|
2139
|
-
/* @__PURE__ */ jsx13(
|
|
2294
|
+
/* @__PURE__ */ jsx13("div", { className: "text-lg font-bold text-white", children: title }),
|
|
2295
|
+
/* @__PURE__ */ jsx13(
|
|
2296
|
+
"div",
|
|
2297
|
+
{
|
|
2298
|
+
className: `px-2 py-0.5 text-xs font-bold ${colors.tagBg} ${colors.tagText} rounded-md border`,
|
|
2299
|
+
style: { borderColor: colors.borderColor },
|
|
2300
|
+
children: colors.badge
|
|
2301
|
+
}
|
|
2302
|
+
)
|
|
2140
2303
|
] }),
|
|
2141
2304
|
/* @__PURE__ */ jsx13(
|
|
2142
2305
|
ClayxButton,
|
|
@@ -2155,16 +2318,16 @@ var LimitToastContainer = ({ message, onUpgrade, closeToast }) => {
|
|
|
2155
2318
|
transition: "background-color 150ms ease",
|
|
2156
2319
|
cursor: "pointer"
|
|
2157
2320
|
},
|
|
2158
|
-
children: /* @__PURE__ */ jsx13(Icon5, { icon: "iconamoon:close", className: "w-4 h-4 text-gray-
|
|
2321
|
+
children: /* @__PURE__ */ jsx13(Icon5, { icon: "iconamoon:close", className: "w-4 h-4 text-gray-300" })
|
|
2159
2322
|
}
|
|
2160
2323
|
)
|
|
2161
2324
|
] }),
|
|
2162
|
-
/* @__PURE__ */ jsx13("p", { className: "text-sm text-
|
|
2325
|
+
/* @__PURE__ */ jsx13("p", { className: "text-sm text-white leading-relaxed font-medium", children: message }),
|
|
2163
2326
|
/* @__PURE__ */ jsx13("div", { className: "mt-1 flex items-center gap-3", children: /* @__PURE__ */ jsx13(
|
|
2164
2327
|
ClayxButton,
|
|
2165
2328
|
{
|
|
2166
2329
|
onClick: () => {
|
|
2167
|
-
|
|
2330
|
+
onAction();
|
|
2168
2331
|
closeToast?.();
|
|
2169
2332
|
},
|
|
2170
2333
|
onMouseEnter: () => setHover(true),
|
|
@@ -2175,21 +2338,31 @@ var LimitToastContainer = ({ message, onUpgrade, closeToast }) => {
|
|
|
2175
2338
|
fontWeight: 600,
|
|
2176
2339
|
cursor: "pointer",
|
|
2177
2340
|
transition: "all 300ms ease-in-out",
|
|
2178
|
-
backgroundImage:
|
|
2179
|
-
boxShadow: hover ?
|
|
2341
|
+
backgroundImage: colors.btnGradient,
|
|
2342
|
+
boxShadow: hover ? colors.btnShadow : "none"
|
|
2180
2343
|
},
|
|
2181
2344
|
children: /* @__PURE__ */ jsxs9("span", { className: "flex items-center gap-2", children: [
|
|
2182
|
-
/* @__PURE__ */ jsx13(Icon5, { icon: "solar:rocket-2-bold", className: "w-4 h-4" }),
|
|
2183
|
-
|
|
2345
|
+
/* @__PURE__ */ jsx13(Icon5, { icon: variant === "purple" ? "solar:rocket-2-bold" : "solar:login-3-bold", className: "w-4 h-4" }),
|
|
2346
|
+
buttonText
|
|
2184
2347
|
] })
|
|
2185
2348
|
}
|
|
2186
2349
|
) })
|
|
2187
2350
|
] }) })
|
|
2188
2351
|
] });
|
|
2189
2352
|
};
|
|
2190
|
-
function
|
|
2353
|
+
function showPremiumActionToast(message, onAction, buttonText, title, variant = "purple") {
|
|
2191
2354
|
ClayxToast.default({
|
|
2192
|
-
render: (closeToast) => /* @__PURE__ */ jsx13(
|
|
2355
|
+
render: (closeToast) => /* @__PURE__ */ jsx13(
|
|
2356
|
+
PremiumActionToast,
|
|
2357
|
+
{
|
|
2358
|
+
message,
|
|
2359
|
+
onAction,
|
|
2360
|
+
closeToast,
|
|
2361
|
+
buttonText,
|
|
2362
|
+
title,
|
|
2363
|
+
variant
|
|
2364
|
+
}
|
|
2365
|
+
),
|
|
2193
2366
|
options: {
|
|
2194
2367
|
position: "bottom-right",
|
|
2195
2368
|
closeOnClick: false,
|
|
@@ -2207,6 +2380,12 @@ function showLimitUpgradeToast(message, onUpgrade) {
|
|
|
2207
2380
|
}
|
|
2208
2381
|
});
|
|
2209
2382
|
}
|
|
2383
|
+
function showLimitUpgradeToast(message, onUpgrade, buttonText, title) {
|
|
2384
|
+
showPremiumActionToast(message, onUpgrade, buttonText, title, "purple");
|
|
2385
|
+
}
|
|
2386
|
+
function showSignInRequiredToast(message, onSignIn, buttonText, title) {
|
|
2387
|
+
showPremiumActionToast(message, onSignIn, buttonText, title, "blue");
|
|
2388
|
+
}
|
|
2210
2389
|
|
|
2211
2390
|
// src/services/ai-workflow.ts
|
|
2212
2391
|
var AIWorkflowClient = class {
|
|
@@ -2582,6 +2761,15 @@ async function executeSSEWorkflow(request, options = {}) {
|
|
|
2582
2761
|
};
|
|
2583
2762
|
if (options.authToken) {
|
|
2584
2763
|
headers["Authorization"] = `Bearer ${options.authToken}`;
|
|
2764
|
+
} else {
|
|
2765
|
+
try {
|
|
2766
|
+
const { getGuestSessionId: getGuestSessionId2 } = (init_session(), __toCommonJS(session_exports));
|
|
2767
|
+
const sessionId = getGuestSessionId2?.();
|
|
2768
|
+
if (sessionId) {
|
|
2769
|
+
headers["X-Session-Id"] = sessionId;
|
|
2770
|
+
}
|
|
2771
|
+
} catch {
|
|
2772
|
+
}
|
|
2585
2773
|
}
|
|
2586
2774
|
const method = request.method?.toUpperCase() ?? "POST";
|
|
2587
2775
|
const hasBody = request.body && Object.keys(request.body).length > 0;
|
|
@@ -2596,7 +2784,23 @@ async function executeSSEWorkflow(request, options = {}) {
|
|
|
2596
2784
|
signal: options.signal
|
|
2597
2785
|
});
|
|
2598
2786
|
if (!response.ok) {
|
|
2599
|
-
|
|
2787
|
+
if (response.status === 403) {
|
|
2788
|
+
showSignInRequiredToast(
|
|
2789
|
+
"Free trial limit reached. Please sign in to continue.",
|
|
2790
|
+
() => {
|
|
2791
|
+
const authUrl = getEnvs().AUTH_ROOT_VALUE;
|
|
2792
|
+
const redirectUri = window.location.href;
|
|
2793
|
+
const projectId = getDefaultProjectId();
|
|
2794
|
+
let authHref = `${authUrl}/auth?redirect_uri=${encodeURIComponent(redirectUri)}`;
|
|
2795
|
+
if (projectId) {
|
|
2796
|
+
authHref += `&project_id=${encodeURIComponent(projectId)}`;
|
|
2797
|
+
}
|
|
2798
|
+
window.location.href = authHref;
|
|
2799
|
+
},
|
|
2800
|
+
"Sign In",
|
|
2801
|
+
"Sign In Required"
|
|
2802
|
+
);
|
|
2803
|
+
}
|
|
2600
2804
|
}
|
|
2601
2805
|
const reader = response.body?.getReader();
|
|
2602
2806
|
if (!reader) {
|
|
@@ -3349,6 +3553,15 @@ function createClient(opts) {
|
|
|
3349
3553
|
const availableToken = getAvailableToken();
|
|
3350
3554
|
if (availableToken) {
|
|
3351
3555
|
config.headers["Authorization"] = `Bearer ${availableToken}`;
|
|
3556
|
+
} else {
|
|
3557
|
+
try {
|
|
3558
|
+
const { getGuestSessionId: getGuestSessionId2 } = (init_session(), __toCommonJS(session_exports));
|
|
3559
|
+
const sessionId = getGuestSessionId2?.();
|
|
3560
|
+
if (sessionId) {
|
|
3561
|
+
config.headers["X-Session-Id"] = sessionId;
|
|
3562
|
+
}
|
|
3563
|
+
} catch {
|
|
3564
|
+
}
|
|
3352
3565
|
}
|
|
3353
3566
|
}
|
|
3354
3567
|
return config;
|
|
@@ -4151,6 +4364,9 @@ var elementSelector = {
|
|
|
4151
4364
|
*/
|
|
4152
4365
|
isActive: () => getElementSelectorState().active
|
|
4153
4366
|
};
|
|
4367
|
+
|
|
4368
|
+
// src/index.ts
|
|
4369
|
+
init_session();
|
|
4154
4370
|
export {
|
|
4155
4371
|
AUTH_TOKEN_KEY,
|
|
4156
4372
|
ClayxButton,
|
|
@@ -4169,6 +4385,7 @@ export {
|
|
|
4169
4385
|
ThemeToggle,
|
|
4170
4386
|
aiWorkflow,
|
|
4171
4387
|
canAccessArtifact,
|
|
4388
|
+
clearGuestSession,
|
|
4172
4389
|
createAIWorkflowClient,
|
|
4173
4390
|
createAIWorkflowClientAxios,
|
|
4174
4391
|
createArtifactsClient,
|
|
@@ -4183,10 +4400,12 @@ export {
|
|
|
4183
4400
|
getEnvironment,
|
|
4184
4401
|
getEnvs,
|
|
4185
4402
|
getGlobalEnvironment,
|
|
4403
|
+
getGuestSessionId,
|
|
4186
4404
|
getToken,
|
|
4187
4405
|
client_default as howone,
|
|
4188
4406
|
iframeNavigation,
|
|
4189
4407
|
initIframeNavigation,
|
|
4408
|
+
isGuestMode,
|
|
4190
4409
|
isTokenValid,
|
|
4191
4410
|
loginWithEmailCode,
|
|
4192
4411
|
onAuthStateChanged,
|
|
@@ -4197,6 +4416,8 @@ export {
|
|
|
4197
4416
|
setEnvironment,
|
|
4198
4417
|
setToken,
|
|
4199
4418
|
showLimitUpgradeToast,
|
|
4419
|
+
showPremiumActionToast,
|
|
4420
|
+
showSignInRequiredToast,
|
|
4200
4421
|
unifiedAuth,
|
|
4201
4422
|
unifiedOAuth,
|
|
4202
4423
|
useAuth,
|