@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.js
CHANGED
|
@@ -269,6 +269,69 @@ var init_auth = __esm({
|
|
|
269
269
|
}
|
|
270
270
|
});
|
|
271
271
|
|
|
272
|
+
// src/utils/session.ts
|
|
273
|
+
var session_exports = {};
|
|
274
|
+
__export(session_exports, {
|
|
275
|
+
clearGuestSession: () => clearGuestSession,
|
|
276
|
+
consumeGuestSession: () => consumeGuestSession,
|
|
277
|
+
getExistingSessionId: () => getExistingSessionId,
|
|
278
|
+
getGuestSessionId: () => getGuestSessionId,
|
|
279
|
+
isGuestMode: () => isGuestMode
|
|
280
|
+
});
|
|
281
|
+
function getGuestSessionId() {
|
|
282
|
+
if (typeof window === "undefined") return null;
|
|
283
|
+
try {
|
|
284
|
+
let sessionId = localStorage.getItem(GUEST_SESSION_KEY);
|
|
285
|
+
if (!sessionId) {
|
|
286
|
+
sessionId = crypto.randomUUID();
|
|
287
|
+
localStorage.setItem(GUEST_SESSION_KEY, sessionId);
|
|
288
|
+
}
|
|
289
|
+
return sessionId;
|
|
290
|
+
} catch {
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function clearGuestSession() {
|
|
295
|
+
if (typeof window === "undefined") return;
|
|
296
|
+
try {
|
|
297
|
+
localStorage.removeItem(GUEST_SESSION_KEY);
|
|
298
|
+
} catch {
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function isGuestMode() {
|
|
302
|
+
if (typeof window === "undefined") return false;
|
|
303
|
+
const hasAuthToken = !!localStorage.getItem("auth_token");
|
|
304
|
+
const hasSession = !!localStorage.getItem(GUEST_SESSION_KEY);
|
|
305
|
+
return !hasAuthToken && hasSession;
|
|
306
|
+
}
|
|
307
|
+
function getExistingSessionId() {
|
|
308
|
+
if (typeof window === "undefined") return null;
|
|
309
|
+
try {
|
|
310
|
+
return localStorage.getItem(GUEST_SESSION_KEY);
|
|
311
|
+
} catch {
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function consumeGuestSession() {
|
|
316
|
+
if (typeof window === "undefined") return null;
|
|
317
|
+
try {
|
|
318
|
+
const sessionId = localStorage.getItem(GUEST_SESSION_KEY);
|
|
319
|
+
if (sessionId) {
|
|
320
|
+
localStorage.removeItem(GUEST_SESSION_KEY);
|
|
321
|
+
}
|
|
322
|
+
return sessionId;
|
|
323
|
+
} catch {
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
var GUEST_SESSION_KEY;
|
|
328
|
+
var init_session = __esm({
|
|
329
|
+
"src/utils/session.ts"() {
|
|
330
|
+
"use strict";
|
|
331
|
+
GUEST_SESSION_KEY = "howone_guest_session";
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
|
|
272
335
|
// src/index.ts
|
|
273
336
|
var index_exports = {};
|
|
274
337
|
__export(index_exports, {
|
|
@@ -289,6 +352,7 @@ __export(index_exports, {
|
|
|
289
352
|
ThemeToggle: () => ThemeToggle,
|
|
290
353
|
aiWorkflow: () => aiWorkflow,
|
|
291
354
|
canAccessArtifact: () => canAccessArtifact,
|
|
355
|
+
clearGuestSession: () => clearGuestSession,
|
|
292
356
|
createAIWorkflowClient: () => createAIWorkflowClient,
|
|
293
357
|
createAIWorkflowClientAxios: () => createAIWorkflowClientAxios,
|
|
294
358
|
createArtifactsClient: () => createArtifactsClient,
|
|
@@ -303,10 +367,12 @@ __export(index_exports, {
|
|
|
303
367
|
getEnvironment: () => getEnvironment,
|
|
304
368
|
getEnvs: () => getEnvs,
|
|
305
369
|
getGlobalEnvironment: () => getGlobalEnvironment,
|
|
370
|
+
getGuestSessionId: () => getGuestSessionId,
|
|
306
371
|
getToken: () => getToken,
|
|
307
372
|
howone: () => client_default,
|
|
308
373
|
iframeNavigation: () => iframeNavigation,
|
|
309
374
|
initIframeNavigation: () => initIframeNavigation,
|
|
375
|
+
isGuestMode: () => isGuestMode,
|
|
310
376
|
isTokenValid: () => isTokenValid,
|
|
311
377
|
loginWithEmailCode: () => loginWithEmailCode,
|
|
312
378
|
onAuthStateChanged: () => onAuthStateChanged,
|
|
@@ -317,6 +383,8 @@ __export(index_exports, {
|
|
|
317
383
|
setEnvironment: () => setEnvironment,
|
|
318
384
|
setToken: () => setToken,
|
|
319
385
|
showLimitUpgradeToast: () => showLimitUpgradeToast,
|
|
386
|
+
showPremiumActionToast: () => showPremiumActionToast,
|
|
387
|
+
showSignInRequiredToast: () => showSignInRequiredToast,
|
|
320
388
|
unifiedAuth: () => unifiedAuth,
|
|
321
389
|
unifiedOAuth: () => unifiedOAuth,
|
|
322
390
|
useAuth: () => useAuth,
|
|
@@ -1021,7 +1089,7 @@ var LoginForm = ({
|
|
|
1021
1089
|
};
|
|
1022
1090
|
|
|
1023
1091
|
// src/components/auth/HowoneProvider.tsx
|
|
1024
|
-
var
|
|
1092
|
+
var import_react11 = require("react");
|
|
1025
1093
|
init_auth();
|
|
1026
1094
|
|
|
1027
1095
|
// src/components/theme/ThemeProvider.tsx
|
|
@@ -1320,851 +1388,944 @@ var ElementSelectorProvider = ({ children }) => {
|
|
|
1320
1388
|
|
|
1321
1389
|
// src/components/auth/HowoneProvider.tsx
|
|
1322
1390
|
init_config();
|
|
1323
|
-
|
|
1324
|
-
var HowoneContext = (0, import_react8.createContext)(null);
|
|
1325
|
-
var redirectOverlayStylesInjected = false;
|
|
1326
|
-
var injectRedirectOverlayStyles = () => {
|
|
1327
|
-
if (redirectOverlayStylesInjected || typeof document === "undefined") return;
|
|
1328
|
-
const style = document.createElement("style");
|
|
1329
|
-
style.setAttribute("data-howone-auth-overlay", "true");
|
|
1330
|
-
style.textContent = `
|
|
1331
|
-
@keyframes howone-logo-pulse {
|
|
1332
|
-
0%, 100% {
|
|
1333
|
-
opacity: 0.2;
|
|
1334
|
-
transform: scale(0.95);
|
|
1335
|
-
filter: drop-shadow(0 0 0 rgba(255, 255, 255, 0.2));
|
|
1336
|
-
}
|
|
1337
|
-
50% {
|
|
1338
|
-
opacity: 1;
|
|
1339
|
-
transform: scale(1.03);
|
|
1340
|
-
filter: drop-shadow(0 0 28px rgba(255, 255, 255, 0.55));
|
|
1341
|
-
}
|
|
1342
|
-
}
|
|
1391
|
+
init_session();
|
|
1343
1392
|
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
}
|
|
1349
|
-
50% {
|
|
1350
|
-
opacity: 0.42;
|
|
1351
|
-
transform: scale(1.05);
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1393
|
+
// src/components/ui/Toast/ClayxToast.tsx
|
|
1394
|
+
var import_react9 = __toESM(require("react"));
|
|
1395
|
+
var import_react_toastify2 = require("react-toastify");
|
|
1396
|
+
var import_react10 = require("@iconify/react");
|
|
1354
1397
|
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
height: 100vh;
|
|
1365
|
-
color: #ffffff;
|
|
1366
|
-
background: rgba(0, 0, 0, 0.65);
|
|
1367
|
-
backdrop-filter: blur(6px);
|
|
1368
|
-
-webkit-backdrop-filter: blur(6px);
|
|
1369
|
-
text-align: center;
|
|
1370
|
-
}
|
|
1371
|
-
`;
|
|
1372
|
-
document.head.appendChild(style);
|
|
1373
|
-
redirectOverlayStylesInjected = true;
|
|
1374
|
-
};
|
|
1375
|
-
var HowOneProvider = ({
|
|
1376
|
-
children,
|
|
1377
|
-
showFloatingButton = true,
|
|
1378
|
-
projectId,
|
|
1379
|
-
defaultTheme = "system",
|
|
1380
|
-
themeStorageKey = "howone-theme",
|
|
1381
|
-
forceDefaultTheme = false,
|
|
1382
|
-
redirectOnUnauthenticated = true
|
|
1383
|
-
}) => {
|
|
1384
|
-
const [user, setUser] = (0, import_react8.useState)(() => parseUserFromToken(getToken()));
|
|
1385
|
-
const [token, setTokenState] = (0, import_react8.useState)(() => getToken());
|
|
1386
|
-
const [hasCheckedUrlToken, setHasCheckedUrlToken] = (0, import_react8.useState)(false);
|
|
1387
|
-
const [pendingRedirect, setPendingRedirect] = (0, import_react8.useState)(false);
|
|
1388
|
-
(0, import_react8.useEffect)(() => {
|
|
1389
|
-
try {
|
|
1390
|
-
const params = new URLSearchParams(window.location.search);
|
|
1391
|
-
let urlToken = params.get("access_token") || params.get("token");
|
|
1392
|
-
if (!urlToken && window.location.hash) {
|
|
1393
|
-
const hashParams = new URLSearchParams(window.location.hash.slice(1));
|
|
1394
|
-
urlToken = hashParams.get("access_token") || hashParams.get("token");
|
|
1395
|
-
}
|
|
1396
|
-
if (urlToken) {
|
|
1397
|
-
setToken(urlToken);
|
|
1398
|
-
setTokenState(urlToken);
|
|
1399
|
-
setUser(parseUserFromToken(urlToken));
|
|
1400
|
-
params.delete("access_token");
|
|
1401
|
-
params.delete("token");
|
|
1402
|
-
params.delete("project_id");
|
|
1403
|
-
const newSearch = params.toString();
|
|
1404
|
-
const newUrl = window.location.pathname + (newSearch ? "?" + newSearch : "");
|
|
1405
|
-
window.history.replaceState({}, "", newUrl);
|
|
1406
|
-
}
|
|
1407
|
-
} catch (e) {
|
|
1408
|
-
console.error("[HowOneProvider] Failed to capture token from URL:", e);
|
|
1409
|
-
} finally {
|
|
1410
|
-
setHasCheckedUrlToken(true);
|
|
1411
|
-
}
|
|
1412
|
-
}, []);
|
|
1413
|
-
const resolvedAuthUrl = (0, import_react8.useMemo)(() => {
|
|
1414
|
-
const env3 = getGlobalEnvironment() ?? "dev";
|
|
1415
|
-
switch (env3) {
|
|
1416
|
-
case "local":
|
|
1417
|
-
return "http://localhost:3000/auth";
|
|
1418
|
-
case "prod":
|
|
1419
|
-
return "https://howone.ai/auth";
|
|
1420
|
-
case "dev":
|
|
1421
|
-
default:
|
|
1422
|
-
return "https://howone.dev/auth";
|
|
1423
|
-
}
|
|
1398
|
+
// src/components/theme/ThemeToggle.tsx
|
|
1399
|
+
var React4 = __toESM(require("react"));
|
|
1400
|
+
var import_react8 = require("@iconify/react");
|
|
1401
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1402
|
+
function ThemeToggle({ className }) {
|
|
1403
|
+
const { setTheme, theme } = useTheme();
|
|
1404
|
+
const [mounted, setMounted] = React4.useState(false);
|
|
1405
|
+
React4.useEffect(() => {
|
|
1406
|
+
setMounted(true);
|
|
1424
1407
|
}, []);
|
|
1425
|
-
|
|
1426
|
-
if (
|
|
1427
|
-
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
|
-
(0, import_react8.useEffect)(() => {
|
|
1431
|
-
if (pendingRedirect) {
|
|
1432
|
-
injectRedirectOverlayStyles();
|
|
1433
|
-
}
|
|
1434
|
-
}, [pendingRedirect]);
|
|
1435
|
-
const redirectToAuth = (0, import_react8.useCallback)(() => {
|
|
1436
|
-
if (!redirectOnUnauthenticated || typeof window === "undefined") return;
|
|
1437
|
-
const activeProjectId = projectId ?? getDefaultProjectId();
|
|
1438
|
-
const navigateToResolvedAuth = () => {
|
|
1439
|
-
setPendingRedirect(true);
|
|
1440
|
-
requestAnimationFrame(() => {
|
|
1441
|
-
if (activeProjectId) {
|
|
1442
|
-
try {
|
|
1443
|
-
const url = new URL(resolvedAuthUrl);
|
|
1444
|
-
url.searchParams.set("redirect_uri", window.location.href);
|
|
1445
|
-
url.searchParams.set("project_id", activeProjectId);
|
|
1446
|
-
window.location.href = url.toString();
|
|
1447
|
-
return;
|
|
1448
|
-
} catch (error) {
|
|
1449
|
-
console.error("[HowOneProvider] Failed to attach project_id to auth URL:", error);
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
window.location.href = resolvedAuthUrl;
|
|
1453
|
-
});
|
|
1454
|
-
};
|
|
1455
|
-
try {
|
|
1456
|
-
const currentUrl = new URL(window.location.href);
|
|
1457
|
-
if (currentUrl.pathname.includes("/auth")) return;
|
|
1458
|
-
try {
|
|
1459
|
-
const authUrlObj = new URL(resolvedAuthUrl);
|
|
1460
|
-
authUrlObj.searchParams.set("redirect_uri", window.location.href);
|
|
1461
|
-
if (activeProjectId) {
|
|
1462
|
-
authUrlObj.searchParams.set("project_id", activeProjectId);
|
|
1463
|
-
}
|
|
1464
|
-
setPendingRedirect(true);
|
|
1465
|
-
requestAnimationFrame(() => {
|
|
1466
|
-
window.location.href = authUrlObj.toString();
|
|
1467
|
-
});
|
|
1468
|
-
return;
|
|
1469
|
-
} catch (error) {
|
|
1470
|
-
console.error("[HowOneProvider] Failed to build auth URL:", error);
|
|
1471
|
-
}
|
|
1472
|
-
navigateToResolvedAuth();
|
|
1473
|
-
} catch {
|
|
1474
|
-
navigateToResolvedAuth();
|
|
1475
|
-
}
|
|
1476
|
-
}, [redirectOnUnauthenticated, resolvedAuthUrl, projectId]);
|
|
1477
|
-
(0, import_react8.useEffect)(() => {
|
|
1478
|
-
if (!hasCheckedUrlToken) return;
|
|
1479
|
-
if (!token && !user) {
|
|
1480
|
-
redirectToAuth();
|
|
1481
|
-
}
|
|
1482
|
-
}, [token, user, hasCheckedUrlToken, redirectToAuth]);
|
|
1483
|
-
const logout = () => {
|
|
1484
|
-
try {
|
|
1485
|
-
setToken(null);
|
|
1486
|
-
} catch {
|
|
1408
|
+
const handleToggle = () => {
|
|
1409
|
+
if (theme === "dark") {
|
|
1410
|
+
setTheme("light");
|
|
1411
|
+
} else {
|
|
1412
|
+
setTheme("dark");
|
|
1487
1413
|
}
|
|
1488
|
-
setTokenState(null);
|
|
1489
|
-
setUser(null);
|
|
1490
|
-
redirectToAuth();
|
|
1491
|
-
};
|
|
1492
|
-
const value = {
|
|
1493
|
-
user,
|
|
1494
|
-
token,
|
|
1495
|
-
isAuthenticated: hasCheckedUrlToken && !!token,
|
|
1496
|
-
logout
|
|
1497
1414
|
};
|
|
1498
|
-
if (!
|
|
1499
|
-
|
|
1500
|
-
|
|
1415
|
+
if (!mounted) {
|
|
1416
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react8.Icon, { icon: "solar:sun-bold", width: 20, height: 20 });
|
|
1417
|
+
}
|
|
1418
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1419
|
+
"div",
|
|
1501
1420
|
{
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
children: [
|
|
1506
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ElementSelectorProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(HowoneContext.Provider, { value, children: [
|
|
1507
|
-
children,
|
|
1508
|
-
showFloatingButton && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FloatingButton, { onClick: () => window.open("https://howone.ai", "_blank") }),
|
|
1509
|
-
pendingRedirect && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1510
|
-
"div",
|
|
1511
|
-
{
|
|
1512
|
-
"data-howone-auth-overlay-root": true,
|
|
1513
|
-
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",
|
|
1514
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "relative mt-6 flex h-[220px] w-[220px] items-center justify-center", children: [
|
|
1515
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1516
|
-
"div",
|
|
1517
|
-
{
|
|
1518
|
-
className: "absolute inset-0 rounded-full bg-white/20",
|
|
1519
|
-
style: { animation: "howone-glow-ring 2.4s ease-in-out infinite" }
|
|
1520
|
-
}
|
|
1521
|
-
),
|
|
1522
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "absolute inset-0 rounded-full bg-gradient-to-br from-white/10 via-white/25 to-white/10 blur-2xl" }),
|
|
1523
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1524
|
-
"img",
|
|
1525
|
-
{
|
|
1526
|
-
style: { width: 250, animation: "howone-logo-pulse 2s ease-in-out infinite" },
|
|
1527
|
-
src: "https://sxwxqoixnnklnpeutjrj.supabase.co/storage/v1/object/public/create-x/logo/logo.svg",
|
|
1528
|
-
alt: "HowOne"
|
|
1529
|
-
}
|
|
1530
|
-
)
|
|
1531
|
-
] })
|
|
1532
|
-
}
|
|
1533
|
-
)
|
|
1534
|
-
] }) }),
|
|
1535
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(GlobalToastContainer, {})
|
|
1536
|
-
]
|
|
1421
|
+
className: `cursor-pointer ${className || ""}`,
|
|
1422
|
+
onClick: handleToggle,
|
|
1423
|
+
children: theme === "light" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react8.Icon, { icon: "solar:sun-bold", width: 20, height: 20 }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react8.Icon, { icon: "solar:moon-linear", width: 20, height: 20 })
|
|
1537
1424
|
}
|
|
1538
1425
|
);
|
|
1539
|
-
};
|
|
1540
|
-
function useHowoneContext() {
|
|
1541
|
-
const ctx = (0, import_react8.useContext)(HowoneContext);
|
|
1542
|
-
if (!ctx) {
|
|
1543
|
-
const t = getToken();
|
|
1544
|
-
return {
|
|
1545
|
-
user: parseUserFromToken(t),
|
|
1546
|
-
token: t,
|
|
1547
|
-
isAuthenticated: !!t,
|
|
1548
|
-
logout: () => {
|
|
1549
|
-
try {
|
|
1550
|
-
setToken(null);
|
|
1551
|
-
} catch {
|
|
1552
|
-
}
|
|
1553
|
-
}
|
|
1554
|
-
};
|
|
1555
|
-
}
|
|
1556
|
-
return ctx;
|
|
1557
1426
|
}
|
|
1558
1427
|
|
|
1559
|
-
// src/components/
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1428
|
+
// src/components/ui/Toast/ClayxToast.tsx
|
|
1429
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1430
|
+
var TOAST_ICONS = {
|
|
1431
|
+
success: {
|
|
1432
|
+
icon: "mdi:success",
|
|
1433
|
+
color: "text-green-400",
|
|
1434
|
+
className: "text-green-400",
|
|
1435
|
+
// 深色主题配置
|
|
1436
|
+
dark: {
|
|
1437
|
+
bgGradient: "bg-[#14181d]",
|
|
1438
|
+
// 移除透明度 f2
|
|
1439
|
+
gradientColor: "#389726",
|
|
1440
|
+
borderGradient: "border-[#389726]",
|
|
1441
|
+
borderGradientColor: "#389726"
|
|
1442
|
+
},
|
|
1443
|
+
// 浅色主题配置
|
|
1444
|
+
light: {
|
|
1445
|
+
bgGradient: "bg-[#fafafa]",
|
|
1446
|
+
// 移除透明度 ff
|
|
1447
|
+
gradientColor: "#22c55e",
|
|
1448
|
+
borderGradient: "border-[#22c55e]",
|
|
1449
|
+
borderGradientColor: "#22c55e"
|
|
1581
1450
|
}
|
|
1582
|
-
}
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1451
|
+
},
|
|
1452
|
+
error: {
|
|
1453
|
+
icon: "ic:outline-close",
|
|
1454
|
+
color: "text-red-400",
|
|
1455
|
+
className: "text-red-400",
|
|
1456
|
+
dark: {
|
|
1457
|
+
bgGradient: "bg-[#14181d]",
|
|
1458
|
+
// 移除透明度 f2
|
|
1459
|
+
gradientColor: "#ef4444",
|
|
1460
|
+
borderGradient: "border-[#ef4444]",
|
|
1461
|
+
borderGradientColor: "#ef4444"
|
|
1462
|
+
},
|
|
1463
|
+
light: {
|
|
1464
|
+
bgGradient: "bg-[#fafafa]",
|
|
1465
|
+
// 移除透明度 ff
|
|
1466
|
+
gradientColor: "#f87171",
|
|
1467
|
+
borderGradient: "border-[#f87171]",
|
|
1468
|
+
borderGradientColor: "#f87171"
|
|
1469
|
+
}
|
|
1470
|
+
},
|
|
1471
|
+
warning: {
|
|
1472
|
+
icon: "mi:warning",
|
|
1473
|
+
color: "text-yellow-400",
|
|
1474
|
+
className: "text-yellow-400",
|
|
1475
|
+
dark: {
|
|
1476
|
+
bgGradient: "bg-[#14181d]",
|
|
1477
|
+
// 移除透明度 f2
|
|
1478
|
+
gradientColor: "#facc15",
|
|
1479
|
+
borderGradient: "border-[#facc15]",
|
|
1480
|
+
borderGradientColor: "#facc15"
|
|
1481
|
+
},
|
|
1482
|
+
light: {
|
|
1483
|
+
bgGradient: "bg-[#fafafa]",
|
|
1484
|
+
// 移除透明度 ff
|
|
1485
|
+
gradientColor: "#f59e0b",
|
|
1486
|
+
borderGradient: "border-[#f59e0b]",
|
|
1487
|
+
borderGradientColor: "#f59e0b"
|
|
1488
|
+
}
|
|
1489
|
+
},
|
|
1490
|
+
info: {
|
|
1491
|
+
icon: "ic:outline-info",
|
|
1492
|
+
color: "text-blue-400",
|
|
1493
|
+
className: "text-blue-400",
|
|
1494
|
+
dark: {
|
|
1495
|
+
bgGradient: "bg-[#14181d]",
|
|
1496
|
+
// 移除透明度 f2
|
|
1497
|
+
gradientColor: "#60a5fa",
|
|
1498
|
+
borderGradient: "border-[#60a5fa]",
|
|
1499
|
+
borderGradientColor: "#f0f0f0"
|
|
1500
|
+
},
|
|
1501
|
+
light: {
|
|
1502
|
+
bgGradient: "bg-[#fafafa]",
|
|
1503
|
+
// 移除透明度 ff
|
|
1504
|
+
gradientColor: "#3b82f6",
|
|
1505
|
+
borderGradient: "border-[#3b82f6]",
|
|
1506
|
+
borderGradientColor: "#3b82f6"
|
|
1507
|
+
}
|
|
1508
|
+
},
|
|
1509
|
+
default: {
|
|
1510
|
+
icon: "ic:round-notifications",
|
|
1511
|
+
color: "text-gray-400",
|
|
1512
|
+
className: "text-gray-400",
|
|
1513
|
+
dark: {
|
|
1514
|
+
bgGradient: "bg-[#14181d]",
|
|
1515
|
+
// 移除透明度 f2
|
|
1516
|
+
gradientColor: "#9ca3af",
|
|
1517
|
+
borderGradient: "border-[#9ca3af]",
|
|
1518
|
+
borderGradientColor: "#9ca3af"
|
|
1519
|
+
},
|
|
1520
|
+
light: {
|
|
1521
|
+
bgGradient: "bg-[#fafafa]",
|
|
1522
|
+
// 移除透明度 ff
|
|
1523
|
+
gradientColor: "#6b7280",
|
|
1524
|
+
borderGradient: "border-[#6b7280]",
|
|
1525
|
+
borderGradientColor: "#6b7280"
|
|
1589
1526
|
}
|
|
1590
|
-
return () => {
|
|
1591
|
-
this.listeners.delete(listener);
|
|
1592
|
-
};
|
|
1593
1527
|
}
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1528
|
+
};
|
|
1529
|
+
var CloseButton = import_react9.default.memo(({ closeToast }) => {
|
|
1530
|
+
const { theme } = useTheme();
|
|
1531
|
+
const handleClick = (0, import_react9.useCallback)((e) => {
|
|
1532
|
+
e.preventDefault();
|
|
1533
|
+
e.stopPropagation();
|
|
1534
|
+
closeToast?.();
|
|
1535
|
+
}, [closeToast]);
|
|
1536
|
+
const getCloseButtonColor = () => {
|
|
1537
|
+
const actualTheme = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
|
|
1538
|
+
return actualTheme === "dark" ? "#b4b4b4" : "#6b7280";
|
|
1539
|
+
};
|
|
1540
|
+
const getCloseButtonHoverColor = () => {
|
|
1541
|
+
const actualTheme = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
|
|
1542
|
+
return actualTheme === "dark" ? "white" : "#374151";
|
|
1543
|
+
};
|
|
1544
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1545
|
+
import_react10.Icon,
|
|
1546
|
+
{
|
|
1547
|
+
icon: "vaadin:close",
|
|
1548
|
+
className: "flex items-center justify-center rounded-full relative z-10 flex-shrink-0 cursor-pointer \n transition-colors duration-200 drop-shadow-sm",
|
|
1549
|
+
onClick: handleClick,
|
|
1550
|
+
width: 14,
|
|
1551
|
+
height: 14,
|
|
1552
|
+
style: {
|
|
1553
|
+
color: getCloseButtonColor()
|
|
1554
|
+
},
|
|
1555
|
+
onMouseEnter: (e) => {
|
|
1556
|
+
e.currentTarget.style.color = getCloseButtonHoverColor();
|
|
1557
|
+
},
|
|
1558
|
+
onMouseLeave: (e) => {
|
|
1559
|
+
e.currentTarget.style.color = getCloseButtonColor();
|
|
1606
1560
|
}
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1561
|
+
}
|
|
1562
|
+
);
|
|
1563
|
+
});
|
|
1564
|
+
CloseButton.displayName = "CloseButton";
|
|
1565
|
+
var ToastContent = ({ type, title, message, component, closeToast }) => {
|
|
1566
|
+
const iconConfig = TOAST_ICONS[type];
|
|
1567
|
+
const { theme } = useTheme();
|
|
1568
|
+
const handleClose = (0, import_react9.useCallback)(() => {
|
|
1569
|
+
closeToast?.();
|
|
1570
|
+
}, [closeToast]);
|
|
1571
|
+
const getTextColor = () => {
|
|
1572
|
+
const actualTheme = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
|
|
1573
|
+
return actualTheme === "dark" ? "white" : "#1f2937";
|
|
1574
|
+
};
|
|
1575
|
+
const getThemeConfig = () => {
|
|
1576
|
+
const actualTheme = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
|
|
1577
|
+
return actualTheme === "dark" ? iconConfig.dark : iconConfig.light;
|
|
1578
|
+
};
|
|
1579
|
+
const themeConfig = getThemeConfig();
|
|
1580
|
+
const lightBaseBackgroundByType = {
|
|
1581
|
+
success: "#f0fdf4",
|
|
1582
|
+
// green-50
|
|
1583
|
+
error: "#fef2f2",
|
|
1584
|
+
// red-50
|
|
1585
|
+
warning: "#fffbeb",
|
|
1586
|
+
// amber-50
|
|
1587
|
+
info: "#eff6ff",
|
|
1588
|
+
// blue-50
|
|
1589
|
+
default: "#f9fafb"
|
|
1590
|
+
// gray-50
|
|
1591
|
+
};
|
|
1592
|
+
if (component) {
|
|
1593
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: `flex items-start gap-3 !min-h-[90px] w-full backdrop-blur-md p-4 shadow-2xl overflow-hidden ${themeConfig.bgGradient}`, children: [
|
|
1594
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex-1 relative z-10", children: component }),
|
|
1595
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "relative z-10", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CloseButton, { closeToast: handleClose }) })
|
|
1596
|
+
] });
|
|
1597
|
+
}
|
|
1598
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("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: [
|
|
1599
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1600
|
+
"div",
|
|
1601
|
+
{
|
|
1602
|
+
className: "absolute left-0 top-0 w-full h-full rounded-xl",
|
|
1603
|
+
style: {
|
|
1604
|
+
background: theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "#0f1419" : lightBaseBackgroundByType[type],
|
|
1605
|
+
zIndex: -2
|
|
1617
1606
|
}
|
|
1618
1607
|
}
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1608
|
+
),
|
|
1609
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1610
|
+
"div",
|
|
1611
|
+
{
|
|
1612
|
+
className: "absolute left-0 top-0 w-full h-full pointer-events-none rounded-xl",
|
|
1613
|
+
style: {
|
|
1614
|
+
background: theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches ? `linear-gradient(135deg, ${themeConfig.gradientColor}30 0%, ${themeConfig.gradientColor}20 15%, #14181df2 30%)` : `linear-gradient(135deg, ${themeConfig.gradientColor}20 0%, ${themeConfig.gradientColor}12 15%, #ffffff 30%)`,
|
|
1615
|
+
zIndex: -1
|
|
1616
|
+
}
|
|
1623
1617
|
}
|
|
1624
|
-
|
|
1625
|
-
}
|
|
1626
|
-
logout() {
|
|
1627
|
-
setToken(null);
|
|
1628
|
-
this.emit();
|
|
1629
|
-
}
|
|
1630
|
-
getUser() {
|
|
1631
|
-
return parseUserFromToken(getToken());
|
|
1632
|
-
}
|
|
1633
|
-
// helper to programmatically set token (e.g., after callback handling)
|
|
1634
|
-
setToken(token) {
|
|
1635
|
-
setToken(token);
|
|
1636
|
-
this.emit();
|
|
1637
|
-
}
|
|
1638
|
-
};
|
|
1639
|
-
var howone = {
|
|
1640
|
-
auth: new HowoneAuthClient()
|
|
1641
|
-
};
|
|
1642
|
-
var client_default = howone;
|
|
1643
|
-
|
|
1644
|
-
// src/components/ui/Loading.tsx
|
|
1645
|
-
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1646
|
-
var Loading = ({
|
|
1647
|
-
size = "md",
|
|
1648
|
-
text = "Loading...",
|
|
1649
|
-
className = "",
|
|
1650
|
-
fullScreen = false
|
|
1651
|
-
}) => {
|
|
1652
|
-
const sizeClasses = {
|
|
1653
|
-
sm: "h-4 w-4",
|
|
1654
|
-
md: "h-8 w-8",
|
|
1655
|
-
lg: "h-12 w-12"
|
|
1656
|
-
};
|
|
1657
|
-
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";
|
|
1658
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: `${containerClasses} ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "text-center", children: [
|
|
1618
|
+
),
|
|
1659
1619
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1660
1620
|
"div",
|
|
1661
1621
|
{
|
|
1662
|
-
className:
|
|
1622
|
+
className: "absolute left-0 top-0 w-full h-full pointer-events-none rounded-xl",
|
|
1623
|
+
style: {
|
|
1624
|
+
border: "2px solid transparent",
|
|
1625
|
+
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%)`,
|
|
1626
|
+
backgroundOrigin: "border-box",
|
|
1627
|
+
backgroundClip: "border-box",
|
|
1628
|
+
WebkitMask: "linear-gradient(#ffffff 0 0) padding-box, linear-gradient(#ffffff 0 0)",
|
|
1629
|
+
WebkitMaskComposite: "xor",
|
|
1630
|
+
zIndex: 0
|
|
1631
|
+
}
|
|
1663
1632
|
}
|
|
1664
1633
|
),
|
|
1665
|
-
|
|
1666
|
-
|
|
1634
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex-shrink-0 flex-grow-0 mt-0.5 relative z-10", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1635
|
+
"div",
|
|
1636
|
+
{
|
|
1637
|
+
className: "backdrop-blur-sm rounded-full flex items-center justify-center overflow-hidden flex-shrink-0 flex-grow-0",
|
|
1638
|
+
style: {
|
|
1639
|
+
backgroundColor: theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.05)",
|
|
1640
|
+
width: "28px",
|
|
1641
|
+
height: "28px"
|
|
1642
|
+
},
|
|
1643
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "rounded-full flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1644
|
+
import_react10.Icon,
|
|
1645
|
+
{
|
|
1646
|
+
icon: iconConfig.icon,
|
|
1647
|
+
width: 16,
|
|
1648
|
+
height: 16,
|
|
1649
|
+
className: `flex-shrink-0`,
|
|
1650
|
+
style: {
|
|
1651
|
+
color: themeConfig.gradientColor,
|
|
1652
|
+
display: "block"
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
) })
|
|
1656
|
+
}
|
|
1657
|
+
) }),
|
|
1658
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col gap-1 flex-1 relative z-10", children: [
|
|
1659
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1660
|
+
"div",
|
|
1661
|
+
{
|
|
1662
|
+
className: "text-[16px] font-semibold leading-tight drop-shadow-sm",
|
|
1663
|
+
style: {
|
|
1664
|
+
color: getTextColor(),
|
|
1665
|
+
backgroundClip: "text"
|
|
1666
|
+
},
|
|
1667
|
+
children: title
|
|
1668
|
+
}
|
|
1669
|
+
),
|
|
1670
|
+
message && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1671
|
+
"div",
|
|
1672
|
+
{
|
|
1673
|
+
className: "text-[13px] font-normal leading-relaxed drop-shadow-sm",
|
|
1674
|
+
style: {
|
|
1675
|
+
color: getTextColor(),
|
|
1676
|
+
backgroundClip: "text"
|
|
1677
|
+
},
|
|
1678
|
+
children: message
|
|
1679
|
+
}
|
|
1680
|
+
)
|
|
1681
|
+
] }),
|
|
1682
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "relative z-10", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CloseButton, { closeToast: handleClose }) })
|
|
1683
|
+
] });
|
|
1667
1684
|
};
|
|
1668
|
-
var
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1678
|
-
"div",
|
|
1679
|
-
{
|
|
1680
|
-
className: `animate-spin rounded-full border-2 border-gray-300 border-t-blue-600 ${sizeClasses[size]} ${className}`
|
|
1681
|
-
}
|
|
1682
|
-
);
|
|
1685
|
+
var defaultToastOptions = {
|
|
1686
|
+
position: "bottom-right",
|
|
1687
|
+
autoClose: 1500,
|
|
1688
|
+
hideProgressBar: true,
|
|
1689
|
+
closeOnClick: false,
|
|
1690
|
+
pauseOnHover: true,
|
|
1691
|
+
draggable: true,
|
|
1692
|
+
pauseOnFocusLoss: false,
|
|
1693
|
+
transition: import_react_toastify2.Bounce
|
|
1683
1694
|
};
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
super(props);
|
|
1691
|
-
this.handleRetry = () => {
|
|
1692
|
-
this.setState({ hasError: false, error: void 0, errorInfo: void 0 });
|
|
1693
|
-
};
|
|
1694
|
-
this.state = { hasError: false };
|
|
1695
|
-
}
|
|
1696
|
-
static getDerivedStateFromError(error) {
|
|
1697
|
-
return { hasError: true, error };
|
|
1698
|
-
}
|
|
1699
|
-
componentDidCatch(error, errorInfo) {
|
|
1700
|
-
this.setState({
|
|
1701
|
-
error,
|
|
1702
|
-
errorInfo
|
|
1703
|
-
});
|
|
1704
|
-
this.props.onError?.(error, errorInfo);
|
|
1695
|
+
var getToastifyTheme = () => {
|
|
1696
|
+
if (typeof window !== "undefined") {
|
|
1697
|
+
const root = document.documentElement;
|
|
1698
|
+
if (root.classList.contains("dark")) return "dark";
|
|
1699
|
+
if (root.classList.contains("light")) return "light";
|
|
1700
|
+
return window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
1705
1701
|
}
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
/* @__PURE__ */ (0,
|
|
1715
|
-
|
|
1716
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1717
|
-
"button",
|
|
1702
|
+
return "light";
|
|
1703
|
+
};
|
|
1704
|
+
var createToast = (type) => {
|
|
1705
|
+
return (params) => {
|
|
1706
|
+
const { title, message, component, options } = params;
|
|
1707
|
+
(0, import_react_toastify2.toast)(
|
|
1708
|
+
({ closeToast }) => {
|
|
1709
|
+
if (params.render) return params.render(closeToast);
|
|
1710
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1711
|
+
ToastContent,
|
|
1718
1712
|
{
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1713
|
+
type,
|
|
1714
|
+
title,
|
|
1715
|
+
message: message || "",
|
|
1716
|
+
component,
|
|
1717
|
+
closeToast
|
|
1722
1718
|
}
|
|
1723
|
-
)
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1719
|
+
);
|
|
1720
|
+
},
|
|
1721
|
+
{
|
|
1722
|
+
...defaultToastOptions,
|
|
1723
|
+
...options,
|
|
1724
|
+
theme: getToastifyTheme(),
|
|
1725
|
+
// 确保圆角样式不被覆盖,添加 rounded-xl 类
|
|
1726
|
+
className: "!p-0 !shadow-none !rounded-xl",
|
|
1727
|
+
style: { padding: 0, borderRadius: "0.75rem", backgroundColor: "transparent" }
|
|
1728
|
+
}
|
|
1729
|
+
);
|
|
1730
|
+
};
|
|
1731
|
+
};
|
|
1732
|
+
var ClayxToast = {
|
|
1733
|
+
success: createToast("success"),
|
|
1734
|
+
error: createToast("error"),
|
|
1735
|
+
warning: createToast("warning"),
|
|
1736
|
+
info: createToast("info"),
|
|
1737
|
+
default: createToast("default")
|
|
1729
1738
|
};
|
|
1730
|
-
var DefaultErrorFallback = ({ retry }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "min-h-[200px] flex items-center justify-center p-4", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "text-center", children: [
|
|
1731
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "text-red-500 text-4xl mb-2", children: "\u26A0\uFE0F" }),
|
|
1732
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-gray-600 mb-2", children: "Something went wrong" }),
|
|
1733
|
-
retry && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1734
|
-
"button",
|
|
1735
|
-
{
|
|
1736
|
-
onClick: retry,
|
|
1737
|
-
className: "px-3 py-1 bg-blue-600 text-white text-sm rounded hover:bg-blue-700 transition-colors",
|
|
1738
|
-
children: "Retry"
|
|
1739
|
-
}
|
|
1740
|
-
)
|
|
1741
|
-
] }) });
|
|
1742
1739
|
|
|
1743
|
-
// src/components/
|
|
1744
|
-
var
|
|
1745
|
-
var
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1740
|
+
// src/components/auth/HowoneProvider.tsx
|
|
1741
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1742
|
+
var HowoneContext = (0, import_react11.createContext)(null);
|
|
1743
|
+
var redirectOverlayStylesInjected = false;
|
|
1744
|
+
var injectRedirectOverlayStyles = () => {
|
|
1745
|
+
if (redirectOverlayStylesInjected || typeof document === "undefined") return;
|
|
1746
|
+
const style = document.createElement("style");
|
|
1747
|
+
style.setAttribute("data-howone-auth-overlay", "true");
|
|
1748
|
+
style.textContent = `
|
|
1749
|
+
@keyframes howone-logo-pulse {
|
|
1750
|
+
0%, 100% {
|
|
1751
|
+
opacity: 0.2;
|
|
1752
|
+
transform: scale(0.95);
|
|
1753
|
+
filter: drop-shadow(0 0 0 rgba(255, 255, 255, 0.2));
|
|
1757
1754
|
}
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1755
|
+
50% {
|
|
1756
|
+
opacity: 1;
|
|
1757
|
+
transform: scale(1.03);
|
|
1758
|
+
filter: drop-shadow(0 0 28px rgba(255, 255, 255, 0.55));
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
@keyframes howone-glow-ring {
|
|
1763
|
+
0%, 100% {
|
|
1764
|
+
opacity: 0.12;
|
|
1765
|
+
transform: scale(0.85);
|
|
1767
1766
|
}
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
case "solid":
|
|
1772
|
-
return "bg-primary text-white hover:bg-primary/90";
|
|
1773
|
-
case "ghost":
|
|
1774
|
-
return "bg-transparent hover:bg-white/10";
|
|
1775
|
-
case "flat":
|
|
1776
|
-
return "bg-white/5 hover:bg-white/10";
|
|
1777
|
-
default:
|
|
1778
|
-
return "";
|
|
1767
|
+
50% {
|
|
1768
|
+
opacity: 0.42;
|
|
1769
|
+
transform: scale(1.05);
|
|
1779
1770
|
}
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
[data-howone-auth-overlay-root] {
|
|
1774
|
+
position: fixed;
|
|
1775
|
+
inset: 0;
|
|
1776
|
+
z-index: 2147483646;
|
|
1777
|
+
display: flex;
|
|
1778
|
+
flex-direction: column;
|
|
1779
|
+
align-items: center;
|
|
1780
|
+
justify-content: center;
|
|
1781
|
+
width: 100vw;
|
|
1782
|
+
height: 100vh;
|
|
1783
|
+
color: #ffffff;
|
|
1784
|
+
background: rgba(0, 0, 0, 0.65);
|
|
1785
|
+
backdrop-filter: blur(6px);
|
|
1786
|
+
-webkit-backdrop-filter: blur(6px);
|
|
1787
|
+
text-align: center;
|
|
1788
|
+
}
|
|
1789
|
+
`;
|
|
1790
|
+
document.head.appendChild(style);
|
|
1791
|
+
redirectOverlayStylesInjected = true;
|
|
1780
1792
|
};
|
|
1781
|
-
var
|
|
1782
|
-
isIconOnly = false,
|
|
1783
|
-
size = "md",
|
|
1784
|
-
variant = "solid",
|
|
1785
|
-
className = "",
|
|
1793
|
+
var HowOneProvider = ({
|
|
1786
1794
|
children,
|
|
1787
|
-
|
|
1788
|
-
|
|
1795
|
+
showFloatingButton = true,
|
|
1796
|
+
projectId,
|
|
1797
|
+
defaultTheme = "system",
|
|
1798
|
+
themeStorageKey = "howone-theme",
|
|
1799
|
+
forceDefaultTheme = false,
|
|
1800
|
+
redirectOnUnauthenticated = false
|
|
1789
1801
|
}) => {
|
|
1790
|
-
const
|
|
1791
|
-
const
|
|
1792
|
-
const
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1802
|
+
const [user, setUser] = (0, import_react11.useState)(() => parseUserFromToken(getToken()));
|
|
1803
|
+
const [token, setTokenState] = (0, import_react11.useState)(() => getToken());
|
|
1804
|
+
const [hasCheckedUrlToken, setHasCheckedUrlToken] = (0, import_react11.useState)(false);
|
|
1805
|
+
const [pendingRedirect, setPendingRedirect] = (0, import_react11.useState)(false);
|
|
1806
|
+
const [isGuest, setIsGuest] = (0, import_react11.useState)(false);
|
|
1807
|
+
(0, import_react11.useEffect)(() => {
|
|
1808
|
+
try {
|
|
1809
|
+
const params = new URLSearchParams(window.location.search);
|
|
1810
|
+
let urlToken = params.get("access_token") || params.get("token");
|
|
1811
|
+
if (!urlToken && window.location.hash) {
|
|
1812
|
+
const hashParams = new URLSearchParams(window.location.hash.slice(1));
|
|
1813
|
+
urlToken = hashParams.get("access_token") || hashParams.get("token");
|
|
1814
|
+
}
|
|
1815
|
+
if (urlToken) {
|
|
1816
|
+
setToken(urlToken);
|
|
1817
|
+
setTokenState(urlToken);
|
|
1818
|
+
setUser(parseUserFromToken(urlToken));
|
|
1819
|
+
params.delete("access_token");
|
|
1820
|
+
params.delete("token");
|
|
1821
|
+
params.delete("project_id");
|
|
1822
|
+
const newSearch = params.toString();
|
|
1823
|
+
const newUrl = window.location.pathname + (newSearch ? "?" + newSearch : "");
|
|
1824
|
+
window.history.replaceState({}, "", newUrl);
|
|
1825
|
+
}
|
|
1826
|
+
} catch (e) {
|
|
1827
|
+
console.error("[HowOneProvider] Failed to capture token from URL:", e);
|
|
1828
|
+
} finally {
|
|
1829
|
+
setHasCheckedUrlToken(true);
|
|
1807
1830
|
}
|
|
1808
|
-
);
|
|
1809
|
-
};
|
|
1810
|
-
|
|
1811
|
-
// src/components/ui/LimitUpgradeToast.tsx
|
|
1812
|
-
var import_react13 = __toESM(require("react"));
|
|
1813
|
-
var import_react14 = require("@iconify/react");
|
|
1814
|
-
|
|
1815
|
-
// src/components/ui/Toast/ClayxToast.tsx
|
|
1816
|
-
var import_react11 = __toESM(require("react"));
|
|
1817
|
-
var import_react_toastify2 = require("react-toastify");
|
|
1818
|
-
var import_react12 = require("@iconify/react");
|
|
1819
|
-
|
|
1820
|
-
// src/components/theme/ThemeToggle.tsx
|
|
1821
|
-
var React6 = __toESM(require("react"));
|
|
1822
|
-
var import_react10 = require("@iconify/react");
|
|
1823
|
-
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1824
|
-
function ThemeToggle({ className }) {
|
|
1825
|
-
const { setTheme, theme } = useTheme();
|
|
1826
|
-
const [mounted, setMounted] = React6.useState(false);
|
|
1827
|
-
React6.useEffect(() => {
|
|
1828
|
-
setMounted(true);
|
|
1829
1831
|
}, []);
|
|
1830
|
-
const
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1841
|
-
"div",
|
|
1842
|
-
{
|
|
1843
|
-
className: `cursor-pointer ${className || ""}`,
|
|
1844
|
-
onClick: handleToggle,
|
|
1845
|
-
children: theme === "light" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react10.Icon, { icon: "solar:sun-bold", width: 20, height: 20 }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react10.Icon, { icon: "solar:moon-linear", width: 20, height: 20 })
|
|
1832
|
+
const resolvedAuthUrl = (0, import_react11.useMemo)(() => {
|
|
1833
|
+
const env3 = getGlobalEnvironment() ?? "dev";
|
|
1834
|
+
switch (env3) {
|
|
1835
|
+
case "local":
|
|
1836
|
+
return "http://localhost:3000/auth";
|
|
1837
|
+
case "prod":
|
|
1838
|
+
return "https://howone.ai/auth";
|
|
1839
|
+
case "dev":
|
|
1840
|
+
default:
|
|
1841
|
+
return "https://howone.dev/auth";
|
|
1846
1842
|
}
|
|
1847
|
-
);
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1852
|
-
var TOAST_ICONS = {
|
|
1853
|
-
success: {
|
|
1854
|
-
icon: "mdi:success",
|
|
1855
|
-
color: "text-green-400",
|
|
1856
|
-
className: "text-green-400",
|
|
1857
|
-
// 深色主题配置
|
|
1858
|
-
dark: {
|
|
1859
|
-
bgGradient: "bg-[#14181d]",
|
|
1860
|
-
// 移除透明度 f2
|
|
1861
|
-
gradientColor: "#389726",
|
|
1862
|
-
borderGradient: "border-[#389726]",
|
|
1863
|
-
borderGradientColor: "#389726"
|
|
1864
|
-
},
|
|
1865
|
-
// 浅色主题配置
|
|
1866
|
-
light: {
|
|
1867
|
-
bgGradient: "bg-[#fafafa]",
|
|
1868
|
-
// 移除透明度 ff
|
|
1869
|
-
gradientColor: "#22c55e",
|
|
1870
|
-
borderGradient: "border-[#22c55e]",
|
|
1871
|
-
borderGradientColor: "#22c55e"
|
|
1843
|
+
}, []);
|
|
1844
|
+
(0, import_react11.useEffect)(() => {
|
|
1845
|
+
if (pendingRedirect) {
|
|
1846
|
+
injectRedirectOverlayStyles();
|
|
1872
1847
|
}
|
|
1873
|
-
},
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
className: "text-red-400",
|
|
1878
|
-
dark: {
|
|
1879
|
-
bgGradient: "bg-[#14181d]",
|
|
1880
|
-
// 移除透明度 f2
|
|
1881
|
-
gradientColor: "#ef4444",
|
|
1882
|
-
borderGradient: "border-[#ef4444]",
|
|
1883
|
-
borderGradientColor: "#ef4444"
|
|
1884
|
-
},
|
|
1885
|
-
light: {
|
|
1886
|
-
bgGradient: "bg-[#fafafa]",
|
|
1887
|
-
// 移除透明度 ff
|
|
1888
|
-
gradientColor: "#f87171",
|
|
1889
|
-
borderGradient: "border-[#f87171]",
|
|
1890
|
-
borderGradientColor: "#f87171"
|
|
1848
|
+
}, [pendingRedirect]);
|
|
1849
|
+
(0, import_react11.useEffect)(() => {
|
|
1850
|
+
if (pendingRedirect) {
|
|
1851
|
+
injectRedirectOverlayStyles();
|
|
1891
1852
|
}
|
|
1892
|
-
},
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1853
|
+
}, [pendingRedirect]);
|
|
1854
|
+
const redirectToAuth = (0, import_react11.useCallback)(() => {
|
|
1855
|
+
if (!redirectOnUnauthenticated || typeof window === "undefined") return;
|
|
1856
|
+
const activeProjectId = projectId ?? getDefaultProjectId();
|
|
1857
|
+
const navigateToResolvedAuth = () => {
|
|
1858
|
+
setPendingRedirect(true);
|
|
1859
|
+
requestAnimationFrame(() => {
|
|
1860
|
+
if (activeProjectId) {
|
|
1861
|
+
try {
|
|
1862
|
+
const url = new URL(resolvedAuthUrl);
|
|
1863
|
+
url.searchParams.set("redirect_uri", window.location.origin);
|
|
1864
|
+
url.searchParams.set("project_id", activeProjectId);
|
|
1865
|
+
window.location.href = url.toString();
|
|
1866
|
+
return;
|
|
1867
|
+
} catch (error) {
|
|
1868
|
+
console.error("[HowOneProvider] Failed to attach project_id to auth URL:", error);
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
window.location.href = resolvedAuthUrl;
|
|
1872
|
+
});
|
|
1873
|
+
};
|
|
1874
|
+
try {
|
|
1875
|
+
const currentUrl = new URL(window.location.href);
|
|
1876
|
+
if (currentUrl.pathname.includes("/auth")) return;
|
|
1877
|
+
try {
|
|
1878
|
+
const authUrlObj = new URL(resolvedAuthUrl);
|
|
1879
|
+
authUrlObj.searchParams.set("redirect_uri", window.location.origin);
|
|
1880
|
+
if (activeProjectId) {
|
|
1881
|
+
authUrlObj.searchParams.set("project_id", activeProjectId);
|
|
1882
|
+
}
|
|
1883
|
+
setPendingRedirect(true);
|
|
1884
|
+
requestAnimationFrame(() => {
|
|
1885
|
+
window.location.href = authUrlObj.toString();
|
|
1886
|
+
});
|
|
1887
|
+
return;
|
|
1888
|
+
} catch (error) {
|
|
1889
|
+
console.error("[HowOneProvider] Failed to build auth URL:", error);
|
|
1890
|
+
}
|
|
1891
|
+
navigateToResolvedAuth();
|
|
1892
|
+
} catch {
|
|
1893
|
+
navigateToResolvedAuth();
|
|
1910
1894
|
}
|
|
1911
|
-
},
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
// 移除透明度 f2
|
|
1919
|
-
gradientColor: "#60a5fa",
|
|
1920
|
-
borderGradient: "border-[#60a5fa]",
|
|
1921
|
-
borderGradientColor: "#f0f0f0"
|
|
1922
|
-
},
|
|
1923
|
-
light: {
|
|
1924
|
-
bgGradient: "bg-[#fafafa]",
|
|
1925
|
-
// 移除透明度 ff
|
|
1926
|
-
gradientColor: "#3b82f6",
|
|
1927
|
-
borderGradient: "border-[#3b82f6]",
|
|
1928
|
-
borderGradientColor: "#3b82f6"
|
|
1895
|
+
}, [redirectOnUnauthenticated, resolvedAuthUrl, projectId]);
|
|
1896
|
+
(0, import_react11.useEffect)(() => {
|
|
1897
|
+
if (!hasCheckedUrlToken) return;
|
|
1898
|
+
const guestMode = isGuestMode() || !!getExistingSessionId();
|
|
1899
|
+
setIsGuest(guestMode);
|
|
1900
|
+
if (token || user || guestMode) {
|
|
1901
|
+
return;
|
|
1929
1902
|
}
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1903
|
+
redirectToAuth();
|
|
1904
|
+
}, [token, user, hasCheckedUrlToken, redirectToAuth]);
|
|
1905
|
+
(0, import_react11.useEffect)(() => {
|
|
1906
|
+
if (!hasCheckedUrlToken || !token || !user) return;
|
|
1907
|
+
const migrateGuestData = async () => {
|
|
1908
|
+
try {
|
|
1909
|
+
const guestSessionId = getExistingSessionId();
|
|
1910
|
+
if (!guestSessionId) return;
|
|
1911
|
+
const activeProjectId = projectId ?? getDefaultProjectId();
|
|
1912
|
+
if (!activeProjectId) {
|
|
1913
|
+
console.warn("[HowOneProvider] No projectId available for guest data migration");
|
|
1914
|
+
return;
|
|
1915
|
+
}
|
|
1916
|
+
const baseUrl = getEnvs().baseUrl;
|
|
1917
|
+
const response = await fetch(
|
|
1918
|
+
`${baseUrl}/entities/apps/${activeProjectId}/migrate-guest-data`,
|
|
1919
|
+
{
|
|
1920
|
+
method: "POST",
|
|
1921
|
+
headers: {
|
|
1922
|
+
"Content-Type": "application/json",
|
|
1923
|
+
"Authorization": `Bearer ${token}`
|
|
1924
|
+
},
|
|
1925
|
+
body: JSON.stringify({ guestSessionId })
|
|
1926
|
+
}
|
|
1927
|
+
);
|
|
1928
|
+
if (response.ok) {
|
|
1929
|
+
const result = await response.json();
|
|
1930
|
+
console.log("[HowOneProvider] Guest data migration result:", result);
|
|
1931
|
+
clearGuestSession();
|
|
1932
|
+
setIsGuest(false);
|
|
1933
|
+
if (result.totalCount > 0) {
|
|
1934
|
+
const entityList = result.details?.map((d) => `${d.entityName} (${d.count})`).join(", ") || "";
|
|
1935
|
+
ClayxToast.success({
|
|
1936
|
+
title: "Data Synced",
|
|
1937
|
+
message: `Migrated ${result.totalCount} records${entityList ? `: ${entityList}` : ""}`
|
|
1938
|
+
});
|
|
1939
|
+
}
|
|
1940
|
+
} else {
|
|
1941
|
+
console.error("[HowOneProvider] Guest data migration failed:", response.status);
|
|
1942
|
+
}
|
|
1943
|
+
} catch (error) {
|
|
1944
|
+
console.error("[HowOneProvider] Failed to migrate guest data:", error);
|
|
1945
|
+
}
|
|
1946
|
+
};
|
|
1947
|
+
migrateGuestData();
|
|
1948
|
+
}, [token, user, hasCheckedUrlToken, projectId]);
|
|
1949
|
+
const logout = () => {
|
|
1950
|
+
try {
|
|
1951
|
+
setToken(null);
|
|
1952
|
+
} catch {
|
|
1948
1953
|
}
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
const { theme } = useTheme();
|
|
1953
|
-
const handleClick = (0, import_react11.useCallback)((e) => {
|
|
1954
|
-
e.preventDefault();
|
|
1955
|
-
e.stopPropagation();
|
|
1956
|
-
closeToast?.();
|
|
1957
|
-
}, [closeToast]);
|
|
1958
|
-
const getCloseButtonColor = () => {
|
|
1959
|
-
const actualTheme = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
|
|
1960
|
-
return actualTheme === "dark" ? "#b4b4b4" : "#6b7280";
|
|
1954
|
+
setTokenState(null);
|
|
1955
|
+
setUser(null);
|
|
1956
|
+
redirectToAuth();
|
|
1961
1957
|
};
|
|
1962
|
-
const
|
|
1963
|
-
|
|
1964
|
-
|
|
1958
|
+
const value = {
|
|
1959
|
+
user,
|
|
1960
|
+
token,
|
|
1961
|
+
isAuthenticated: hasCheckedUrlToken && (!!token || isGuest),
|
|
1962
|
+
isGuest,
|
|
1963
|
+
logout
|
|
1965
1964
|
};
|
|
1966
|
-
|
|
1967
|
-
|
|
1965
|
+
if (!hasCheckedUrlToken) return null;
|
|
1966
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1967
|
+
ThemeProvider,
|
|
1968
1968
|
{
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1969
|
+
defaultTheme,
|
|
1970
|
+
storageKey: themeStorageKey,
|
|
1971
|
+
forceDefault: forceDefaultTheme,
|
|
1972
|
+
children: [
|
|
1973
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ElementSelectorProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(HowoneContext.Provider, { value, children: [
|
|
1974
|
+
children,
|
|
1975
|
+
showFloatingButton && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FloatingButton, { onClick: () => window.open("https://howone.ai", "_blank") }),
|
|
1976
|
+
pendingRedirect && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1977
|
+
"div",
|
|
1978
|
+
{
|
|
1979
|
+
"data-howone-auth-overlay-root": true,
|
|
1980
|
+
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",
|
|
1981
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "relative mt-6 flex h-[220px] w-[220px] items-center justify-center", children: [
|
|
1982
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1983
|
+
"div",
|
|
1984
|
+
{
|
|
1985
|
+
className: "absolute inset-0 rounded-full bg-white/20",
|
|
1986
|
+
style: { animation: "howone-glow-ring 2.4s ease-in-out infinite" }
|
|
1987
|
+
}
|
|
1988
|
+
),
|
|
1989
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "absolute inset-0 rounded-full bg-gradient-to-br from-white/10 via-white/25 to-white/10 blur-2xl" }),
|
|
1990
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1991
|
+
"img",
|
|
1992
|
+
{
|
|
1993
|
+
style: { width: 250, animation: "howone-logo-pulse 2s ease-in-out infinite" },
|
|
1994
|
+
src: "https://sxwxqoixnnklnpeutjrj.supabase.co/storage/v1/object/public/create-x/logo/logo.svg",
|
|
1995
|
+
alt: "HowOne"
|
|
1996
|
+
}
|
|
1997
|
+
)
|
|
1998
|
+
] })
|
|
1999
|
+
}
|
|
2000
|
+
)
|
|
2001
|
+
] }) }),
|
|
2002
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(GlobalToastContainer, {})
|
|
2003
|
+
]
|
|
1983
2004
|
}
|
|
1984
2005
|
);
|
|
1985
|
-
}
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
};
|
|
2001
|
-
const themeConfig = getThemeConfig();
|
|
2002
|
-
const lightBaseBackgroundByType = {
|
|
2003
|
-
success: "#f0fdf4",
|
|
2004
|
-
// green-50
|
|
2005
|
-
error: "#fef2f2",
|
|
2006
|
-
// red-50
|
|
2007
|
-
warning: "#fffbeb",
|
|
2008
|
-
// amber-50
|
|
2009
|
-
info: "#eff6ff",
|
|
2010
|
-
// blue-50
|
|
2011
|
-
default: "#f9fafb"
|
|
2012
|
-
// gray-50
|
|
2013
|
-
};
|
|
2014
|
-
if (component) {
|
|
2015
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `flex items-start gap-3 !min-h-[90px] w-full backdrop-blur-md p-4 shadow-2xl overflow-hidden ${themeConfig.bgGradient}`, children: [
|
|
2016
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex-1 relative z-10", children: component }),
|
|
2017
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "relative z-10", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CloseButton, { closeToast: handleClose }) })
|
|
2018
|
-
] });
|
|
2019
|
-
}
|
|
2020
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("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: [
|
|
2021
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2022
|
-
"div",
|
|
2023
|
-
{
|
|
2024
|
-
className: "absolute left-0 top-0 w-full h-full rounded-xl",
|
|
2025
|
-
style: {
|
|
2026
|
-
background: theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "#0f1419" : lightBaseBackgroundByType[type],
|
|
2027
|
-
zIndex: -2
|
|
2006
|
+
};
|
|
2007
|
+
function useHowoneContext() {
|
|
2008
|
+
const ctx = (0, import_react11.useContext)(HowoneContext);
|
|
2009
|
+
if (!ctx) {
|
|
2010
|
+
const t = getToken();
|
|
2011
|
+
const guestMode = isGuestMode() || !!getExistingSessionId();
|
|
2012
|
+
return {
|
|
2013
|
+
user: parseUserFromToken(t),
|
|
2014
|
+
token: t,
|
|
2015
|
+
isAuthenticated: !!t || guestMode,
|
|
2016
|
+
isGuest: guestMode,
|
|
2017
|
+
logout: () => {
|
|
2018
|
+
try {
|
|
2019
|
+
setToken(null);
|
|
2020
|
+
} catch {
|
|
2028
2021
|
}
|
|
2029
2022
|
}
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2023
|
+
};
|
|
2024
|
+
}
|
|
2025
|
+
return ctx;
|
|
2026
|
+
}
|
|
2027
|
+
|
|
2028
|
+
// src/components/index.ts
|
|
2029
|
+
init_auth();
|
|
2030
|
+
|
|
2031
|
+
// src/howone/client.ts
|
|
2032
|
+
init_auth();
|
|
2033
|
+
init_config();
|
|
2034
|
+
var HowoneAuthClient = class {
|
|
2035
|
+
constructor() {
|
|
2036
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
2037
|
+
this.loading = false;
|
|
2038
|
+
}
|
|
2039
|
+
emit() {
|
|
2040
|
+
const state = {
|
|
2041
|
+
user: parseUserFromToken(getToken()),
|
|
2042
|
+
isLoading: this.loading
|
|
2043
|
+
};
|
|
2044
|
+
for (const l of this.listeners) {
|
|
2045
|
+
try {
|
|
2046
|
+
l(state);
|
|
2047
|
+
} catch (e) {
|
|
2048
|
+
void e;
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
onAuthStateChanged(listener) {
|
|
2053
|
+
this.listeners.add(listener);
|
|
2054
|
+
try {
|
|
2055
|
+
listener({ user: parseUserFromToken(getToken()), isLoading: this.loading });
|
|
2056
|
+
} catch (e) {
|
|
2057
|
+
void e;
|
|
2058
|
+
}
|
|
2059
|
+
return () => {
|
|
2060
|
+
this.listeners.delete(listener);
|
|
2061
|
+
};
|
|
2062
|
+
}
|
|
2063
|
+
// Simple redirect-based login trigger (consumer can override)
|
|
2064
|
+
login() {
|
|
2065
|
+
const root = getEnvs().AUTH_ROOT_VALUE;
|
|
2066
|
+
try {
|
|
2067
|
+
const loc = window.location.href;
|
|
2068
|
+
const authUrl = new URL("/auth", String(root));
|
|
2069
|
+
authUrl.searchParams.set("redirect_uri", String(loc));
|
|
2070
|
+
try {
|
|
2071
|
+
const cfg = (init_config(), __toCommonJS(config_exports));
|
|
2072
|
+
const pid = cfg.getDefaultProjectId && cfg.getDefaultProjectId();
|
|
2073
|
+
if (pid) authUrl.searchParams.set("project_id", String(pid));
|
|
2074
|
+
} catch {
|
|
2075
|
+
}
|
|
2076
|
+
try {
|
|
2077
|
+
if (window.top && window.top !== window) {
|
|
2078
|
+
window.top.location.replace(authUrl.toString());
|
|
2079
|
+
} else {
|
|
2080
|
+
window.location.replace(authUrl.toString());
|
|
2081
|
+
}
|
|
2082
|
+
} catch {
|
|
2083
|
+
try {
|
|
2084
|
+
window.location.replace(String(root));
|
|
2085
|
+
} catch {
|
|
2038
2086
|
}
|
|
2039
2087
|
}
|
|
2040
|
-
|
|
2041
|
-
|
|
2088
|
+
} catch {
|
|
2089
|
+
try {
|
|
2090
|
+
window.location.replace(String(root));
|
|
2091
|
+
} catch {
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
logout() {
|
|
2096
|
+
setToken(null);
|
|
2097
|
+
this.emit();
|
|
2098
|
+
}
|
|
2099
|
+
getUser() {
|
|
2100
|
+
return parseUserFromToken(getToken());
|
|
2101
|
+
}
|
|
2102
|
+
// helper to programmatically set token (e.g., after callback handling)
|
|
2103
|
+
setToken(token) {
|
|
2104
|
+
setToken(token);
|
|
2105
|
+
this.emit();
|
|
2106
|
+
}
|
|
2107
|
+
};
|
|
2108
|
+
var howone = {
|
|
2109
|
+
auth: new HowoneAuthClient()
|
|
2110
|
+
};
|
|
2111
|
+
var client_default = howone;
|
|
2112
|
+
|
|
2113
|
+
// src/components/ui/Loading.tsx
|
|
2114
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2115
|
+
var Loading = ({
|
|
2116
|
+
size = "md",
|
|
2117
|
+
text = "Loading...",
|
|
2118
|
+
className = "",
|
|
2119
|
+
fullScreen = false
|
|
2120
|
+
}) => {
|
|
2121
|
+
const sizeClasses = {
|
|
2122
|
+
sm: "h-4 w-4",
|
|
2123
|
+
md: "h-8 w-8",
|
|
2124
|
+
lg: "h-12 w-12"
|
|
2125
|
+
};
|
|
2126
|
+
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";
|
|
2127
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: `${containerClasses} ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "text-center", children: [
|
|
2128
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2042
2129
|
"div",
|
|
2043
2130
|
{
|
|
2044
|
-
className:
|
|
2045
|
-
style: {
|
|
2046
|
-
border: "2px solid transparent",
|
|
2047
|
-
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%)`,
|
|
2048
|
-
backgroundOrigin: "border-box",
|
|
2049
|
-
backgroundClip: "border-box",
|
|
2050
|
-
WebkitMask: "linear-gradient(#ffffff 0 0) padding-box, linear-gradient(#ffffff 0 0)",
|
|
2051
|
-
WebkitMaskComposite: "xor",
|
|
2052
|
-
zIndex: 0
|
|
2053
|
-
}
|
|
2131
|
+
className: `animate-spin rounded-full border-2 border-gray-300 border-t-blue-600 mx-auto ${sizeClasses[size]}`
|
|
2054
2132
|
}
|
|
2055
2133
|
),
|
|
2056
|
-
/* @__PURE__ */ (0,
|
|
2057
|
-
|
|
2058
|
-
{
|
|
2059
|
-
className: "backdrop-blur-sm rounded-full flex items-center justify-center overflow-hidden flex-shrink-0 flex-grow-0",
|
|
2060
|
-
style: {
|
|
2061
|
-
backgroundColor: theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.05)",
|
|
2062
|
-
width: "28px",
|
|
2063
|
-
height: "28px"
|
|
2064
|
-
},
|
|
2065
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rounded-full flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2066
|
-
import_react12.Icon,
|
|
2067
|
-
{
|
|
2068
|
-
icon: iconConfig.icon,
|
|
2069
|
-
width: 16,
|
|
2070
|
-
height: 16,
|
|
2071
|
-
className: `flex-shrink-0`,
|
|
2072
|
-
style: {
|
|
2073
|
-
color: themeConfig.gradientColor,
|
|
2074
|
-
display: "block"
|
|
2075
|
-
}
|
|
2076
|
-
}
|
|
2077
|
-
) })
|
|
2078
|
-
}
|
|
2079
|
-
) }),
|
|
2080
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col gap-1 flex-1 relative z-10", children: [
|
|
2081
|
-
title && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2082
|
-
"div",
|
|
2083
|
-
{
|
|
2084
|
-
className: "text-[16px] font-semibold leading-tight drop-shadow-sm",
|
|
2085
|
-
style: {
|
|
2086
|
-
color: getTextColor(),
|
|
2087
|
-
backgroundClip: "text"
|
|
2088
|
-
},
|
|
2089
|
-
children: title
|
|
2090
|
-
}
|
|
2091
|
-
),
|
|
2092
|
-
message && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2093
|
-
"div",
|
|
2094
|
-
{
|
|
2095
|
-
className: "text-[13px] font-normal leading-relaxed drop-shadow-sm",
|
|
2096
|
-
style: {
|
|
2097
|
-
color: getTextColor(),
|
|
2098
|
-
backgroundClip: "text"
|
|
2099
|
-
},
|
|
2100
|
-
children: message
|
|
2101
|
-
}
|
|
2102
|
-
)
|
|
2103
|
-
] }),
|
|
2104
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "relative z-10", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CloseButton, { closeToast: handleClose }) })
|
|
2105
|
-
] });
|
|
2134
|
+
text && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "mt-2 text-sm text-gray-600", children: text })
|
|
2135
|
+
] }) });
|
|
2106
2136
|
};
|
|
2107
|
-
var
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2137
|
+
var LoadingSpinner = ({
|
|
2138
|
+
size = "md",
|
|
2139
|
+
className = ""
|
|
2140
|
+
}) => {
|
|
2141
|
+
const sizeClasses = {
|
|
2142
|
+
sm: "h-4 w-4",
|
|
2143
|
+
md: "h-8 w-8",
|
|
2144
|
+
lg: "h-12 w-12"
|
|
2145
|
+
};
|
|
2146
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2147
|
+
"div",
|
|
2148
|
+
{
|
|
2149
|
+
className: `animate-spin rounded-full border-2 border-gray-300 border-t-blue-600 ${sizeClasses[size]} ${className}`
|
|
2150
|
+
}
|
|
2151
|
+
);
|
|
2116
2152
|
};
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2153
|
+
|
|
2154
|
+
// src/components/ui/ErrorBoundary.tsx
|
|
2155
|
+
var import_react12 = require("react");
|
|
2156
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2157
|
+
var ErrorBoundary = class extends import_react12.Component {
|
|
2158
|
+
constructor(props) {
|
|
2159
|
+
super(props);
|
|
2160
|
+
this.handleRetry = () => {
|
|
2161
|
+
this.setState({ hasError: false, error: void 0, errorInfo: void 0 });
|
|
2162
|
+
};
|
|
2163
|
+
this.state = { hasError: false };
|
|
2123
2164
|
}
|
|
2124
|
-
|
|
2125
|
-
};
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2165
|
+
static getDerivedStateFromError(error) {
|
|
2166
|
+
return { hasError: true, error };
|
|
2167
|
+
}
|
|
2168
|
+
componentDidCatch(error, errorInfo) {
|
|
2169
|
+
this.setState({
|
|
2170
|
+
error,
|
|
2171
|
+
errorInfo
|
|
2172
|
+
});
|
|
2173
|
+
this.props.onError?.(error, errorInfo);
|
|
2174
|
+
}
|
|
2175
|
+
render() {
|
|
2176
|
+
if (this.state.hasError) {
|
|
2177
|
+
if (this.props.fallback) {
|
|
2178
|
+
const FallbackComponent = this.props.fallback;
|
|
2179
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(FallbackComponent, { error: this.state.error, retry: this.handleRetry });
|
|
2180
|
+
}
|
|
2181
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "min-h-[400px] flex items-center justify-center p-4", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "text-center max-w-md", children: [
|
|
2182
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "text-red-500 text-6xl mb-4", children: "\u26A0\uFE0F" }),
|
|
2183
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h2", { className: "text-xl font-semibold text-gray-900 mb-2", children: "Something went wrong" }),
|
|
2184
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-gray-600 mb-4", children: "An unexpected error occurred. Please try refreshing the page." }),
|
|
2185
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2186
|
+
"button",
|
|
2134
2187
|
{
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
component,
|
|
2139
|
-
closeToast
|
|
2188
|
+
onClick: this.handleRetry,
|
|
2189
|
+
className: "px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors",
|
|
2190
|
+
children: "Try Again"
|
|
2140
2191
|
}
|
|
2141
|
-
)
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
// 确保圆角样式不被覆盖,添加 rounded-xl 类
|
|
2148
|
-
className: "!p-0 !shadow-none !rounded-xl",
|
|
2149
|
-
style: { padding: 0, borderRadius: "0.75rem", backgroundColor: "transparent" }
|
|
2150
|
-
}
|
|
2151
|
-
);
|
|
2152
|
-
};
|
|
2192
|
+
),
|
|
2193
|
+
false
|
|
2194
|
+
] }) });
|
|
2195
|
+
}
|
|
2196
|
+
return this.props.children;
|
|
2197
|
+
}
|
|
2153
2198
|
};
|
|
2154
|
-
var
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2199
|
+
var DefaultErrorFallback = ({ retry }) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "min-h-[200px] flex items-center justify-center p-4", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "text-center", children: [
|
|
2200
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "text-red-500 text-4xl mb-2", children: "\u26A0\uFE0F" }),
|
|
2201
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-gray-600 mb-2", children: "Something went wrong" }),
|
|
2202
|
+
retry && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2203
|
+
"button",
|
|
2204
|
+
{
|
|
2205
|
+
onClick: retry,
|
|
2206
|
+
className: "px-3 py-1 bg-blue-600 text-white text-sm rounded hover:bg-blue-700 transition-colors",
|
|
2207
|
+
children: "Retry"
|
|
2208
|
+
}
|
|
2209
|
+
)
|
|
2210
|
+
] }) });
|
|
2211
|
+
|
|
2212
|
+
// src/components/ui/ClayxButton.tsx
|
|
2213
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2214
|
+
var getSizeClasses = (size, isIconOnly) => {
|
|
2215
|
+
if (isIconOnly) {
|
|
2216
|
+
switch (size) {
|
|
2217
|
+
case "sm":
|
|
2218
|
+
return "h-8 w-8 min-w-8 p-0";
|
|
2219
|
+
case "md":
|
|
2220
|
+
return "h-10 w-10 min-w-10 p-0";
|
|
2221
|
+
case "lg":
|
|
2222
|
+
return "h-12 w-12 min-w-12 p-0";
|
|
2223
|
+
default:
|
|
2224
|
+
return "h-10 w-10 min-w-10 p-0";
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
switch (size) {
|
|
2228
|
+
case "sm":
|
|
2229
|
+
return "h-8 px-3 text-sm";
|
|
2230
|
+
case "md":
|
|
2231
|
+
return "h-10 px-4 text-base";
|
|
2232
|
+
case "lg":
|
|
2233
|
+
return "h-12 px-6 text-lg";
|
|
2234
|
+
default:
|
|
2235
|
+
return "h-10 px-4 text-base";
|
|
2236
|
+
}
|
|
2237
|
+
};
|
|
2238
|
+
var getVariantClasses = (variant) => {
|
|
2239
|
+
switch (variant) {
|
|
2240
|
+
case "solid":
|
|
2241
|
+
return "bg-primary text-white hover:bg-primary/90";
|
|
2242
|
+
case "ghost":
|
|
2243
|
+
return "bg-transparent hover:bg-white/10";
|
|
2244
|
+
case "flat":
|
|
2245
|
+
return "bg-white/5 hover:bg-white/10";
|
|
2246
|
+
default:
|
|
2247
|
+
return "";
|
|
2248
|
+
}
|
|
2249
|
+
};
|
|
2250
|
+
var ClayxButton = ({
|
|
2251
|
+
isIconOnly = false,
|
|
2252
|
+
size = "md",
|
|
2253
|
+
variant = "solid",
|
|
2254
|
+
className = "",
|
|
2255
|
+
children,
|
|
2256
|
+
disabled = false,
|
|
2257
|
+
...props
|
|
2258
|
+
}) => {
|
|
2259
|
+
const sizeClasses = getSizeClasses(size, isIconOnly);
|
|
2260
|
+
const variantClasses = getVariantClasses(variant);
|
|
2261
|
+
const baseClasses = `
|
|
2262
|
+
inline-flex items-center justify-center
|
|
2263
|
+
rounded-md font-medium
|
|
2264
|
+
transition-all duration-200
|
|
2265
|
+
focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-transparent
|
|
2266
|
+
disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none
|
|
2267
|
+
`.replace(/\s+/g, " ").trim();
|
|
2268
|
+
const combinedClasses = `${baseClasses} ${sizeClasses} ${variantClasses} ${className}`.trim();
|
|
2269
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2270
|
+
"button",
|
|
2271
|
+
{
|
|
2272
|
+
className: combinedClasses,
|
|
2273
|
+
disabled,
|
|
2274
|
+
...props,
|
|
2275
|
+
children
|
|
2276
|
+
}
|
|
2277
|
+
);
|
|
2160
2278
|
};
|
|
2161
2279
|
|
|
2162
2280
|
// src/components/ui/LimitUpgradeToast.tsx
|
|
2281
|
+
var import_react13 = __toESM(require("react"));
|
|
2282
|
+
var import_react14 = require("@iconify/react");
|
|
2163
2283
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2164
|
-
var
|
|
2284
|
+
var PremiumActionToast = ({
|
|
2285
|
+
message,
|
|
2286
|
+
onAction,
|
|
2287
|
+
closeToast,
|
|
2288
|
+
buttonText = "Upgrade Now",
|
|
2289
|
+
title = "Information",
|
|
2290
|
+
variant = "purple"
|
|
2291
|
+
}) => {
|
|
2165
2292
|
const [hover, setHover] = import_react13.default.useState(false);
|
|
2166
2293
|
const [closeHover, setCloseHover] = import_react13.default.useState(false);
|
|
2167
|
-
|
|
2294
|
+
const colors = {
|
|
2295
|
+
purple: {
|
|
2296
|
+
gradient1: "rgba(168,85,247,0.3)",
|
|
2297
|
+
gradient2: "rgba(168,85,247,0.2)",
|
|
2298
|
+
borderStart: "rgba(168,85,247,0.8)",
|
|
2299
|
+
borderEnd: "rgba(168,85,247,0.5)",
|
|
2300
|
+
bgGlow1: "from-purple-500/20 via-pink-500/10",
|
|
2301
|
+
bgGlow2: "from-blue-500/10",
|
|
2302
|
+
tagBg: "bg-purple-500/30",
|
|
2303
|
+
tagText: "text-white",
|
|
2304
|
+
tagBorder: "border border-purple-400/50",
|
|
2305
|
+
borderColor: "#a855f7",
|
|
2306
|
+
btnGradient: hover ? "linear-gradient(to right, #9333ea, #db2777)" : "linear-gradient(to right, #a855f7, #ec4899)",
|
|
2307
|
+
btnShadow: "0 10px 15px -3px rgba(168,85,247,0.3), 0 4px 6px -2px rgba(168,85,247,0.3)",
|
|
2308
|
+
shadow: "0_20px_60px_rgba(168,85,247,0.2)",
|
|
2309
|
+
badge: "Premium"
|
|
2310
|
+
},
|
|
2311
|
+
blue: {
|
|
2312
|
+
gradient1: "rgba(59,130,246,0.3)",
|
|
2313
|
+
gradient2: "rgba(59,130,246,0.2)",
|
|
2314
|
+
borderStart: "rgba(59,130,246,0.8)",
|
|
2315
|
+
borderEnd: "rgba(59,130,246,0.5)",
|
|
2316
|
+
bgGlow1: "from-blue-500/20 via-cyan-500/10",
|
|
2317
|
+
bgGlow2: "from-indigo-500/10",
|
|
2318
|
+
tagBg: "bg-blue-500/30",
|
|
2319
|
+
tagText: "text-white",
|
|
2320
|
+
tagBorder: "border border-blue-400/50",
|
|
2321
|
+
borderColor: "#3b82f6",
|
|
2322
|
+
btnGradient: hover ? "linear-gradient(to right, #1d4ed8, #0ea5e9)" : "linear-gradient(to right, #3b82f6, #06b6d4)",
|
|
2323
|
+
btnShadow: "0 10px 15px -3px rgba(59,130,246,0.3), 0 4px 6px -2px rgba(59,130,246,0.3)",
|
|
2324
|
+
shadow: "0_20px_60px_rgba(59,130,246,0.2)",
|
|
2325
|
+
badge: "Secure"
|
|
2326
|
+
}
|
|
2327
|
+
}[variant];
|
|
2328
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("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: [
|
|
2168
2329
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2169
2330
|
"div",
|
|
2170
2331
|
{
|
|
@@ -2180,7 +2341,7 @@ var LimitToastContainer = ({ message, onUpgrade, closeToast }) => {
|
|
|
2180
2341
|
{
|
|
2181
2342
|
className: "absolute left-0 top-0 w-full h-full pointer-events-none rounded-md",
|
|
2182
2343
|
style: {
|
|
2183
|
-
background: `linear-gradient(135deg,
|
|
2344
|
+
background: `linear-gradient(135deg, ${colors.gradient1} 0%, ${colors.gradient2} 15%, #1A1A1A 30%)`,
|
|
2184
2345
|
zIndex: -1
|
|
2185
2346
|
}
|
|
2186
2347
|
}
|
|
@@ -2191,7 +2352,7 @@ var LimitToastContainer = ({ message, onUpgrade, closeToast }) => {
|
|
|
2191
2352
|
className: "absolute left-0 top-0 w-full h-full pointer-events-none rounded-md",
|
|
2192
2353
|
style: {
|
|
2193
2354
|
border: "2px solid transparent",
|
|
2194
|
-
backgroundImage: `linear-gradient(135deg,
|
|
2355
|
+
backgroundImage: `linear-gradient(135deg, ${colors.borderStart} 0%, ${colors.borderEnd} 5%, transparent 22%)`,
|
|
2195
2356
|
backgroundOrigin: "border-box",
|
|
2196
2357
|
backgroundClip: "border-box",
|
|
2197
2358
|
WebkitMask: "linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0)",
|
|
@@ -2201,13 +2362,20 @@ var LimitToastContainer = ({ message, onUpgrade, closeToast }) => {
|
|
|
2201
2362
|
}
|
|
2202
2363
|
}
|
|
2203
2364
|
),
|
|
2204
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className:
|
|
2205
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className:
|
|
2365
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("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` }),
|
|
2366
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("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" } }),
|
|
2206
2367
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "relative z-10 flex items-start gap-4 p-4", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-1 flex-col gap-3", children: [
|
|
2207
2368
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
2208
2369
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2209
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-lg font-bold text-white", children:
|
|
2210
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2370
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-lg font-bold text-white", children: title }),
|
|
2371
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2372
|
+
"div",
|
|
2373
|
+
{
|
|
2374
|
+
className: `px-2 py-0.5 text-xs font-bold ${colors.tagBg} ${colors.tagText} rounded-md border`,
|
|
2375
|
+
style: { borderColor: colors.borderColor },
|
|
2376
|
+
children: colors.badge
|
|
2377
|
+
}
|
|
2378
|
+
)
|
|
2211
2379
|
] }),
|
|
2212
2380
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2213
2381
|
ClayxButton,
|
|
@@ -2226,16 +2394,16 @@ var LimitToastContainer = ({ message, onUpgrade, closeToast }) => {
|
|
|
2226
2394
|
transition: "background-color 150ms ease",
|
|
2227
2395
|
cursor: "pointer"
|
|
2228
2396
|
},
|
|
2229
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react14.Icon, { icon: "iconamoon:close", className: "w-4 h-4 text-gray-
|
|
2397
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react14.Icon, { icon: "iconamoon:close", className: "w-4 h-4 text-gray-300" })
|
|
2230
2398
|
}
|
|
2231
2399
|
)
|
|
2232
2400
|
] }),
|
|
2233
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-sm text-
|
|
2401
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-sm text-white leading-relaxed font-medium", children: message }),
|
|
2234
2402
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "mt-1 flex items-center gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2235
2403
|
ClayxButton,
|
|
2236
2404
|
{
|
|
2237
2405
|
onClick: () => {
|
|
2238
|
-
|
|
2406
|
+
onAction();
|
|
2239
2407
|
closeToast?.();
|
|
2240
2408
|
},
|
|
2241
2409
|
onMouseEnter: () => setHover(true),
|
|
@@ -2246,21 +2414,31 @@ var LimitToastContainer = ({ message, onUpgrade, closeToast }) => {
|
|
|
2246
2414
|
fontWeight: 600,
|
|
2247
2415
|
cursor: "pointer",
|
|
2248
2416
|
transition: "all 300ms ease-in-out",
|
|
2249
|
-
backgroundImage:
|
|
2250
|
-
boxShadow: hover ?
|
|
2417
|
+
backgroundImage: colors.btnGradient,
|
|
2418
|
+
boxShadow: hover ? colors.btnShadow : "none"
|
|
2251
2419
|
},
|
|
2252
2420
|
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "flex items-center gap-2", children: [
|
|
2253
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react14.Icon, { icon: "solar:rocket-2-bold", className: "w-4 h-4" }),
|
|
2254
|
-
|
|
2421
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react14.Icon, { icon: variant === "purple" ? "solar:rocket-2-bold" : "solar:login-3-bold", className: "w-4 h-4" }),
|
|
2422
|
+
buttonText
|
|
2255
2423
|
] })
|
|
2256
2424
|
}
|
|
2257
2425
|
) })
|
|
2258
2426
|
] }) })
|
|
2259
2427
|
] });
|
|
2260
2428
|
};
|
|
2261
|
-
function
|
|
2429
|
+
function showPremiumActionToast(message, onAction, buttonText, title, variant = "purple") {
|
|
2262
2430
|
ClayxToast.default({
|
|
2263
|
-
render: (closeToast) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2431
|
+
render: (closeToast) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2432
|
+
PremiumActionToast,
|
|
2433
|
+
{
|
|
2434
|
+
message,
|
|
2435
|
+
onAction,
|
|
2436
|
+
closeToast,
|
|
2437
|
+
buttonText,
|
|
2438
|
+
title,
|
|
2439
|
+
variant
|
|
2440
|
+
}
|
|
2441
|
+
),
|
|
2264
2442
|
options: {
|
|
2265
2443
|
position: "bottom-right",
|
|
2266
2444
|
closeOnClick: false,
|
|
@@ -2278,6 +2456,12 @@ function showLimitUpgradeToast(message, onUpgrade) {
|
|
|
2278
2456
|
}
|
|
2279
2457
|
});
|
|
2280
2458
|
}
|
|
2459
|
+
function showLimitUpgradeToast(message, onUpgrade, buttonText, title) {
|
|
2460
|
+
showPremiumActionToast(message, onUpgrade, buttonText, title, "purple");
|
|
2461
|
+
}
|
|
2462
|
+
function showSignInRequiredToast(message, onSignIn, buttonText, title) {
|
|
2463
|
+
showPremiumActionToast(message, onSignIn, buttonText, title, "blue");
|
|
2464
|
+
}
|
|
2281
2465
|
|
|
2282
2466
|
// src/services/ai-workflow.ts
|
|
2283
2467
|
var AIWorkflowClient = class {
|
|
@@ -2653,6 +2837,15 @@ async function executeSSEWorkflow(request, options = {}) {
|
|
|
2653
2837
|
};
|
|
2654
2838
|
if (options.authToken) {
|
|
2655
2839
|
headers["Authorization"] = `Bearer ${options.authToken}`;
|
|
2840
|
+
} else {
|
|
2841
|
+
try {
|
|
2842
|
+
const { getGuestSessionId: getGuestSessionId2 } = (init_session(), __toCommonJS(session_exports));
|
|
2843
|
+
const sessionId = getGuestSessionId2?.();
|
|
2844
|
+
if (sessionId) {
|
|
2845
|
+
headers["X-Session-Id"] = sessionId;
|
|
2846
|
+
}
|
|
2847
|
+
} catch {
|
|
2848
|
+
}
|
|
2656
2849
|
}
|
|
2657
2850
|
const method = request.method?.toUpperCase() ?? "POST";
|
|
2658
2851
|
const hasBody = request.body && Object.keys(request.body).length > 0;
|
|
@@ -2667,7 +2860,23 @@ async function executeSSEWorkflow(request, options = {}) {
|
|
|
2667
2860
|
signal: options.signal
|
|
2668
2861
|
});
|
|
2669
2862
|
if (!response.ok) {
|
|
2670
|
-
|
|
2863
|
+
if (response.status === 403) {
|
|
2864
|
+
showSignInRequiredToast(
|
|
2865
|
+
"Free trial limit reached. Please sign in to continue.",
|
|
2866
|
+
() => {
|
|
2867
|
+
const authUrl = getEnvs().AUTH_ROOT_VALUE;
|
|
2868
|
+
const redirectUri = window.location.href;
|
|
2869
|
+
const projectId = getDefaultProjectId();
|
|
2870
|
+
let authHref = `${authUrl}/auth?redirect_uri=${encodeURIComponent(redirectUri)}`;
|
|
2871
|
+
if (projectId) {
|
|
2872
|
+
authHref += `&project_id=${encodeURIComponent(projectId)}`;
|
|
2873
|
+
}
|
|
2874
|
+
window.location.href = authHref;
|
|
2875
|
+
},
|
|
2876
|
+
"Sign In",
|
|
2877
|
+
"Sign In Required"
|
|
2878
|
+
);
|
|
2879
|
+
}
|
|
2671
2880
|
}
|
|
2672
2881
|
const reader = response.body?.getReader();
|
|
2673
2882
|
if (!reader) {
|
|
@@ -3420,6 +3629,15 @@ function createClient(opts) {
|
|
|
3420
3629
|
const availableToken = getAvailableToken();
|
|
3421
3630
|
if (availableToken) {
|
|
3422
3631
|
config.headers["Authorization"] = `Bearer ${availableToken}`;
|
|
3632
|
+
} else {
|
|
3633
|
+
try {
|
|
3634
|
+
const { getGuestSessionId: getGuestSessionId2 } = (init_session(), __toCommonJS(session_exports));
|
|
3635
|
+
const sessionId = getGuestSessionId2?.();
|
|
3636
|
+
if (sessionId) {
|
|
3637
|
+
config.headers["X-Session-Id"] = sessionId;
|
|
3638
|
+
}
|
|
3639
|
+
} catch {
|
|
3640
|
+
}
|
|
3423
3641
|
}
|
|
3424
3642
|
}
|
|
3425
3643
|
return config;
|
|
@@ -4222,6 +4440,9 @@ var elementSelector = {
|
|
|
4222
4440
|
*/
|
|
4223
4441
|
isActive: () => getElementSelectorState().active
|
|
4224
4442
|
};
|
|
4443
|
+
|
|
4444
|
+
// src/index.ts
|
|
4445
|
+
init_session();
|
|
4225
4446
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4226
4447
|
0 && (module.exports = {
|
|
4227
4448
|
AUTH_TOKEN_KEY,
|
|
@@ -4241,6 +4462,7 @@ var elementSelector = {
|
|
|
4241
4462
|
ThemeToggle,
|
|
4242
4463
|
aiWorkflow,
|
|
4243
4464
|
canAccessArtifact,
|
|
4465
|
+
clearGuestSession,
|
|
4244
4466
|
createAIWorkflowClient,
|
|
4245
4467
|
createAIWorkflowClientAxios,
|
|
4246
4468
|
createArtifactsClient,
|
|
@@ -4255,10 +4477,12 @@ var elementSelector = {
|
|
|
4255
4477
|
getEnvironment,
|
|
4256
4478
|
getEnvs,
|
|
4257
4479
|
getGlobalEnvironment,
|
|
4480
|
+
getGuestSessionId,
|
|
4258
4481
|
getToken,
|
|
4259
4482
|
howone,
|
|
4260
4483
|
iframeNavigation,
|
|
4261
4484
|
initIframeNavigation,
|
|
4485
|
+
isGuestMode,
|
|
4262
4486
|
isTokenValid,
|
|
4263
4487
|
loginWithEmailCode,
|
|
4264
4488
|
onAuthStateChanged,
|
|
@@ -4269,6 +4493,8 @@ var elementSelector = {
|
|
|
4269
4493
|
setEnvironment,
|
|
4270
4494
|
setToken,
|
|
4271
4495
|
showLimitUpgradeToast,
|
|
4496
|
+
showPremiumActionToast,
|
|
4497
|
+
showSignInRequiredToast,
|
|
4272
4498
|
unifiedAuth,
|
|
4273
4499
|
unifiedOAuth,
|
|
4274
4500
|
useAuth,
|