@kite-copilot/chat-panel 0.2.42 → 0.2.44

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.
@@ -882,7 +882,7 @@ function DataRenderer({ type, data }) {
882
882
  }
883
883
 
884
884
  // src/ChatPanel.tsx
885
- import * as React5 from "react";
885
+ import * as React6 from "react";
886
886
  import { createClient } from "@supabase/supabase-js";
887
887
  import { ArrowLeft, ArrowUp, Command, CornerDownLeft, CheckCircle2 as CheckCircle23, SquarePen, Paperclip, X, FileSpreadsheet, Loader2 as Loader22, ChevronLeft, ChevronRight, Sparkles, Minus } from "lucide-react";
888
888
 
@@ -897,9 +897,13 @@ function useUserAuth({
897
897
  const lastSessionIdRef = React4.useRef(null);
898
898
  const fetchUser = React4.useCallback(async () => {
899
899
  if (!productBackendUrl || !enabled) {
900
+ console.log("[useUserAuth] Skipping auth - productBackendUrl:", productBackendUrl, "enabled:", enabled);
900
901
  setAuthState({ status: "idle" });
901
902
  return;
902
903
  }
904
+ console.log("[useUserAuth] Starting auth request to product backend...");
905
+ console.log("[useUserAuth] Product backend URL:", productBackendUrl);
906
+ console.log("[useUserAuth] Full request URL:", `${productBackendUrl}/users/me`);
903
907
  setAuthState({ status: "loading" });
904
908
  try {
905
909
  const response = await fetch(`${productBackendUrl}/users/me`, {
@@ -910,7 +914,9 @@ function useUserAuth({
910
914
  "Accept": "application/json"
911
915
  }
912
916
  });
917
+ console.log("[useUserAuth] Response received - status:", response.status, "ok:", response.ok);
913
918
  if (!response.ok) {
919
+ console.log("[useUserAuth] Auth request failed with status:", response.status);
914
920
  if (response.status === 401) {
915
921
  throw new Error("Please log in to use the chat assistant.");
916
922
  }
@@ -920,8 +926,17 @@ function useUserAuth({
920
926
  throw new Error(`Authentication failed (${response.status})`);
921
927
  }
922
928
  const user = await response.json();
929
+ console.log("[useUserAuth] Auth SUCCESS - parsed user data:");
930
+ console.log("[useUserAuth] id:", user.id);
931
+ console.log("[useUserAuth] email:", user.email);
932
+ console.log("[useUserAuth] name:", user.name);
933
+ console.log("[useUserAuth] role:", user.role);
934
+ console.log("[useUserAuth] isInternal:", user.isInternal);
935
+ console.log("[useUserAuth] agreementsSigned:", user.agreementsSigned);
936
+ console.log("[useUserAuth] lastLoginTime:", user.lastLoginTime);
923
937
  setAuthState({ status: "authenticated", user });
924
938
  } catch (error) {
939
+ console.log("[useUserAuth] Auth ERROR:", error);
925
940
  const message = error instanceof Error ? error.message : "Unable to verify your identity. Please try again.";
926
941
  setAuthState({ status: "error", error: message });
927
942
  }
@@ -938,6 +953,47 @@ function useUserAuth({
938
953
  return { authState, retry };
939
954
  }
940
955
 
956
+ // src/hooks/useOrgConfig.ts
957
+ import * as React5 from "react";
958
+ function useOrgConfig({ agentUrl, orgId }) {
959
+ const [state, setState] = React5.useState({
960
+ status: "idle",
961
+ config: null,
962
+ error: null
963
+ });
964
+ React5.useEffect(() => {
965
+ if (!agentUrl || !orgId) {
966
+ console.log("[useOrgConfig] Skipping - missing agentUrl or orgId", { agentUrl, orgId });
967
+ return;
968
+ }
969
+ const fetchConfig = async () => {
970
+ setState({ status: "loading", config: null, error: null });
971
+ const url = `${agentUrl}/org/${orgId}/config`;
972
+ console.log("[useOrgConfig] Fetching org config from:", url);
973
+ try {
974
+ const response = await fetch(url, {
975
+ method: "GET",
976
+ headers: {
977
+ "Accept": "application/json"
978
+ }
979
+ });
980
+ if (!response.ok) {
981
+ throw new Error(`Failed to fetch org config (${response.status})`);
982
+ }
983
+ const config = await response.json();
984
+ console.log("[useOrgConfig] Received config:", config);
985
+ setState({ status: "success", config, error: null });
986
+ } catch (error) {
987
+ const message = error instanceof Error ? error.message : "Failed to fetch org config";
988
+ console.error("[useOrgConfig] Error:", message);
989
+ setState({ status: "error", config: null, error: message });
990
+ }
991
+ };
992
+ fetchConfig();
993
+ }, [agentUrl, orgId]);
994
+ return state;
995
+ }
996
+
941
997
  // src/components/TypingIndicator.tsx
942
998
  import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
943
999
  function TypingIndicator({ className = "" }) {
@@ -968,7 +1024,7 @@ function TypingIndicator({ className = "" }) {
968
1024
 
969
1025
  // src/ChatPanel.tsx
970
1026
  import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
971
- var CHAT_PANEL_VERSION = true ? "0.2.42" : "dev";
1027
+ var CHAT_PANEL_VERSION = true ? "0.2.44" : "dev";
972
1028
  var DEFAULT_AGENT_URL = "http://localhost:5002";
973
1029
  var PANEL_WIDTH = 340;
974
1030
  function unescapeJsonString(str) {
@@ -1432,16 +1488,18 @@ function ChatPanel({
1432
1488
  supabaseAnonKey,
1433
1489
  productBackendUrl
1434
1490
  } = {}) {
1435
- const [messages, setMessages] = React5.useState(initialMessages);
1436
- const [input, setInput] = React5.useState("");
1437
- const [sessionId, setSessionId] = React5.useState(() => crypto.randomUUID());
1491
+ const [messages, setMessages] = React6.useState(initialMessages);
1492
+ const [input, setInput] = React6.useState("");
1493
+ const [sessionId, setSessionId] = React6.useState(() => crypto.randomUUID());
1494
+ const orgConfigState = useOrgConfig({ agentUrl, orgId: orgId || "" });
1495
+ const effectiveProductBackendUrl = orgConfigState.config?.productBackendUrl || productBackendUrl;
1438
1496
  const { authState, retry: retryAuth } = useUserAuth({
1439
- productBackendUrl,
1497
+ productBackendUrl: effectiveProductBackendUrl,
1440
1498
  sessionId,
1441
- enabled: !!productBackendUrl
1442
- // Only enable if URL is provided
1499
+ enabled: !!effectiveProductBackendUrl && orgConfigState.status === "success"
1500
+ // Only enable after config is fetched
1443
1501
  });
1444
- const effectiveUser = React5.useMemo(() => {
1502
+ const effectiveUser = React6.useMemo(() => {
1445
1503
  if (authState.status === "authenticated") {
1446
1504
  return {
1447
1505
  userId: authState.user.id,
@@ -1459,16 +1517,16 @@ function ChatPanel({
1459
1517
  isInternal: false
1460
1518
  };
1461
1519
  }, [authState, userId, userName, userEmail]);
1462
- const [isEscalated, setIsEscalated] = React5.useState(false);
1463
- const escalationWsRef = React5.useRef(null);
1464
- const [agentIsTyping, setAgentIsTyping] = React5.useState(false);
1465
- const supabaseRef = React5.useRef(null);
1466
- const typingChannelRef = React5.useRef(null);
1467
- const typingTimeoutRef = React5.useRef(null);
1468
- React5.useEffect(() => {
1520
+ const [isEscalated, setIsEscalated] = React6.useState(false);
1521
+ const escalationWsRef = React6.useRef(null);
1522
+ const [agentIsTyping, setAgentIsTyping] = React6.useState(false);
1523
+ const supabaseRef = React6.useRef(null);
1524
+ const typingChannelRef = React6.useRef(null);
1525
+ const typingTimeoutRef = React6.useRef(null);
1526
+ React6.useEffect(() => {
1469
1527
  console.log(`[KiteChat] Chat Panel v${CHAT_PANEL_VERSION} loaded`);
1470
1528
  }, []);
1471
- const resetSession = React5.useCallback(() => {
1529
+ const resetSession = React6.useCallback(() => {
1472
1530
  console.log("[KiteChat] resetSession called", { isEscalated, hasSupabase: !!supabaseRef.current, sessionId });
1473
1531
  if (isEscalated && supabaseRef.current && sessionId) {
1474
1532
  console.log("[KiteChat] Updating customer_status to disconnected for session:", sessionId);
@@ -1498,12 +1556,12 @@ function ChatPanel({
1498
1556
  typingChannelRef.current = null;
1499
1557
  }
1500
1558
  }, [isEscalated, sessionId]);
1501
- React5.useEffect(() => {
1559
+ React6.useEffect(() => {
1502
1560
  if (supabaseUrl && supabaseAnonKey && !supabaseRef.current) {
1503
1561
  supabaseRef.current = createClient(supabaseUrl, supabaseAnonKey);
1504
1562
  }
1505
1563
  }, [supabaseUrl, supabaseAnonKey]);
1506
- React5.useEffect(() => {
1564
+ React6.useEffect(() => {
1507
1565
  if (!isEscalated || !sessionId || !supabaseRef.current) {
1508
1566
  return;
1509
1567
  }
@@ -1540,8 +1598,8 @@ function ChatPanel({
1540
1598
  }
1541
1599
  };
1542
1600
  }, [isEscalated, sessionId]);
1543
- const heartbeatIntervalRef = React5.useRef(null);
1544
- const updateCustomerStatus = React5.useCallback(async (status) => {
1601
+ const heartbeatIntervalRef = React6.useRef(null);
1602
+ const updateCustomerStatus = React6.useCallback(async (status) => {
1545
1603
  if (!supabaseRef.current || !sessionId) return;
1546
1604
  try {
1547
1605
  await supabaseRef.current.from("escalations").update({
@@ -1552,7 +1610,7 @@ function ChatPanel({
1552
1610
  console.error("[KiteChat] Failed to update customer status:", err);
1553
1611
  }
1554
1612
  }, [sessionId]);
1555
- React5.useEffect(() => {
1613
+ React6.useEffect(() => {
1556
1614
  if (!isEscalated || !sessionId || !supabaseRef.current) {
1557
1615
  return;
1558
1616
  }
@@ -1600,7 +1658,7 @@ function ChatPanel({
1600
1658
  }
1601
1659
  };
1602
1660
  }, [isEscalated, sessionId, updateCustomerStatus]);
1603
- const sendTypingIndicator = React5.useCallback((isTyping) => {
1661
+ const sendTypingIndicator = React6.useCallback((isTyping) => {
1604
1662
  if (!typingChannelRef.current) {
1605
1663
  console.log("[KiteChat] Cannot send typing - channel not ready");
1606
1664
  return;
@@ -1616,8 +1674,8 @@ function ChatPanel({
1616
1674
  payload: { sender: "user", isTyping }
1617
1675
  });
1618
1676
  }, [isEscalated]);
1619
- const userTypingTimeoutRef = React5.useRef(null);
1620
- const handleTypingStart = React5.useCallback(() => {
1677
+ const userTypingTimeoutRef = React6.useRef(null);
1678
+ const handleTypingStart = React6.useCallback(() => {
1621
1679
  if (!isEscalated || !supabaseRef.current) return;
1622
1680
  sendTypingIndicator(true);
1623
1681
  updateCustomerStatus("active");
@@ -1628,19 +1686,19 @@ function ChatPanel({
1628
1686
  sendTypingIndicator(false);
1629
1687
  }, 1500);
1630
1688
  }, [isEscalated, sendTypingIndicator, updateCustomerStatus]);
1631
- const streamIntervals = React5.useRef({});
1689
+ const streamIntervals = React6.useRef({});
1632
1690
  const isEmpty = messages.length === 0;
1633
- const [phase, setPhase] = React5.useState("idle");
1634
- const [progressSteps, setProgressSteps] = React5.useState([]);
1635
- const phaseTimers = React5.useRef([]);
1691
+ const [phase, setPhase] = React6.useState("idle");
1692
+ const [progressSteps, setProgressSteps] = React6.useState([]);
1693
+ const phaseTimers = React6.useRef([]);
1636
1694
  const lastRole = messages.length ? messages[messages.length - 1].role : void 0;
1637
- const [panelView, setPanelView] = React5.useState(
1695
+ const [panelView, setPanelView] = React6.useState(
1638
1696
  "landing"
1639
1697
  );
1640
- const [currentFolderId, setCurrentFolderId] = React5.useState(void 0);
1641
- const [startingQuestions, setStartingQuestions] = React5.useState(startingQuestionsProp || defaultStartingQuestions);
1642
- const [loadingQuestions, setLoadingQuestions] = React5.useState(false);
1643
- React5.useEffect(() => {
1698
+ const [currentFolderId, setCurrentFolderId] = React6.useState(void 0);
1699
+ const [startingQuestions, setStartingQuestions] = React6.useState(startingQuestionsProp || defaultStartingQuestions);
1700
+ const [loadingQuestions, setLoadingQuestions] = React6.useState(false);
1701
+ React6.useEffect(() => {
1644
1702
  if (startingQuestionsEndpoint && !startingQuestionsProp) {
1645
1703
  setLoadingQuestions(true);
1646
1704
  fetch(startingQuestionsEndpoint).then((res) => res.json()).then((data) => {
@@ -1652,16 +1710,16 @@ function ChatPanel({
1652
1710
  }).finally(() => setLoadingQuestions(false));
1653
1711
  }
1654
1712
  }, [startingQuestionsEndpoint, startingQuestionsProp]);
1655
- React5.useEffect(() => {
1713
+ React6.useEffect(() => {
1656
1714
  if (startingQuestionsProp) {
1657
1715
  setStartingQuestions(startingQuestionsProp);
1658
1716
  }
1659
1717
  }, [startingQuestionsProp]);
1660
- const [activeGuide, setActiveGuide] = React5.useState(void 0);
1661
- const activeGuideRef = React5.useRef(void 0);
1662
- const latestBulkSummaryNavigationRef = React5.useRef(null);
1663
- const [guideComplete, setGuideComplete] = React5.useState(false);
1664
- React5.useEffect(() => {
1718
+ const [activeGuide, setActiveGuide] = React6.useState(void 0);
1719
+ const activeGuideRef = React6.useRef(void 0);
1720
+ const latestBulkSummaryNavigationRef = React6.useRef(null);
1721
+ const [guideComplete, setGuideComplete] = React6.useState(false);
1722
+ React6.useEffect(() => {
1665
1723
  window.resetIntegrationNotification = () => {
1666
1724
  localStorage.removeItem("gmailNotificationSeen");
1667
1725
  console.log(
@@ -1695,7 +1753,7 @@ function ChatPanel({
1695
1753
  );
1696
1754
  };
1697
1755
  }, []);
1698
- React5.useEffect(() => {
1756
+ React6.useEffect(() => {
1699
1757
  if (activeGuide) {
1700
1758
  if (!activeGuideRef.current || activeGuideRef.current.id !== activeGuide.id || activeGuideRef.current.stepIndex !== activeGuide.stepIndex) {
1701
1759
  activeGuideRef.current = activeGuide;
@@ -1704,21 +1762,21 @@ function ChatPanel({
1704
1762
  activeGuideRef.current = void 0;
1705
1763
  }
1706
1764
  }, [activeGuide]);
1707
- const [pendingNavigation, setPendingNavigation] = React5.useState(null);
1708
- const [pendingAction, setPendingAction] = React5.useState(null);
1709
- const [actionFormData, setActionFormData] = React5.useState({});
1710
- const messagesEndRef = React5.useRef(null);
1711
- const messagesContainerRef = React5.useRef(null);
1712
- const currentStepRef = React5.useRef(null);
1765
+ const [pendingNavigation, setPendingNavigation] = React6.useState(null);
1766
+ const [pendingAction, setPendingAction] = React6.useState(null);
1767
+ const [actionFormData, setActionFormData] = React6.useState({});
1768
+ const messagesEndRef = React6.useRef(null);
1769
+ const messagesContainerRef = React6.useRef(null);
1770
+ const currentStepRef = React6.useRef(null);
1713
1771
  const { cursorState, moveTo, hide } = useGuideCursor();
1714
- const [pendingFile, setPendingFile] = React5.useState(null);
1715
- const [pendingBulkSession, setPendingBulkSession] = React5.useState(null);
1716
- const pendingBulkSessionRef = React5.useRef(null);
1717
- const fileInputRef = React5.useRef(null);
1718
- const [searchExpanded, setSearchExpanded] = React5.useState(false);
1719
- const [searchInput, setSearchInput] = React5.useState("");
1720
- const searchInputRef = React5.useRef(null);
1721
- React5.useEffect(() => {
1772
+ const [pendingFile, setPendingFile] = React6.useState(null);
1773
+ const [pendingBulkSession, setPendingBulkSession] = React6.useState(null);
1774
+ const pendingBulkSessionRef = React6.useRef(null);
1775
+ const fileInputRef = React6.useRef(null);
1776
+ const [searchExpanded, setSearchExpanded] = React6.useState(false);
1777
+ const [searchInput, setSearchInput] = React6.useState("");
1778
+ const searchInputRef = React6.useRef(null);
1779
+ React6.useEffect(() => {
1722
1780
  if (!activeGuide || activeGuide.id !== "add-api-key" || activeGuide.stepIndex !== 2) {
1723
1781
  return;
1724
1782
  }
@@ -1744,7 +1802,7 @@ function ChatPanel({
1744
1802
  const interval = setInterval(checkForDialogOpen, 300);
1745
1803
  return () => clearInterval(interval);
1746
1804
  }, [activeGuide, hide]);
1747
- React5.useEffect(() => {
1805
+ React6.useEffect(() => {
1748
1806
  return () => {
1749
1807
  Object.values(streamIntervals.current).forEach(
1750
1808
  (id) => window.clearInterval(id)
@@ -1754,7 +1812,7 @@ function ChatPanel({
1754
1812
  phaseTimers.current = [];
1755
1813
  };
1756
1814
  }, []);
1757
- React5.useEffect(() => {
1815
+ React6.useEffect(() => {
1758
1816
  if (activeGuide && messages.length > 0) {
1759
1817
  const lastMessage = messages[messages.length - 1];
1760
1818
  if (lastMessage.kind === "guideStep" || lastMessage.kind === "guideComplete") {
@@ -1771,7 +1829,7 @@ function ChatPanel({
1771
1829
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
1772
1830
  }
1773
1831
  }, [messages, phase, activeGuide]);
1774
- const latestBulkSummaryNavigation = React5.useMemo(() => {
1832
+ const latestBulkSummaryNavigation = React6.useMemo(() => {
1775
1833
  for (let i = messages.length - 1; i >= 0; i--) {
1776
1834
  const msg = messages[i];
1777
1835
  if (msg.kind === "bulkSummary" && msg.bulkSummary?.navigationPage && msg.bulkSummary.successes > 0) {
@@ -1780,13 +1838,13 @@ function ChatPanel({
1780
1838
  }
1781
1839
  return null;
1782
1840
  }, [messages]);
1783
- React5.useEffect(() => {
1841
+ React6.useEffect(() => {
1784
1842
  latestBulkSummaryNavigationRef.current = latestBulkSummaryNavigation;
1785
1843
  }, [latestBulkSummaryNavigation]);
1786
- React5.useEffect(() => {
1844
+ React6.useEffect(() => {
1787
1845
  pendingBulkSessionRef.current = pendingBulkSession;
1788
1846
  }, [pendingBulkSession]);
1789
- React5.useEffect(() => {
1847
+ React6.useEffect(() => {
1790
1848
  const handleKeyDown = (e) => {
1791
1849
  if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
1792
1850
  const currentBulkSession = pendingBulkSessionRef.current;
@@ -1849,7 +1907,7 @@ function ChatPanel({
1849
1907
  guideComplete,
1850
1908
  onNavigate
1851
1909
  ]);
1852
- const connectToEscalationWs = React5.useCallback((currentSessionId) => {
1910
+ const connectToEscalationWs = React6.useCallback((currentSessionId) => {
1853
1911
  if (!agentUrl) return;
1854
1912
  if (escalationWsRef.current) {
1855
1913
  escalationWsRef.current.close();
@@ -1892,7 +1950,7 @@ function ChatPanel({
1892
1950
  };
1893
1951
  escalationWsRef.current = ws;
1894
1952
  }, [agentUrl]);
1895
- const sendEscalatedMessage = React5.useCallback(async (content) => {
1953
+ const sendEscalatedMessage = React6.useCallback(async (content) => {
1896
1954
  if (!escalationWsRef.current || escalationWsRef.current.readyState !== WebSocket.OPEN) {
1897
1955
  console.error("[KiteChat] Escalation WebSocket not connected");
1898
1956
  return false;
@@ -1909,14 +1967,14 @@ function ChatPanel({
1909
1967
  return false;
1910
1968
  }
1911
1969
  }, [updateCustomerStatus]);
1912
- React5.useEffect(() => {
1970
+ React6.useEffect(() => {
1913
1971
  return () => {
1914
1972
  if (escalationWsRef.current) {
1915
1973
  escalationWsRef.current.close();
1916
1974
  }
1917
1975
  };
1918
1976
  }, []);
1919
- React5.useEffect(() => {
1977
+ React6.useEffect(() => {
1920
1978
  if (isEscalated && sessionId) {
1921
1979
  connectToEscalationWs(sessionId);
1922
1980
  }
@@ -2182,6 +2240,15 @@ function ChatPanel({
2182
2240
  try {
2183
2241
  const controller = new AbortController();
2184
2242
  const timeoutId = setTimeout(() => controller.abort(), 6e4);
2243
+ console.log("[ChatPanel] Sending chat request to agent backend...");
2244
+ console.log("[ChatPanel] Agent URL:", agentUrl);
2245
+ console.log("[ChatPanel] User data being sent:");
2246
+ console.log("[ChatPanel] user_id:", effectiveUser.userId);
2247
+ console.log("[ChatPanel] user_name:", effectiveUser.userName);
2248
+ console.log("[ChatPanel] user_email:", effectiveUser.userEmail);
2249
+ console.log("[ChatPanel] user_organization:", userOrganization);
2250
+ console.log("[ChatPanel] org_id:", orgId);
2251
+ console.log("[ChatPanel] authState.status:", authState.status);
2185
2252
  const response = await fetch(`${agentUrl}/chat/stream`, {
2186
2253
  method: "POST",
2187
2254
  headers: {
@@ -3136,7 +3203,38 @@ ${userText}`
3136
3203
  ] })
3137
3204
  ] }) }) });
3138
3205
  }
3139
- if (productBackendUrl) {
3206
+ if (orgConfigState.status === "loading") {
3207
+ return /* @__PURE__ */ jsxs6(
3208
+ "section",
3209
+ {
3210
+ className: `fixed top-0 right-0 z-40 flex flex-col bg-white border-l border-gray-200 h-full overflow-hidden transition-transform duration-300 ${isOpen ? "translate-x-0" : "translate-x-full"}`,
3211
+ style: { width: `${PANEL_WIDTH}px` },
3212
+ children: [
3213
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-100 bg-gradient-to-r from-gray-50 to-white shrink-0", children: [
3214
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2.5", children: [
3215
+ /* @__PURE__ */ jsx10(Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" }),
3216
+ /* @__PURE__ */ jsx10("h3", { className: "text-sm font-semibold text-gray-800", children: "Copilot" })
3217
+ ] }),
3218
+ /* @__PURE__ */ jsx10(
3219
+ Button,
3220
+ {
3221
+ variant: "ghost",
3222
+ size: "sm",
3223
+ className: "h-7 w-7 p-0 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-full",
3224
+ onClick: () => onClose?.(),
3225
+ children: /* @__PURE__ */ jsx10(X, { className: "h-4 w-4" })
3226
+ }
3227
+ )
3228
+ ] }),
3229
+ /* @__PURE__ */ jsx10("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs6("div", { className: "text-center", children: [
3230
+ /* @__PURE__ */ jsx10(Loader22, { className: "h-8 w-8 animate-spin text-gray-400 mx-auto mb-3" }),
3231
+ /* @__PURE__ */ jsx10("p", { className: "text-sm text-gray-500", children: "Loading..." })
3232
+ ] }) })
3233
+ ]
3234
+ }
3235
+ );
3236
+ }
3237
+ if (effectiveProductBackendUrl) {
3140
3238
  if (authState.status === "loading") {
3141
3239
  return /* @__PURE__ */ jsxs6(
3142
3240
  "section",
@@ -4311,7 +4409,7 @@ ${userText}`
4311
4409
  message.id
4312
4410
  );
4313
4411
  }
4314
- return /* @__PURE__ */ jsx10(React5.Fragment, { children: /* @__PURE__ */ jsxs6(
4412
+ return /* @__PURE__ */ jsx10(React6.Fragment, { children: /* @__PURE__ */ jsxs6(
4315
4413
  "div",
4316
4414
  {
4317
4415
  ref: isCurrentGuideStep ? currentStepRef : null,
@@ -4568,7 +4666,7 @@ function ChatPanelWithToggle({
4568
4666
  supabaseAnonKey,
4569
4667
  productBackendUrl
4570
4668
  }) {
4571
- const [internalIsOpen, setInternalIsOpen] = React5.useState(defaultOpen);
4669
+ const [internalIsOpen, setInternalIsOpen] = React6.useState(defaultOpen);
4572
4670
  const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
4573
4671
  const setIsOpen = (open) => {
4574
4672
  if (controlledIsOpen === void 0) {
@@ -4576,7 +4674,7 @@ function ChatPanelWithToggle({
4576
4674
  }
4577
4675
  onOpenChange?.(open);
4578
4676
  };
4579
- React5.useEffect(() => {
4677
+ React6.useEffect(() => {
4580
4678
  const originalPadding = document.body.style.paddingRight;
4581
4679
  const originalTransition = document.body.style.transition;
4582
4680
  document.body.style.transition = "padding-right 0.3s ease";
@@ -4623,7 +4721,7 @@ function HelpButton({ onClick, className = "" }) {
4623
4721
  }
4624
4722
 
4625
4723
  // src/createKiteChat.tsx
4626
- import React6 from "react";
4724
+ import React7 from "react";
4627
4725
  import { createRoot } from "react-dom/client";
4628
4726
  import { jsx as jsx11 } from "react/jsx-runtime";
4629
4727
  function KiteChatWrapper({
@@ -4631,14 +4729,14 @@ function KiteChatWrapper({
4631
4729
  onConfigUpdate,
4632
4730
  onStateUpdate
4633
4731
  }) {
4634
- const [config, setConfig] = React6.useState(initialConfig);
4635
- const [currentPage, setCurrentPage] = React6.useState(initialConfig.currentPage || "dashboard");
4636
- const [isOpen, setIsOpen] = React6.useState(false);
4637
- const isOpenRef = React6.useRef(false);
4638
- React6.useEffect(() => {
4732
+ const [config, setConfig] = React7.useState(initialConfig);
4733
+ const [currentPage, setCurrentPage] = React7.useState(initialConfig.currentPage || "dashboard");
4734
+ const [isOpen, setIsOpen] = React7.useState(false);
4735
+ const isOpenRef = React7.useRef(false);
4736
+ React7.useEffect(() => {
4639
4737
  isOpenRef.current = isOpen;
4640
4738
  }, [isOpen]);
4641
- React6.useEffect(() => {
4739
+ React7.useEffect(() => {
4642
4740
  onConfigUpdate((newConfig) => {
4643
4741
  if (newConfig.currentPage !== void 0) {
4644
4742
  setCurrentPage(newConfig.currentPage);
@@ -4650,7 +4748,7 @@ function KiteChatWrapper({
4650
4748
  getIsOpen: () => isOpenRef.current
4651
4749
  });
4652
4750
  }, [onConfigUpdate, onStateUpdate]);
4653
- React6.useEffect(() => {
4751
+ React7.useEffect(() => {
4654
4752
  const container = document.getElementById("kite-chat-root");
4655
4753
  if (!container) return;
4656
4754
  if (config.theme === "dark") {