@howone/sdk 0.3.25 → 0.5.0

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