@blockspark/chat-widget 1.0.21 → 1.0.22
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/ChatWidget-CkiqiScx.cjs +2 -0
- package/dist/ChatWidget-CkiqiScx.cjs.map +1 -0
- package/dist/{ChatWidget-fbaJU7v-.js → ChatWidget-CsEN9biV.js} +6 -17
- package/dist/ChatWidget-CsEN9biV.js.map +1 -0
- package/dist/components/ChatWidget.d.ts.map +1 -1
- package/dist/core/stateManager.d.ts.map +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +61 -50
- package/dist/index.esm.js.map +1 -1
- package/dist/nuxt.cjs.js +1 -1
- package/dist/nuxt.esm.js +2 -2
- package/dist/styles.css +1 -1
- package/dist/vue.cjs.js +1 -1
- package/dist/vue.esm.js +2 -2
- package/package.json +1 -1
- package/dist/ChatWidget-DoVcxHqA.cjs +0 -2
- package/dist/ChatWidget-DoVcxHqA.cjs.map +0 -1
- package/dist/ChatWidget-fbaJU7v-.js.map +0 -1
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../src/hooks/useChatMode.ts","../src/components/ChatWidget.tsx","../src/utils/frameworkDetector.ts","../node_modules/react-dom/client.js","../src/entry/vanilla.ts"],"sourcesContent":["// hooks/useChatMode.ts\nimport { useState, useEffect, useCallback } from \"react\";\nimport type { ChatResponse } from \"../services/dialogflowBackendService\";\n\nexport type ChatMode = \"BOT\" | \"HUMAN\";\n\nconst MODE_STORAGE_KEY = \"chartsconnectect_chat_mode\";\nconst CHAT_ID_STORAGE_KEY = \"chartsconnect_chat_id\";\nconst SESSION_ID_STORAGE_KEY = \"chartsconnect_session_id\";\n\nexport interface UseChatModeReturn {\n currentMode: ChatMode;\n switchToHumanMode: () => void;\n switchToBotMode: () => void;\n isHandoffTriggered: (dialogflowResponse: ChatResponse) => boolean;\n chatId: string | null;\n sessionId: string | null;\n setChatId: (id: string | null) => void;\n setSessionId: (id: string | null) => void;\n}\n\n/**\n * Hook to manage chat mode (BOT or HUMAN)\n */\nexport function useChatMode(): UseChatModeReturn {\n const [currentMode, setCurrentMode] = useState<ChatMode>(() => {\n // Load from localStorage on init\n const savedMode = localStorage.getItem(MODE_STORAGE_KEY);\n return (savedMode === \"HUMAN\" ? \"HUMAN\" : \"BOT\") as ChatMode;\n });\n\n const [chatId, setChatIdState] = useState<string | null>(() => {\n return localStorage.getItem(CHAT_ID_STORAGE_KEY);\n });\n\n const [sessionId, setSessionIdState] = useState<string | null>(() => {\n return localStorage.getItem(SESSION_ID_STORAGE_KEY);\n });\n\n // Persist mode to localStorage\n useEffect(() => {\n localStorage.setItem(MODE_STORAGE_KEY, currentMode);\n }, [currentMode]);\n\n // Persist chat_id to localStorage\n const setChatId = useCallback((id: string | null) => {\n setChatIdState(id);\n if (id) {\n localStorage.setItem(CHAT_ID_STORAGE_KEY, id);\n } else {\n localStorage.removeItem(CHAT_ID_STORAGE_KEY);\n }\n }, []);\n\n // Persist session_id to localStorage\n const setSessionId = useCallback((id: string | null) => {\n setSessionIdState(id);\n if (id) {\n localStorage.setItem(SESSION_ID_STORAGE_KEY, id);\n } else {\n localStorage.removeItem(SESSION_ID_STORAGE_KEY);\n }\n }, []);\n\n const switchToHumanMode = useCallback(() => {\n setCurrentMode(\"HUMAN\");\n }, []);\n\n const switchToBotMode = useCallback(() => {\n setCurrentMode(\"BOT\");\n }, []);\n\n /**\n * Check if Dialogflow response contains handoff trigger\n * Handoff is triggered when response contains {\"handoff\": true}\n * This can be in:\n * - queryResult.parameters.handoff\n * - queryResult.responseMessages payload\n * - queryResult.intent.displayName (if configured)\n */\n const isHandoffTriggered = useCallback(\n (dialogflowResponse: ChatResponse): boolean => {\n // Check if response has handoff flag\n // This would need to be extracted from Dialogflow response\n // For now, we'll check the response text or any custom fields\n \n // The handoff flag might come from Dialogflow's custom payload\n // We need to check the actual Dialogflow response structure\n // Since ChatResponse doesn't include the full response, we'll need to\n // modify the dialogflowClient to pass through handoff information\n \n // For now, return false - this will be handled by dialogflowHandler\n return false;\n },\n []\n );\n\n return {\n currentMode,\n switchToHumanMode,\n switchToBotMode,\n isHandoffTriggered,\n chatId,\n sessionId,\n setChatId,\n setSessionId,\n };\n}\n\n","import React, { useState, useEffect, useRef, useCallback } from \"react\";\nimport {\n createDialogflowSession,\n sendDialogflowMessage,\n type DialogflowBackendConfig,\n type SessionResponse,\n type ChatResponse,\n} from \"../services/dialogflowBackendService\";\nimport { useChatMode } from \"../hooks/useChatMode\";\nimport { ChatResolvedError, createChatService, type WebSocketMessage } from \"../services/chatService\";\nimport { linkifyText } from \"../utils/sanitize\";\nimport \"../styles/chatWidget.css\";\n\ninterface ChipOption {\n text: string;\n payload: string;\n}\n\ninterface RichContent {\n type?: string;\n options?: ChipOption[];\n}\n\ntype RichContentArray = RichContent | RichContent[];\n\ninterface Message {\n id: string;\n text: string;\n sender: \"user\" | \"bot\" | \"agent\";\n timestamp: Date;\n richContent?: RichContentArray[];\n}\n\nexport interface ChatWidgetProps {\n /** Custom title for the chat widget */\n title?: string;\n /** Custom subtitle for the chat widget */\n subtitle?: string;\n /** Welcome popup title */\n welcomeTitle?: string;\n /** Welcome popup message */\n welcomeMessage?: string;\n /** Welcome popup CTA text */\n welcomeCta?: string;\n /** Whether to show the welcome popup */\n showWelcomePopup?: boolean;\n /** Delay in milliseconds before showing welcome popup */\n welcomePopupDelay?: number;\n /** Fallback welcome message if API fails */\n fallbackWelcomeMessage?: string;\n /** Placeholder text for input field */\n inputPlaceholder?: string;\n /** Custom empty state message */\n emptyStateMessage?: string;\n /** Enable/disable debug logging */\n debug?: boolean;\n /** Dialogflow project ID */\n dfProjectId?: string;\n /** Dialogflow location (e.g., \"us-central1\") */\n dfLocation?: string;\n /** Dialogflow agent ID */\n dfAgentId?: string;\n /** Language code for Dialogflow */\n languageCode?: string;\n /** Backend API base URL (default: http://localhost:8012) */\n backendBaseUrl?: string;\n /** WebSocket URL (default: ws://localhost:8012) */\n backendWsUrl?: string;\n}\n\nexport default function ChatWidget({\n title = \"💬 Charts Connect AI Assistant\",\n subtitle = \"We're here to help\",\n welcomeTitle = \"👋 Welcome to Charts Connect\",\n welcomeMessage = \"My name is Charts Connect AI Assistant and I'll guide you.\",\n welcomeCta = \"💬 Click here to start chatting!\",\n showWelcomePopup: enableWelcomePopup = true,\n welcomePopupDelay = 1500,\n fallbackWelcomeMessage = \"Hello! I'm Charts Connect AI Assistant. How can I help you today?\",\n inputPlaceholder = \"Type your message...\",\n emptyStateMessage = \"Hi! I'm Charts Connect AI Assistant. How can I help you today?\",\n debug = false,\n dfProjectId,\n dfLocation = \"us-central1\",\n dfAgentId,\n languageCode = \"en\",\n backendBaseUrl,\n backendWsUrl,\n}: ChatWidgetProps) {\n const [isOpen, setIsOpen] = useState(false);\n const [showWelcomePopup, setShowWelcomePopup] = useState(false);\n const [messages, setMessages] = useState<Message[]>([]);\n const [inputValue, setInputValue] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [sessionId, setSessionId] = useState<string | null>(null);\n const [isInitializing, setIsInitializing] = useState(false);\n const [isConnectingToAgent, setIsConnectingToAgent] = useState(false);\n const [wsConnected, setWsConnected] = useState(false);\n const [agentTyping, setAgentTyping] = useState(false);\n const [currentAgent, setCurrentAgent] = useState<{ name: string; id?: string }>({ name: \"Agent\" });\n const [chatResolved, setChatResolved] = useState(false);\n const [isStartingNewChat, setIsStartingNewChat] = useState(false);\n const [agentAccepted, setAgentAccepted] = useState(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const typingTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const agentTypingTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const creatingSessionRef = useRef(false); // Prevent race condition in createSession\n const createSessionRef = useRef<((forceRecreate?: boolean, reuseSessionId?: boolean) => Promise<string | null>) | null>(null); // Ref for createSession to avoid stale closure\n \n // Get backend URLs from props or environment variables (injected at build time)\n const getBackendBaseUrl = () => {\n return backendBaseUrl || process.env.REACT_APP_BACKEND_BASE_URL || '';\n };\n\n const getBackendWsUrl = () => {\n return backendWsUrl || process.env.REACT_APP_BACKEND_WS_URL || '';\n };\n \n const chatServiceRef = useRef(\n createChatService({ \n baseUrl: getBackendBaseUrl(), \n wsUrl: getBackendWsUrl(),\n debug: debug\n })\n );\n const historyLoadedRef = useRef<string | null>(null);\n \n // Use chat mode hook\n const {\n currentMode,\n switchToHumanMode,\n switchToBotMode,\n chatId,\n sessionId: supportSessionId,\n setChatId,\n setSessionId: setSupportSessionId,\n } = useChatMode();\n\n const enterResolvedState = useCallback(\n (_resolvedChatId?: string | null) => {\n setChatResolved(true);\n setIsConnectingToAgent(false);\n setAgentAccepted(false);\n setAgentTyping(false);\n if (agentTypingTimeoutRef.current) {\n clearTimeout(agentTypingTimeoutRef.current);\n agentTypingTimeoutRef.current = null;\n }\n\n // Stop WS + prevent any reuse of the old chat_id\n chatServiceRef.current.disconnectWebSocket();\n setChatId(null);\n setSupportSessionId(null);\n setSessionId(null); // Fix #1: Clear sessionId to force new session creation\n \n // Add thank you message before reset\n const thankYouMessage: Message = {\n id: `resolved-${Date.now()}`,\n text: \"Thank you for contacting us!\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, thankYouMessage]);\n \n // Automatically reset to BOT mode after showing thank you message\n setTimeout(() => {\n switchToBotMode();\n setChatResolved(false);\n setMessages([]);\n // Recreate Dialogflow session to start fresh (sessionId already cleared above)\n // Use ref to access latest createSession function to avoid stale closure\n if (createSessionRef.current) {\n createSessionRef.current().catch(console.error);\n }\n }, 2000); // 2 second delay to show thank you message\n },\n [setChatId, setSupportSessionId, switchToBotMode] // createSession accessed via ref, no need in deps\n );\n\n const handleStartNewChat = useCallback(async () => {\n if (isStartingNewChat) return;\n setIsStartingNewChat(true);\n try {\n const newSession = await chatServiceRef.current.startSupportChat(\n sessionId || null\n );\n\n switchToHumanMode();\n setChatId(newSession.chat_id);\n setSupportSessionId(newSession.session_id);\n setChatResolved(false);\n setInputValue(\"\");\n } catch (error: any) {\n console.error(\"Error starting new chat:\", error);\n setMessages((prev) => [\n ...prev,\n {\n id: `error-new-chat-${Date.now()}`,\n text: debug\n ? `Error: ${error?.message || \"Failed to start a new chat.\"}`\n : \"Sorry, I couldn't start a new chat. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n },\n ]);\n } finally {\n setIsStartingNewChat(false);\n }\n }, [\n debug,\n isStartingNewChat,\n sessionId,\n setChatId,\n setSupportSessionId,\n switchToHumanMode,\n ]);\n\n // Helper function to build Dialogflow config from props\n const getDialogflowConfig = (): DialogflowBackendConfig | undefined => {\n if (!dfProjectId || !dfAgentId) {\n return undefined;\n }\n \n return {\n dfProjectId,\n dfLocation: dfLocation || 'us-central1',\n dfAgentId,\n languageCode: languageCode || 'en',\n backendBaseUrl: getBackendBaseUrl(),\n };\n };\n\n // Show welcome popup after page load\n useEffect(() => {\n if (!enableWelcomePopup) return;\n \n const timer = setTimeout(() => {\n setShowWelcomePopup(true);\n }, welcomePopupDelay);\n return () => clearTimeout(timer);\n }, [enableWelcomePopup, welcomePopupDelay]);\n\n // Auto-scroll to bottom when new messages arrive\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages]);\n\n // Handle agent changed notification\n const handleAgentChanged = useCallback((message: WebSocketMessage) => {\n if (message.to_agent) {\n setCurrentAgent({\n id: message.to_agent_id,\n name: message.to_agent,\n });\n\n // Add system message to chat\n const systemMessage: Message = {\n id: `system-${Date.now()}`,\n text: message.from_agent\n ? `Chat has been transferred from ${message.from_agent} to ${message.to_agent}`\n : `Chat has been transferred to ${message.to_agent}`,\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, systemMessage]);\n\n if (debug) {\n console.log(\"Agent changed:\", {\n from: message.from_agent,\n to: message.to_agent,\n reason: message.reason,\n });\n }\n }\n }, [debug]);\n\n // Handle WebSocket messages\n const handleWebSocketMessage = useCallback((message: WebSocketMessage) => {\n switch (message.type) {\n case \"message\":\n if (message.content) {\n // Only display messages from agent, ignore customer messages (we already added them)\n if (message.sender_type === \"agent\" || !message.sender_type) {\n const agentMessage: Message = {\n id: message.id || `agent-${Date.now()}`,\n text: message.content,\n sender: \"agent\",\n timestamp: new Date(message.timestamp || Date.now()),\n };\n setMessages((prev) => {\n // Avoid duplicate messages by checking if message ID already exists\n const existingIds = new Set(prev.map(m => m.id));\n if (existingIds.has(agentMessage.id)) {\n return prev;\n }\n return [...prev, agentMessage];\n });\n // Hide typing indicator when message received\n setAgentTyping(false);\n if (agentTypingTimeoutRef.current) {\n clearTimeout(agentTypingTimeoutRef.current);\n agentTypingTimeoutRef.current = null;\n }\n } else if (debug && message.sender_type === \"customer\") {\n console.log(\"Ignoring customer message from WebSocket (already added)\");\n }\n // If sender_type is \"customer\", ignore it - we already added the user message\n } else if (debug) {\n console.warn(\"WebSocket message received without content:\", message);\n }\n break;\n\n case \"typing_start\":\n if (message.sender_type === \"agent\") {\n setAgentTyping(true);\n // Auto-hide after 3 seconds if no message received\n if (agentTypingTimeoutRef.current) {\n clearTimeout(agentTypingTimeoutRef.current);\n }\n agentTypingTimeoutRef.current = setTimeout(() => {\n setAgentTyping(false);\n }, 3000);\n }\n break;\n\n case \"typing_stop\":\n if (message.sender_type === \"agent\") {\n setAgentTyping(false);\n if (agentTypingTimeoutRef.current) {\n clearTimeout(agentTypingTimeoutRef.current);\n agentTypingTimeoutRef.current = null;\n }\n }\n break;\n\n case \"agent_changed\":\n handleAgentChanged(message);\n break;\n\n case \"chat_info\":\n if (debug) {\n console.log(\"Chat info:\", message);\n }\n // Update connection status based on chat info\n if (message.status === \"active\") {\n setIsConnectingToAgent(false);\n setAgentAccepted(true);\n } else if (message.status === \"resolved\" || message.status === \"ended\") {\n enterResolvedState(message.chat_id || null);\n }\n // Update agent info if provided\n if (message.agent_id) {\n setCurrentAgent((prev) => ({\n ...prev,\n id: message.agent_id,\n }));\n }\n break;\n\n case \"agent_accepted\":\n // Agent has accepted the chat request\n setAgentAccepted(true);\n setIsConnectingToAgent(false);\n const acceptedMessage: Message = {\n id: message.id || `agent-accepted-${message.chat_id || Date.now()}-${Date.now()}`,\n text: \"You can chat now, the agent has accepted your request.\",\n sender: \"bot\",\n timestamp: message.timestamp ? new Date(message.timestamp) : new Date(),\n };\n setMessages((prev) => {\n // Avoid duplicate messages\n const existingIds = new Set(prev.map(m => m.id));\n if (existingIds.has(acceptedMessage.id)) {\n return prev;\n }\n return [...prev, acceptedMessage];\n });\n // Update agent info if provided\n if (message.to_agent) {\n setCurrentAgent({\n name: message.to_agent,\n id: message.to_agent_id,\n });\n }\n if (debug) {\n console.log(\"Agent accepted chat:\", message);\n }\n break;\n\n case \"chat_resolved\":\n case \"chat_ended\":\n // Chat has been resolved/ended by agent (terminal state)\n enterResolvedState(message.chat_id || null);\n if (debug) {\n console.log(\"Chat resolved/ended:\", message);\n }\n break;\n\n case \"error\":\n console.error(\"WebSocket error:\", message.error);\n const errorMessage: Message = {\n id: `error-${Date.now()}`,\n text: message.error || \"An error occurred. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n break;\n\n case \"pong\":\n // Keep-alive response, no action needed\n break;\n\n default:\n if (debug) {\n console.log(\"Unknown message type:\", message.type);\n }\n }\n }, [debug, enterResolvedState, handleAgentChanged]);\n\n const handleWebSocketClose = useCallback(\n (event: CloseEvent) => {\n // Backend uses 4000 to indicate the chat is resolved, and then closes.\n if (event.code === 4000) {\n enterResolvedState(chatId);\n }\n },\n [chatId, enterResolvedState]\n );\n\n // Handle WebSocket connection changes\n const handleConnectionChange = useCallback((connected: boolean) => {\n setWsConnected(connected);\n if (connected) {\n setIsConnectingToAgent(false);\n }\n }, []);\n\n // Initialize WebSocket when switching to HUMAN mode\n useEffect(() => {\n if (currentMode === \"HUMAN\" && chatId && supportSessionId) {\n chatServiceRef.current.connectWebSocket(\n chatId,\n supportSessionId,\n handleWebSocketMessage,\n handleConnectionChange,\n handleWebSocketClose\n );\n\n return () => {\n chatServiceRef.current.disconnectWebSocket();\n };\n }\n }, [\n currentMode,\n chatId,\n supportSessionId,\n handleWebSocketMessage,\n handleConnectionChange,\n handleWebSocketClose,\n ]);\n\n // Load message history from backend\n const loadMessageHistory = useCallback(async (preserveExisting: boolean = true) => {\n if (!chatId || !supportSessionId) return;\n\n try {\n setIsLoading(true);\n const history = await chatServiceRef.current.loadMessageHistory(chatId, supportSessionId);\n \n const historyMessages: Message[] = history.map((msg) => ({\n id: msg.id || `msg-${Date.now()}-${Math.random()}`,\n text: msg.content,\n sender: msg.sender_type === \"agent\" ? \"agent\" : \"user\",\n timestamp: new Date(msg.timestamp),\n }));\n\n if (preserveExisting) {\n // Merge with existing messages, avoiding duplicates\n setMessages((prevMessages) => {\n const existingIds = new Set(prevMessages.map(m => m.id));\n const newMessages = historyMessages.filter(m => !existingIds.has(m.id));\n \n // Combine existing messages with new history messages\n // Sort by timestamp to maintain chronological order\n const combined = [...prevMessages, ...newMessages].sort((a, b) => \n a.timestamp.getTime() - b.timestamp.getTime()\n );\n \n return combined;\n });\n } else {\n // Replace all messages (only if explicitly requested)\n setMessages(historyMessages);\n }\n } catch (error: any) {\n console.error(\"Error loading message history:\", error);\n if (debug) {\n const errorMessage: Message = {\n id: `error-${Date.now()}`,\n text: `Failed to load chat history: ${error.message}`,\n sender: \"bot\",\n timestamp: new Date(),\n };\n // Only add error message, don't replace existing messages\n setMessages((prev) => [...prev, errorMessage]);\n }\n } finally {\n setIsLoading(false);\n }\n }, [chatId, supportSessionId, debug]);\n\n // Load message history when switching to HUMAN mode\n useEffect(() => {\n if (currentMode === \"HUMAN\" && chatId && supportSessionId) {\n // Only load if we haven't loaded history for this chat session yet\n const sessionKey = `${chatId}-${supportSessionId}`;\n if (historyLoadedRef.current !== sessionKey) {\n historyLoadedRef.current = sessionKey;\n // Check if we have existing messages (from bot conversation during handoff)\n // If yes, preserve them and don't load history\n // If no, load history for new chat\n // Access messages state via a ref or check in the next tick\n const checkAndLoad = () => {\n // Check messages length - if 0, load history; if > 0, preserve existing\n if (messages.length === 0) {\n // No existing messages, load history\n loadMessageHistory(false).catch(console.error);\n }\n // Has existing messages (bot conversation), keep them - don't load history\n };\n // Use setTimeout to ensure we check after state updates\n setTimeout(checkAndLoad, 0);\n }\n } else if (currentMode === \"BOT\") {\n // Reset history loaded flag when switching back to BOT mode\n historyLoadedRef.current = null;\n }\n }, [currentMode, chatId, supportSessionId, loadMessageHistory, messages.length]);\n\n // Handle handoff from Dialogflow\n const handleHandoff = async (webhookChatId?: string, webhookSessionId?: string) => {\n try {\n setIsConnectingToAgent(true);\n\n // Get Dialogflow session ID if available\n const dialogflowSessionId = sessionId;\n\n // STEP 1: Use chat created by webhook if provided, otherwise ensure one exists\n const session = webhookChatId && webhookSessionId\n ? { chat_id: webhookChatId, session_id: webhookSessionId }\n : await chatServiceRef.current.ensureChatInitialized(\n chatId,\n supportSessionId,\n dialogflowSessionId || null\n );\n \n if (!session || !session.chat_id) {\n throw new Error(\"Failed to initialize chat session\");\n }\n \n const currentChatId = session.chat_id;\n const currentSupportSessionId = session.session_id;\n \n // Update state if chat was newly initialized\n if (currentChatId !== chatId) {\n setChatId(currentChatId);\n setSupportSessionId(currentSupportSessionId);\n if (debug) {\n console.log(\"✅ Chat initialized:\", { chatId: currentChatId, sessionId: currentSupportSessionId });\n }\n }\n\n // STEP 2: Only request handoff if the frontend created the chat\n // Skip if webhookChatId is provided — the webhook already created the chat with \"waiting\" status\n if (!webhookChatId) {\n try {\n await chatServiceRef.current.requestHandoff(\n currentChatId,\n currentSupportSessionId,\n \"Customer requested human agent\",\n dialogflowSessionId || null\n );\n\n if (debug) {\n console.log(\"✅ Handoff requested successfully\");\n }\n } catch (handoffError: any) {\n // Handle 401/404 or \"chat not found\" - clear chat_id and retry (but keep session logic)\n if (handoffError.message?.includes(\"Invalid chat_id\") ||\n handoffError.message?.includes(\"Chat not found\") ||\n handoffError.message?.includes(\"unauthorized\") ||\n handoffError.message?.includes(\"400\") ||\n handoffError.message?.includes(\"401\") ||\n handoffError.message?.includes(\"404\") ||\n handoffError.message?.includes(\"expired\")) {\n if (debug) {\n console.log(\"⚠️ Chat expired or not found. Re-initializing chat...\");\n }\n\n // Clear old chat_id (but keep session logic - session_id is managed by sessionManager)\n setChatId(null);\n setSupportSessionId(null);\n\n // Create new chat session (session_id will be automatically included from session manager)\n const newSession = await chatServiceRef.current.startSupportChat(\n dialogflowSessionId || null\n );\n\n if (!newSession || !newSession.chat_id) {\n throw new Error(\"Failed to re-initialize chat session\");\n }\n\n const newChatId = newSession.chat_id;\n const newSessionId = newSession.session_id;\n setChatId(newChatId);\n setSupportSessionId(newSessionId);\n\n // Retry handoff with new chat_id\n await chatServiceRef.current.requestHandoff(\n newChatId,\n newSessionId,\n \"Customer requested human agent\",\n dialogflowSessionId || null\n );\n\n if (debug) {\n console.log(\"✅ Handoff requested successfully after retry\");\n }\n\n // Update for message history loading\n const newSessionKey = `${newChatId}-${newSessionId}`;\n if (historyLoadedRef.current !== newSessionKey) {\n historyLoadedRef.current = newSessionKey;\n await loadMessageHistory(true);\n }\n } else {\n throw handoffError;\n }\n }\n } else if (debug) {\n console.log(\"✅ Using webhook-created chat, skipping requestHandoff\");\n }\n\n // Switch to human mode\n switchToHumanMode();\n // Reset states for new handoff\n setChatResolved(false);\n setAgentAccepted(false);\n\n // Add connecting message (preserve existing messages)\n const connectingMessage: Message = {\n id: `connecting-${Date.now()}`,\n text: \"Connecting you to a human agent...\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, connectingMessage]);\n\n // Don't load history during handoff - preserve existing bot conversation\n // History will be loaded automatically via useEffect if needed for new sessions\n const sessionKey = `${currentChatId}-${currentSupportSessionId}`;\n historyLoadedRef.current = sessionKey;\n } catch (error: any) {\n console.error(\"Error handling handoff:\", error);\n const errorMessage: Message = {\n id: `error-${Date.now()}`,\n text: debug\n ? `Handoff error: ${error.message}`\n : \"Failed to connect to agent. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n setIsConnectingToAgent(false);\n }\n };\n\n // Create new session\n const createSession = async (forceRecreate: boolean = false, reuseSessionId: boolean = false) => {\n // If sessionId exists and we're not forcing recreation, return existing session\n // Unless reuseSessionId is true (then we'll pass it to backend to potentially reuse)\n if (sessionId && !forceRecreate && !reuseSessionId) return sessionId;\n\n // Prevent race condition: if already creating, wait and return existing session\n if (creatingSessionRef.current) {\n // Wait a bit for the concurrent call to complete\n await new Promise(resolve => setTimeout(resolve, 100));\n if (sessionId) return sessionId; // Return if session was created by concurrent call\n throw new Error('Session creation in progress. Please try again.');\n }\n\n creatingSessionRef.current = true;\n\n try {\n setIsInitializing(true);\n const dfConfig = getDialogflowConfig();\n if (!dfConfig) {\n throw new Error('Dialogflow configuration is missing. Please provide dfProjectId and dfAgentId.');\n }\n \n // Pass existing sessionId if reuseSessionId is true and sessionId exists\n // Backend can decide whether to reuse it or create a new one\n const existingSessionId = (reuseSessionId && sessionId) ? sessionId : null;\n const data = await createDialogflowSession(dfConfig, existingSessionId);\n setSessionId(data.session_id);\n\n // Add welcome message from backend\n if (data.message) {\n if (debug) {\n console.log('Session response richContent:', data.richContent);\n console.log('Full session response:', data);\n }\n \n const welcomeMessage: Message = {\n id: `welcome-${Date.now()}`,\n text: data.message,\n sender: \"bot\",\n timestamp: new Date(),\n richContent: data.richContent,\n };\n // Preserve existing messages instead of replacing (fix message replacement bug)\n setMessages((prev) => {\n // Only replace if no messages exist, otherwise prepend welcome message\n if (prev.length === 0) {\n return [welcomeMessage];\n }\n return [welcomeMessage, ...prev];\n });\n }\n\n return data.session_id;\n } catch (error: any) {\n console.error(\"Error creating session:\", error);\n if (debug) {\n console.error(\"Full error details:\", {\n message: error.message,\n stack: error.stack,\n config: getDialogflowConfig(),\n });\n }\n // Show error message to user\n const errorMessage: Message = {\n id: `error-${Date.now()}`,\n text: debug \n ? `Error: ${error.message || 'Failed to create session. Please check your Dialogflow configuration.'}`\n : fallbackWelcomeMessage,\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n return null;\n } finally {\n setIsInitializing(false);\n creatingSessionRef.current = false; // Release lock\n }\n };\n\n // Update createSession ref when function is defined (fixes stale closure issue)\n createSessionRef.current = createSession;\n\n // Note: Dialogflow manages conversation history internally\n // History is maintained through the session, so we don't need to load it separately\n\n // Send message to backend API\n const sendMessage = async (text: string, displayText?: string, skipUserMessage: boolean = false) => {\n if (!text.trim()) return;\n\n // Handle HUMAN mode\n if (currentMode === \"HUMAN\") {\n if (!chatId || !supportSessionId) {\n const errorMessage: Message = {\n id: Date.now().toString(),\n text: \"Chat session not initialized. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n return;\n }\n\n // Add user message unless skipped\n if (!skipUserMessage) {\n const userMessage: Message = {\n id: Date.now().toString(),\n text: displayText || text.trim(),\n sender: \"user\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, userMessage]);\n }\n\n // Send typing_stop before sending message\n chatServiceRef.current.sendTypingIndicator(\"typing_stop\");\n \n // Clear typing timeout\n if (typingTimeoutRef.current) {\n clearTimeout(typingTimeoutRef.current);\n typingTimeoutRef.current = null;\n }\n\n setInputValue(\"\");\n setIsLoading(true);\n\n try {\n // Try WebSocket first, fallback to REST API\n const sentViaWs = chatServiceRef.current.sendMessageViaWebSocket(text.trim());\n \n if (!sentViaWs) {\n // Fallback to REST API\n await chatServiceRef.current.sendMessageToAgent(chatId, supportSessionId, text.trim());\n }\n } catch (error: any) {\n // chat_resolved is a normal terminal success condition, not an error.\n if (\n error instanceof ChatResolvedError ||\n error?.name === \"ChatResolvedError\" ||\n error?.message === \"chat_resolved\"\n ) {\n enterResolvedState(chatId);\n return;\n }\n\n console.error(\"Error sending message to agent:\", error);\n \n // Handle 401/404 - clear chat_id and reinitialize (but keep session logic)\n if (error.message?.includes(\"Chat not found\") ||\n error.message?.includes(\"unauthorized\") ||\n error.message?.includes(\"401\") ||\n error.message?.includes(\"404\")) {\n if (debug) {\n console.log(\"⚠️ Chat expired. Re-initializing...\");\n }\n \n // Clear chat_id (session_id is managed by sessionManager)\n setChatId(null);\n setSupportSessionId(null);\n \n // Try to reinitialize chat\n try {\n const newSession = await chatServiceRef.current.startSupportChat(\n sessionId || null\n );\n setChatId(newSession.chat_id);\n setSupportSessionId(newSession.session_id);\n \n // Retry sending message\n try {\n await chatServiceRef.current.sendMessageToAgent(\n newSession.chat_id,\n newSession.session_id,\n text.trim()\n );\n } catch (retryError: any) {\n if (\n retryError instanceof ChatResolvedError ||\n retryError?.name === \"ChatResolvedError\" ||\n retryError?.message === \"chat_resolved\"\n ) {\n enterResolvedState(newSession.chat_id);\n return;\n }\n throw retryError;\n }\n return; // Success, exit early\n } catch (retryError: any) {\n if (\n retryError instanceof ChatResolvedError ||\n retryError?.name === \"ChatResolvedError\" ||\n retryError?.message === \"chat_resolved\"\n ) {\n enterResolvedState(chatId);\n return;\n }\n // If retry fails, show error\n const errorMessage: Message = {\n id: (Date.now() + 1).toString(),\n text: debug\n ? `Error: ${retryError.message || 'Failed to send message.'}`\n : \"Sorry, I'm having trouble sending your message. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n }\n } else {\n const errorMessage: Message = {\n id: (Date.now() + 1).toString(),\n text: debug\n ? `Error: ${error.message || 'Failed to send message to agent.'}`\n : \"Sorry, I'm having trouble sending your message. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n }\n } finally {\n setIsLoading(false);\n }\n return;\n }\n\n // Handle BOT mode (Dialogflow)\n // Ensure we have a session\n let currentSessionId = sessionId;\n if (!currentSessionId) {\n try {\n currentSessionId = await createSession();\n if (!currentSessionId) {\n const errorMessage: Message = {\n id: Date.now().toString(),\n text: debug \n ? \"Failed to create session. Please check the console for details.\"\n : \"Sorry, I'm having trouble connecting. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n return;\n }\n } catch (error: any) {\n console.error(\"Error in createSession:\", error);\n const errorMessage: Message = {\n id: Date.now().toString(),\n text: debug \n ? `Connection Error: ${error.message || 'Please check your Dialogflow configuration.'}`\n : \"Sorry, I'm having trouble connecting. Please check your configuration.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n return;\n }\n }\n\n // Add user message unless skipped (e.g., when chip button already added it)\n if (!skipUserMessage) {\n const userMessage: Message = {\n id: Date.now().toString(),\n text: displayText || text.trim(),\n sender: \"user\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, userMessage]);\n }\n \n setInputValue(\"\");\n setIsLoading(true);\n\n try {\n const dfConfig = getDialogflowConfig();\n if (!dfConfig) {\n throw new Error('Dialogflow configuration is missing. Please provide dfProjectId and dfAgentId.');\n }\n \n const data = await sendDialogflowMessage(text.trim(), currentSessionId, dfConfig);\n\n if (debug) {\n console.log('Chat response richContent:', data.richContent);\n console.log('Full chat response:', data);\n console.log('Handoff detected:', data.handoff);\n }\n \n // Check for handoff\n if (data.handoff === true) {\n // Add bot response first only if there is actual text or rich content\n if (data.response || data.richContent) {\n const botMessage: Message = {\n id: (Date.now() + 1).toString(),\n text: data.response,\n sender: \"bot\",\n timestamp: new Date(data.timestamp || Date.now()),\n richContent: data.richContent,\n };\n setMessages((prev) => [...prev, botMessage]);\n }\n\n // Proceed directly with handoff — pass chat_id/session_id created by the webhook\n await handleHandoff(data.chat_id, data.support_session_id);\n return;\n }\n \n // Only add a bot message if the backend returned actual text or rich content\n if (data.response || data.richContent) {\n const botMessage: Message = {\n id: (Date.now() + 1).toString(),\n text: data.response,\n sender: \"bot\",\n timestamp: new Date(data.timestamp || Date.now()),\n richContent: data.richContent,\n };\n setMessages((prev) => [...prev, botMessage]);\n }\n } catch (error: any) {\n console.error(\"Error sending message:\", error);\n if (debug) {\n console.error(\"Full error details:\", {\n message: error.message,\n stack: error.stack,\n sessionId: currentSessionId,\n config: getDialogflowConfig(),\n });\n }\n const errorMessage: Message = {\n id: (Date.now() + 1).toString(),\n text: debug\n ? `Error: ${error.message || 'Failed to send message. Please check your Dialogflow configuration.'}`\n : error.message?.includes(\"Failed to fetch\") || error.message?.includes(\"CORS\")\n ? \"Unable to connect to Dialogflow. Please check your configuration and network.\"\n : \"Sorry, I'm having trouble processing your message. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n sendMessage(inputValue);\n };\n\n // Handle input change - send typing indicators (only in HUMAN mode)\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value;\n setInputValue(value);\n\n // Only send typing indicators in HUMAN mode with WebSocket connected\n if (currentMode === \"HUMAN\" && wsConnected) {\n // Send typing_start\n chatServiceRef.current.sendTypingIndicator(\"typing_start\");\n\n // Clear existing timeout\n if (typingTimeoutRef.current) {\n clearTimeout(typingTimeoutRef.current);\n }\n\n // Send typing_stop after 2 seconds of inactivity\n typingTimeoutRef.current = setTimeout(() => {\n chatServiceRef.current.sendTypingIndicator(\"typing_stop\");\n typingTimeoutRef.current = null;\n }, 2000);\n }\n };\n\n // Cleanup typing timeouts on unmount\n useEffect(() => {\n return () => {\n if (typingTimeoutRef.current) {\n clearTimeout(typingTimeoutRef.current);\n }\n if (agentTypingTimeoutRef.current) {\n clearTimeout(agentTypingTimeoutRef.current);\n }\n };\n }, []);\n\n const openChat = async () => {\n setIsOpen(true);\n setShowWelcomePopup(false);\n\n // Create session when chat opens if it doesn't exist\n if (!sessionId) {\n await createSession();\n }\n // Note: Dialogflow maintains conversation history internally through the session\n };\n\n const closeChat = () => {\n setIsOpen(false);\n // Disconnect WebSocket when closing chat\n if (currentMode === \"HUMAN\") {\n chatServiceRef.current.disconnectWebSocket();\n }\n };\n\n // Check if message is a handoff message\n const isHandoffMessage = (text: string): boolean => {\n return (\n text.includes(\"👤\") ||\n text.includes(\"being connected\") ||\n text.includes(\"live support agent\") ||\n text.includes(\"transfer your conversation\") ||\n text.includes(\"✅\") ||\n text.includes(\"🔄\")\n );\n };\n\n // Cleanup WebSocket on unmount\n useEffect(() => {\n return () => {\n chatServiceRef.current.disconnectWebSocket();\n };\n }, []);\n\n return (\n <>\n {/* Welcome Popup */}\n {showWelcomePopup && !isOpen && (\n <div className=\"custom-welcome-popup\" onClick={openChat}>\n <div className=\"custom-welcome-header\">\n <div className=\"custom-welcome-title\">{welcomeTitle}</div>\n <button\n className=\"custom-close-popup\"\n onClick={(e) => {\n e.stopPropagation();\n setShowWelcomePopup(false);\n }}\n >\n ×\n </button>\n </div>\n <div className=\"custom-welcome-message\">\n {welcomeMessage}\n </div>\n <div className=\"custom-welcome-cta\">{welcomeCta}</div>\n </div>\n )}\n\n {/* Chat Toggle Button */}\n {!isOpen && (\n <button\n className=\"custom-chat-toggle-btn\"\n onClick={openChat}\n aria-label=\"Open chat\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\n </svg>\n </button>\n )}\n\n {/* Chat Window */}\n {isOpen && (\n <div className=\"custom-chat-window\">\n <div className=\"custom-chat-header\">\n <div className=\"custom-chat-header-content\">\n <div className=\"custom-chat-title\">{title}</div>\n <div className=\"custom-chat-subtitle\">\n {subtitle}\n {currentMode === \"HUMAN\" && (\n <span className=\"custom-mode-indicator\">\n {\" \"}\n • {wsConnected ? \"🟢 Connected\" : \"🟡 Connecting...\"}\n </span>\n )}\n </div>\n {currentMode === \"HUMAN\" && (\n <>\n <div className=\"custom-mode-badge\">Human Support Mode</div>\n <div className=\"custom-agent-info\">\n <span className=\"custom-agent-label\">Agent:</span>\n <span className=\"custom-agent-name\">{currentAgent.name}</span>\n </div>\n </>\n )}\n {currentMode === \"BOT\" && (\n <div className=\"custom-mode-badge\">Bot Mode</div>\n )}\n </div>\n <button\n className=\"custom-chat-close-btn\"\n onClick={closeChat}\n aria-label=\"Close chat\"\n >\n ×\n </button>\n </div>\n\n <div className=\"custom-chat-messages\">\n {isInitializing && messages.length === 0 && (\n <div className=\"custom-chat-empty\">\n <div className=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n <p>Initializing chat...</p>\n </div>\n )}\n {!isInitializing && messages.length === 0 && (\n <div className=\"custom-chat-empty\">\n <div className=\"custom-chat-empty-icon\">👋</div>\n <p>{emptyStateMessage}</p>\n </div>\n )}\n {messages.map((message) => (\n <div\n key={message.id}\n className={`custom-message custom-message-${message.sender} ${\n isHandoffMessage(message.text) ? \"custom-handoff-message\" : \"\"\n }`}\n >\n <div \n className={`custom-message-content ${\n isHandoffMessage(message.text) ? \"custom-handoff-content\" : \"\"\n }`}\n dangerouslySetInnerHTML={{ \n __html: linkifyText(message.text).replace(/\\n/g, \"<br>\") \n }}\n />\n {(() => {\n // Debug: Log rich content structure\n if (debug && message.richContent) {\n console.log('Rendering message with richContent:', message.richContent);\n console.log('richContent type:', typeof message.richContent);\n console.log('richContent is array:', Array.isArray(message.richContent));\n console.log('richContent length:', message.richContent?.length);\n }\n \n // Check if richContent exists and has data\n if (message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0) {\n return (\n <div className=\"custom-chips-container\">\n {message.richContent.map((contentGroup, groupIndex) => {\n if (debug) {\n console.log(`Processing contentGroup ${groupIndex}:`, contentGroup);\n }\n if (!Array.isArray(contentGroup)) {\n // Handle case where contentGroup is not an array (single RichContent object)\n const content = contentGroup as RichContent;\n if (content && content.type === \"chips\" && content.options) {\n return (\n <div key={groupIndex} className=\"custom-chips-group\">\n {content.options.map((chip: ChipOption, chipIndex: number) => (\n <button\n key={chipIndex}\n className=\"custom-chip-button\"\n onClick={() => {\n const userMessage: Message = {\n id: Date.now().toString(),\n text: chip.text,\n sender: \"user\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, userMessage]);\n // Send the chip text instead of payload for better intent matching\n // Dialogflow will match the text to the intent\n sendMessage(chip.text, chip.text, true);\n }}\n type=\"button\"\n >\n {chip.text}\n </button>\n ))}\n </div>\n );\n }\n return null;\n }\n return contentGroup.map((content: RichContent, contentIndex: number) => {\n if (debug) {\n console.log(`Processing content ${groupIndex}-${contentIndex}:`, content);\n }\n if (content && content.type === \"chips\" && content.options) {\n return (\n <div key={`${groupIndex}-${contentIndex}`} className=\"custom-chips-group\">\n {content.options.map((chip: ChipOption, chipIndex: number) => (\n <button\n key={chipIndex}\n className=\"custom-chip-button\"\n onClick={() => {\n const userMessage: Message = {\n id: Date.now().toString(),\n text: chip.text,\n sender: \"user\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, userMessage]);\n // Send the chip text instead of payload for better intent matching\n sendMessage(chip.text, chip.text, true);\n }}\n type=\"button\"\n >\n {chip.text}\n </button>\n ))}\n </div>\n );\n }\n return null;\n });\n })}\n </div>\n );\n }\n return null;\n })()}\n <div className=\"custom-message-time\">\n {message.timestamp.toLocaleTimeString([], {\n hour: \"2-digit\",\n minute: \"2-digit\",\n })}\n </div>\n </div>\n ))}\n {isLoading && (\n <div className=\"custom-message custom-message-bot\">\n <div className=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n )}\n {isConnectingToAgent && (\n <div className=\"custom-message custom-message-bot\">\n <div className=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n <div className=\"custom-message-content\">\n Connecting to agent...\n </div>\n </div>\n )}\n {/* Agent Typing Indicator */}\n {currentMode === \"HUMAN\" && agentTyping && (\n <div className=\"custom-agent-typing-indicator\">\n <span className=\"custom-typing-dots\">\n <span></span>\n <span></span>\n <span></span>\n </span>\n <span className=\"custom-typing-text\">Agent is typing...</span>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form className=\"custom-chat-input-form\" onSubmit={handleSubmit}>\n <input\n type=\"text\"\n className=\"custom-chat-input\"\n value={inputValue}\n onChange={handleInputChange}\n placeholder={inputPlaceholder}\n disabled={isLoading || isInitializing || isStartingNewChat}\n />\n <button\n type=\"submit\"\n className=\"custom-chat-send-btn\"\n disabled={!inputValue.trim() || isLoading || isInitializing || isStartingNewChat}\n >\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </form>\n </div>\n )}\n </>\n );\n} ","/**\n * Framework Detection Utility\n * Detects which framework is available in the runtime environment\n */\n\nexport type Framework = 'react' | 'vue' | 'next' | 'nuxt' | 'vite' | 'vanilla';\n\nexport interface FrameworkInfo {\n name: Framework;\n version?: string;\n isSSR: boolean;\n}\n\n/**\n * Detects the framework in the current environment\n */\nexport function detectFramework(): FrameworkInfo {\n const isSSR = typeof window === 'undefined';\n \n // Check for Next.js\n // Use safe property access to avoid bundling process.env\n if (typeof process !== 'undefined' && typeof (process as any).env !== 'undefined') {\n const env = (process as any).env;\n if (env?.NEXT_RUNTIME) {\n return {\n name: 'next',\n version: env.NEXT_VERSION,\n isSSR,\n };\n }\n }\n \n // Check for Nuxt\n if (typeof process !== 'undefined' && typeof (process as any).env !== 'undefined') {\n const env = (process as any).env;\n if (env?.NUXT || (globalThis as any).__NUXT__) {\n return {\n name: 'nuxt',\n version: env.NUXT_VERSION,\n isSSR,\n };\n }\n }\n \n // Also check for Nuxt via globalThis (SSR-safe)\n if ((globalThis as any).__NUXT__) {\n return {\n name: 'nuxt',\n version: undefined,\n isSSR,\n };\n }\n \n // Check for Vite (development)\n if (typeof import.meta !== 'undefined') {\n const meta = import.meta as any;\n if (meta.env?.DEV) {\n return {\n name: 'vite',\n version: meta.env?.VITE_VERSION,\n isSSR,\n };\n }\n }\n \n // Check for React\n if (detectReact()) {\n return {\n name: 'react',\n version: getReactVersion(),\n isSSR,\n };\n }\n \n // Check for Vue\n if (detectVue()) {\n return {\n name: 'vue',\n version: getVueVersion(),\n isSSR,\n };\n }\n \n // Default to vanilla\n return {\n name: 'vanilla',\n isSSR,\n };\n}\n\n/**\n * Detects if React is available\n */\nfunction detectReact(): boolean {\n // Check global React\n if (typeof window !== 'undefined') {\n if ((window as any).React || (window as any).react) {\n return true;\n }\n }\n \n // Note: Removed module.hot check as it's Node-specific and not available in browser ESM\n \n // For ESM environments, we can't use require.resolve\n // Instead, we check for common React indicators\n if (typeof document !== 'undefined') {\n // Check if React DevTools are present (indicates React is loaded)\n if ((window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__) {\n return true;\n }\n }\n \n return false;\n}\n\n/**\n * Gets React version if available\n */\nfunction getReactVersion(): string | undefined {\n try {\n if (typeof window !== 'undefined' && (window as any).React?.version) {\n return (window as any).React.version;\n }\n \n // In ESM environments, we can't use require\n // Try to get version from React DevTools hook if available\n if (typeof window !== 'undefined' && (window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__) {\n const hook = (window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__;\n if (hook.renderers && hook.renderers.size > 0) {\n const renderer = Array.from(hook.renderers.values())[0] as any;\n return renderer.version;\n }\n }\n } catch {\n // Version not available\n }\n \n return undefined;\n}\n\n/**\n * Detects if Vue is available\n */\nfunction detectVue(): boolean {\n // Check global Vue\n if (typeof window !== 'undefined') {\n if ((window as any).Vue || (window as any).vue) {\n return true;\n }\n }\n \n // For ESM environments, we can't use require.resolve\n // Check for Vue DevTools or other indicators\n if (typeof window !== 'undefined') {\n // Check if Vue DevTools are present\n if ((window as any).__VUE_DEVTOOLS_GLOBAL_HOOK__) {\n return true;\n }\n }\n \n return false;\n}\n\n/**\n * Gets Vue version if available\n */\nfunction getVueVersion(): string | undefined {\n try {\n if (typeof window !== 'undefined' && (window as any).Vue?.version) {\n return (window as any).Vue.version;\n }\n \n // In ESM environments, we can't use require\n // Try to get version from Vue DevTools hook if available\n if (typeof window !== 'undefined' && (window as any).__VUE_DEVTOOLS_GLOBAL_HOOK__) {\n const hook = (window as any).__VUE_DEVTOOLS_GLOBAL_HOOK__;\n if (hook.apps && hook.apps.length > 0) {\n const app = hook.apps[0];\n return app.version;\n }\n }\n } catch {\n // Version not available\n }\n \n return undefined;\n}\n\n/**\n * Forces a specific framework (useful for testing or explicit configuration)\n */\nlet forcedFramework: Framework | null = null;\n\nexport function setFramework(framework: Framework): void {\n forcedFramework = framework;\n}\n\nexport function getFramework(): FrameworkInfo {\n if (forcedFramework) {\n return {\n name: forcedFramework,\n isSSR: typeof window === 'undefined',\n };\n }\n return detectFramework();\n}\n","'use strict';\n\nvar m = require('react-dom');\nif (process.env.NODE_ENV === 'production') {\n exports.createRoot = m.createRoot;\n exports.hydrateRoot = m.hydrateRoot;\n} else {\n var i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;\n exports.createRoot = function(c, o) {\n i.usingClientEntryPoint = true;\n try {\n return m.createRoot(c, o);\n } finally {\n i.usingClientEntryPoint = false;\n }\n };\n exports.hydrateRoot = function(c, h, o) {\n i.usingClientEntryPoint = true;\n try {\n return m.hydrateRoot(c, h, o);\n } finally {\n i.usingClientEntryPoint = false;\n }\n };\n}\n","/**\n * Vanilla JavaScript Entry Point\n * Uses the original ChatWidget.tsx component via ReactDOM\n * Reuses the same component to reduce code duplication\n */\n\nimport React from 'react';\nimport { createRoot, Root } from 'react-dom/client';\nimport ChatWidgetComponent from '../components/ChatWidget';\nimport type { ChatWidgetProps } from '../components/ChatWidget';\nimport '../styles/chatWidget.css';\n\n/**\n * Vanilla JS Chat Widget\n * Renders the original React component using ReactDOM\n * This reuses the same component code, reducing duplication\n */\nexport class ChatWidget {\n private container: HTMLElement;\n private config: ChatWidgetProps;\n private root: Root | null = null;\n\n constructor(container: HTMLElement | string, config: ChatWidgetProps) {\n this.config = config;\n \n // Get container element\n if (typeof container === 'string') {\n const element = document.querySelector(container);\n if (!element) {\n throw new Error(`Container element \"${container}\" not found`);\n }\n this.container = element as HTMLElement;\n } else {\n this.container = container;\n }\n\n // Create React root and render the component\n // This reuses the same ChatWidget.tsx component\n this.root = createRoot(this.container);\n this.render();\n }\n\n private render(): void {\n // Render the original React component using ReactDOM\n // This reuses the same component code, reducing duplication\n if (this.root) {\n this.root.render(React.createElement(ChatWidgetComponent, this.config));\n }\n }\n\n /**\n * Update configuration\n */\n updateConfig(config: Partial<ChatWidgetProps>): void {\n this.config = { ...this.config, ...config };\n this.render();\n }\n\n /**\n * Destroy the widget\n */\n destroy(): void {\n if (this.root) {\n this.root.unmount();\n this.root = null;\n }\n }\n}\n\n/**\n * Factory function for easier usage\n */\nexport function createChatWidget(\n container: HTMLElement | string,\n config: ChatWidgetProps\n): ChatWidget {\n return new ChatWidget(container, config);\n}\n\nexport default ChatWidget;\n"],"names":["ChatWidget","m","welcomeMessage","ChatWidgetComponent"],"mappings":"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","x_google_ignoreList":[3]}
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/hooks/useChatMode.ts","../src/components/ChatWidget.tsx","../src/utils/frameworkDetector.ts","../node_modules/react-dom/client.js","../src/entry/vanilla.ts"],"sourcesContent":["// hooks/useChatMode.ts\nimport { useState, useEffect, useCallback } from \"react\";\nimport type { ChatResponse } from \"../services/dialogflowBackendService\";\n\nexport type ChatMode = \"BOT\" | \"HUMAN\";\n\nconst MODE_STORAGE_KEY = \"chartsconnectect_chat_mode\";\nconst CHAT_ID_STORAGE_KEY = \"chartsconnect_chat_id\";\nconst SESSION_ID_STORAGE_KEY = \"chartsconnect_session_id\";\n\nexport interface UseChatModeReturn {\n currentMode: ChatMode;\n switchToHumanMode: () => void;\n switchToBotMode: () => void;\n isHandoffTriggered: (dialogflowResponse: ChatResponse) => boolean;\n chatId: string | null;\n sessionId: string | null;\n setChatId: (id: string | null) => void;\n setSessionId: (id: string | null) => void;\n}\n\n/**\n * Hook to manage chat mode (BOT or HUMAN)\n */\nexport function useChatMode(): UseChatModeReturn {\n const [currentMode, setCurrentMode] = useState<ChatMode>(() => {\n // Load from localStorage on init\n const savedMode = localStorage.getItem(MODE_STORAGE_KEY);\n return (savedMode === \"HUMAN\" ? \"HUMAN\" : \"BOT\") as ChatMode;\n });\n\n const [chatId, setChatIdState] = useState<string | null>(() => {\n return localStorage.getItem(CHAT_ID_STORAGE_KEY);\n });\n\n const [sessionId, setSessionIdState] = useState<string | null>(() => {\n return localStorage.getItem(SESSION_ID_STORAGE_KEY);\n });\n\n // Persist mode to localStorage\n useEffect(() => {\n localStorage.setItem(MODE_STORAGE_KEY, currentMode);\n }, [currentMode]);\n\n // Persist chat_id to localStorage\n const setChatId = useCallback((id: string | null) => {\n setChatIdState(id);\n if (id) {\n localStorage.setItem(CHAT_ID_STORAGE_KEY, id);\n } else {\n localStorage.removeItem(CHAT_ID_STORAGE_KEY);\n }\n }, []);\n\n // Persist session_id to localStorage\n const setSessionId = useCallback((id: string | null) => {\n setSessionIdState(id);\n if (id) {\n localStorage.setItem(SESSION_ID_STORAGE_KEY, id);\n } else {\n localStorage.removeItem(SESSION_ID_STORAGE_KEY);\n }\n }, []);\n\n const switchToHumanMode = useCallback(() => {\n setCurrentMode(\"HUMAN\");\n }, []);\n\n const switchToBotMode = useCallback(() => {\n setCurrentMode(\"BOT\");\n }, []);\n\n /**\n * Check if Dialogflow response contains handoff trigger\n * Handoff is triggered when response contains {\"handoff\": true}\n * This can be in:\n * - queryResult.parameters.handoff\n * - queryResult.responseMessages payload\n * - queryResult.intent.displayName (if configured)\n */\n const isHandoffTriggered = useCallback(\n (dialogflowResponse: ChatResponse): boolean => {\n // Check if response has handoff flag\n // This would need to be extracted from Dialogflow response\n // For now, we'll check the response text or any custom fields\n \n // The handoff flag might come from Dialogflow's custom payload\n // We need to check the actual Dialogflow response structure\n // Since ChatResponse doesn't include the full response, we'll need to\n // modify the dialogflowClient to pass through handoff information\n \n // For now, return false - this will be handled by dialogflowHandler\n return false;\n },\n []\n );\n\n return {\n currentMode,\n switchToHumanMode,\n switchToBotMode,\n isHandoffTriggered,\n chatId,\n sessionId,\n setChatId,\n setSessionId,\n };\n}\n\n","import React, { useState, useEffect, useRef, useCallback } from \"react\";\nimport {\n createDialogflowSession,\n sendDialogflowMessage,\n type DialogflowBackendConfig,\n type SessionResponse,\n type ChatResponse,\n} from \"../services/dialogflowBackendService\";\nimport { useChatMode } from \"../hooks/useChatMode\";\nimport { ChatResolvedError, createChatService, type WebSocketMessage } from \"../services/chatService\";\nimport { linkifyText } from \"../utils/sanitize\";\nimport \"../styles/chatWidget.css\";\n\ninterface ChipOption {\n text: string;\n payload: string;\n}\n\ninterface RichContent {\n type?: string;\n options?: ChipOption[];\n}\n\ntype RichContentArray = RichContent | RichContent[];\n\ninterface Message {\n id: string;\n text: string;\n sender: \"user\" | \"bot\" | \"agent\";\n timestamp: Date;\n richContent?: RichContentArray[];\n}\n\nexport interface ChatWidgetProps {\n /** Custom title for the chat widget */\n title?: string;\n /** Custom subtitle for the chat widget */\n subtitle?: string;\n /** Welcome popup title */\n welcomeTitle?: string;\n /** Welcome popup message */\n welcomeMessage?: string;\n /** Welcome popup CTA text */\n welcomeCta?: string;\n /** Whether to show the welcome popup */\n showWelcomePopup?: boolean;\n /** Delay in milliseconds before showing welcome popup */\n welcomePopupDelay?: number;\n /** Fallback welcome message if API fails */\n fallbackWelcomeMessage?: string;\n /** Placeholder text for input field */\n inputPlaceholder?: string;\n /** Custom empty state message */\n emptyStateMessage?: string;\n /** Enable/disable debug logging */\n debug?: boolean;\n /** Dialogflow project ID */\n dfProjectId?: string;\n /** Dialogflow location (e.g., \"us-central1\") */\n dfLocation?: string;\n /** Dialogflow agent ID */\n dfAgentId?: string;\n /** Language code for Dialogflow */\n languageCode?: string;\n /** Backend API base URL (default: http://localhost:8012) */\n backendBaseUrl?: string;\n /** WebSocket URL (default: ws://localhost:8012) */\n backendWsUrl?: string;\n}\n\nexport default function ChatWidget({\n title = \"💬 Charts Connect AI Assistant\",\n subtitle = \"We're here to help\",\n welcomeTitle = \"👋 Welcome to Charts Connect\",\n welcomeMessage = \"My name is Charts Connect AI Assistant and I'll guide you.\",\n welcomeCta = \"💬 Click here to start chatting!\",\n showWelcomePopup: enableWelcomePopup = true,\n welcomePopupDelay = 1500,\n fallbackWelcomeMessage = \"Hello! I'm Charts Connect AI Assistant. How can I help you today?\",\n inputPlaceholder = \"Type your message...\",\n emptyStateMessage = \"Hi! I'm Charts Connect AI Assistant. How can I help you today?\",\n debug = false,\n dfProjectId,\n dfLocation = \"us-central1\",\n dfAgentId,\n languageCode = \"en\",\n backendBaseUrl,\n backendWsUrl,\n}: ChatWidgetProps) {\n // Unique ID generator to avoid message ID collisions\n const msgIdCounter = useRef(0);\n const uid = (prefix: string = \"msg\") => `${prefix}-${Date.now()}-${++msgIdCounter.current}`;\n\n const [isOpen, setIsOpen] = useState(false);\n const [showWelcomePopup, setShowWelcomePopup] = useState(false);\n const [messages, setMessages] = useState<Message[]>([]);\n const [inputValue, setInputValue] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [sessionId, setSessionId] = useState<string | null>(null);\n const [isInitializing, setIsInitializing] = useState(false);\n const [isConnectingToAgent, setIsConnectingToAgent] = useState(false);\n const [wsConnected, setWsConnected] = useState(false);\n const [agentTyping, setAgentTyping] = useState(false);\n const [currentAgent, setCurrentAgent] = useState<{ name: string; id?: string }>({ name: \"Agent\" });\n const [chatResolved, setChatResolved] = useState(false);\n const [isStartingNewChat, setIsStartingNewChat] = useState(false);\n const [agentAccepted, setAgentAccepted] = useState(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const typingTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const agentTypingTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const creatingSessionRef = useRef(false); // Prevent race condition in createSession\n const resolvedResetTimerRef = useRef<NodeJS.Timeout | null>(null); // Guard resolved-state reset\n const createSessionRef = useRef<((forceRecreate?: boolean, reuseSessionId?: boolean) => Promise<string | null>) | null>(null); // Ref for createSession to avoid stale closure\n \n // Get backend URLs from props or environment variables (injected at build time)\n const getBackendBaseUrl = () => {\n return backendBaseUrl || process.env.REACT_APP_BACKEND_BASE_URL || '';\n };\n\n const getBackendWsUrl = () => {\n return backendWsUrl || process.env.REACT_APP_BACKEND_WS_URL || '';\n };\n \n const chatServiceRef = useRef(\n createChatService({ \n baseUrl: getBackendBaseUrl(), \n wsUrl: getBackendWsUrl(),\n debug: debug\n })\n );\n const historyLoadedRef = useRef<string | null>(null);\n \n // Use chat mode hook\n const {\n currentMode,\n switchToHumanMode,\n switchToBotMode,\n chatId,\n sessionId: supportSessionId,\n setChatId,\n setSessionId: setSupportSessionId,\n } = useChatMode();\n\n const enterResolvedState = useCallback(\n (_resolvedChatId?: string | null) => {\n setChatResolved(true);\n setIsConnectingToAgent(false);\n setAgentAccepted(false);\n setAgentTyping(false);\n if (agentTypingTimeoutRef.current) {\n clearTimeout(agentTypingTimeoutRef.current);\n agentTypingTimeoutRef.current = null;\n }\n\n // Stop WS + prevent any reuse of the old chat_id\n chatServiceRef.current.disconnectWebSocket();\n setChatId(null);\n setSupportSessionId(null);\n setSessionId(null); // Fix #1: Clear sessionId to force new session creation\n \n // Add thank you message before reset\n const thankYouMessage: Message = {\n id: uid(\"resolved\"),\n text: \"Thank you for contacting us!\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, thankYouMessage]);\n \n // Automatically reset to BOT mode after showing thank you message\n // Use a ref-tracked timer so reopening chat won't race with the reset\n if (resolvedResetTimerRef.current) clearTimeout(resolvedResetTimerRef.current);\n resolvedResetTimerRef.current = setTimeout(() => {\n resolvedResetTimerRef.current = null;\n switchToBotMode();\n setChatResolved(false);\n setMessages([]);\n // Recreate Dialogflow session to start fresh (sessionId already cleared above)\n // Use ref to access latest createSession function to avoid stale closure\n if (createSessionRef.current) {\n createSessionRef.current().catch(console.error);\n }\n }, 2000); // 2 second delay to show thank you message\n },\n [setChatId, setSupportSessionId, switchToBotMode] // createSession accessed via ref, no need in deps\n );\n\n const handleStartNewChat = useCallback(async () => {\n if (isStartingNewChat) return;\n setIsStartingNewChat(true);\n try {\n const newSession = await chatServiceRef.current.startSupportChat(\n sessionId || null\n );\n\n switchToHumanMode();\n setChatId(newSession.chat_id);\n setSupportSessionId(newSession.session_id);\n setChatResolved(false);\n setInputValue(\"\");\n } catch (error: any) {\n console.error(\"Error starting new chat:\", error);\n setMessages((prev) => [\n ...prev,\n {\n id: uid(\"error\"),\n text: debug\n ? `Error: ${error?.message || \"Failed to start a new chat.\"}`\n : \"Sorry, I couldn't start a new chat. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n },\n ]);\n } finally {\n setIsStartingNewChat(false);\n }\n }, [\n debug,\n isStartingNewChat,\n sessionId,\n setChatId,\n setSupportSessionId,\n switchToHumanMode,\n ]);\n\n // Helper function to build Dialogflow config from props\n const getDialogflowConfig = (): DialogflowBackendConfig | undefined => {\n if (!dfProjectId || !dfAgentId) {\n return undefined;\n }\n \n return {\n dfProjectId,\n dfLocation: dfLocation || 'us-central1',\n dfAgentId,\n languageCode: languageCode || 'en',\n backendBaseUrl: getBackendBaseUrl(),\n };\n };\n\n // Show welcome popup after page load (only if chat is not already open)\n useEffect(() => {\n if (!enableWelcomePopup) return;\n\n const timer = setTimeout(() => {\n if (!isOpen) {\n setShowWelcomePopup(true);\n }\n }, welcomePopupDelay);\n return () => clearTimeout(timer);\n }, [enableWelcomePopup, welcomePopupDelay, isOpen]);\n\n // Auto-scroll to bottom when new messages arrive (debounced to avoid jitter)\n const scrollTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n useEffect(() => {\n if (scrollTimeoutRef.current) clearTimeout(scrollTimeoutRef.current);\n scrollTimeoutRef.current = setTimeout(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, 80);\n return () => {\n if (scrollTimeoutRef.current) clearTimeout(scrollTimeoutRef.current);\n };\n }, [messages]);\n\n // Handle agent changed notification\n const handleAgentChanged = useCallback((message: WebSocketMessage) => {\n if (message.to_agent) {\n setCurrentAgent({\n id: message.to_agent_id,\n name: message.to_agent,\n });\n\n // Add system message to chat\n const systemMessage: Message = {\n id: uid(\"system\"),\n text: message.from_agent\n ? `Chat has been transferred from ${message.from_agent} to ${message.to_agent}`\n : `Chat has been transferred to ${message.to_agent}`,\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, systemMessage]);\n\n if (debug) {\n console.log(\"Agent changed:\", {\n from: message.from_agent,\n to: message.to_agent,\n reason: message.reason,\n });\n }\n }\n }, [debug]);\n\n // Handle WebSocket messages\n const handleWebSocketMessage = useCallback((message: WebSocketMessage) => {\n switch (message.type) {\n case \"message\":\n if (message.content) {\n // Only display messages from agent, ignore customer messages (we already added them)\n if (message.sender_type === \"agent\" || !message.sender_type) {\n const agentMessage: Message = {\n id: message.id || uid(\"agent\"),\n text: message.content,\n sender: \"agent\",\n timestamp: new Date(message.timestamp || Date.now()),\n };\n setMessages((prev) => {\n // Avoid duplicate messages by checking if message ID already exists\n const existingIds = new Set(prev.map(m => m.id));\n if (existingIds.has(agentMessage.id)) {\n return prev;\n }\n return [...prev, agentMessage];\n });\n // Hide typing indicator when message received\n setAgentTyping(false);\n if (agentTypingTimeoutRef.current) {\n clearTimeout(agentTypingTimeoutRef.current);\n agentTypingTimeoutRef.current = null;\n }\n } else if (debug && message.sender_type === \"customer\") {\n console.log(\"Ignoring customer message from WebSocket (already added)\");\n }\n // If sender_type is \"customer\", ignore it - we already added the user message\n } else if (debug) {\n console.warn(\"WebSocket message received without content:\", message);\n }\n break;\n\n case \"typing_start\":\n if (message.sender_type === \"agent\") {\n setAgentTyping(true);\n // Auto-hide after 3 seconds if no message received\n if (agentTypingTimeoutRef.current) {\n clearTimeout(agentTypingTimeoutRef.current);\n }\n agentTypingTimeoutRef.current = setTimeout(() => {\n setAgentTyping(false);\n }, 3000);\n }\n break;\n\n case \"typing_stop\":\n if (message.sender_type === \"agent\") {\n setAgentTyping(false);\n if (agentTypingTimeoutRef.current) {\n clearTimeout(agentTypingTimeoutRef.current);\n agentTypingTimeoutRef.current = null;\n }\n }\n break;\n\n case \"agent_changed\":\n handleAgentChanged(message);\n break;\n\n case \"chat_info\":\n if (debug) {\n console.log(\"Chat info:\", message);\n }\n // Update connection status based on chat info\n if (message.status === \"active\") {\n setIsConnectingToAgent(false);\n setAgentAccepted(true);\n } else if (message.status === \"resolved\" || message.status === \"ended\") {\n enterResolvedState(message.chat_id || null);\n }\n // Update agent info if provided\n if (message.agent_id) {\n setCurrentAgent((prev) => ({\n ...prev,\n id: message.agent_id,\n }));\n }\n break;\n\n case \"agent_accepted\":\n // Agent has accepted the chat request\n setAgentAccepted(true);\n setIsConnectingToAgent(false);\n const acceptedMessage: Message = {\n id: message.id || uid(\"agent-accepted\"),\n text: \"You can chat now, the agent has accepted your request.\",\n sender: \"bot\",\n timestamp: message.timestamp ? new Date(message.timestamp) : new Date(),\n };\n setMessages((prev) => {\n // Avoid duplicate messages\n const existingIds = new Set(prev.map(m => m.id));\n if (existingIds.has(acceptedMessage.id)) {\n return prev;\n }\n return [...prev, acceptedMessage];\n });\n // Update agent info if provided\n if (message.to_agent) {\n setCurrentAgent({\n name: message.to_agent,\n id: message.to_agent_id,\n });\n }\n if (debug) {\n console.log(\"Agent accepted chat:\", message);\n }\n break;\n\n case \"chat_resolved\":\n case \"chat_ended\":\n // Chat has been resolved/ended by agent (terminal state)\n enterResolvedState(message.chat_id || null);\n if (debug) {\n console.log(\"Chat resolved/ended:\", message);\n }\n break;\n\n case \"error\":\n console.error(\"WebSocket error:\", message.error);\n const errorMessage: Message = {\n id: uid(\"error\"),\n text: message.error || \"An error occurred. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n break;\n\n case \"pong\":\n // Keep-alive response, no action needed\n break;\n\n default:\n if (debug) {\n console.log(\"Unknown message type:\", message.type);\n }\n }\n }, [debug, enterResolvedState, handleAgentChanged]);\n\n const handleWebSocketClose = useCallback(\n (event: CloseEvent) => {\n // Backend uses 4000 to indicate the chat is resolved, and then closes.\n if (event.code === 4000) {\n enterResolvedState(chatId);\n }\n },\n [chatId, enterResolvedState]\n );\n\n // Handle WebSocket connection changes\n const handleConnectionChange = useCallback((connected: boolean) => {\n setWsConnected(connected);\n if (connected) {\n setIsConnectingToAgent(false);\n }\n }, []);\n\n // Initialize WebSocket when switching to HUMAN mode\n useEffect(() => {\n if (currentMode === \"HUMAN\" && chatId && supportSessionId) {\n chatServiceRef.current.connectWebSocket(\n chatId,\n supportSessionId,\n handleWebSocketMessage,\n handleConnectionChange,\n handleWebSocketClose\n );\n\n return () => {\n chatServiceRef.current.disconnectWebSocket();\n };\n }\n }, [\n currentMode,\n chatId,\n supportSessionId,\n handleWebSocketMessage,\n handleConnectionChange,\n handleWebSocketClose,\n ]);\n\n // Load message history from backend\n const loadMessageHistory = useCallback(async (preserveExisting: boolean = true) => {\n if (!chatId || !supportSessionId) return;\n\n try {\n setIsLoading(true);\n const history = await chatServiceRef.current.loadMessageHistory(chatId, supportSessionId);\n \n const historyMessages: Message[] = history.map((msg) => ({\n id: msg.id || uid(\"history\"),\n text: msg.content,\n sender: msg.sender_type === \"agent\" ? \"agent\" : \"user\",\n timestamp: new Date(msg.timestamp),\n }));\n\n if (preserveExisting) {\n // Merge with existing messages, avoiding duplicates\n setMessages((prevMessages) => {\n const existingIds = new Set(prevMessages.map(m => m.id));\n const newMessages = historyMessages.filter(m => !existingIds.has(m.id));\n \n // Combine existing messages with new history messages\n // Sort by timestamp to maintain chronological order\n const combined = [...prevMessages, ...newMessages].sort((a, b) => \n a.timestamp.getTime() - b.timestamp.getTime()\n );\n \n return combined;\n });\n } else {\n // Replace all messages (only if explicitly requested)\n setMessages(historyMessages);\n }\n } catch (error: any) {\n console.error(\"Error loading message history:\", error);\n if (debug) {\n const errorMessage: Message = {\n id: uid(\"error\"),\n text: `Failed to load chat history: ${error.message}`,\n sender: \"bot\",\n timestamp: new Date(),\n };\n // Only add error message, don't replace existing messages\n setMessages((prev) => [...prev, errorMessage]);\n }\n } finally {\n setIsLoading(false);\n }\n }, [chatId, supportSessionId, debug]);\n\n // Load message history when switching to HUMAN mode\n useEffect(() => {\n if (currentMode === \"HUMAN\" && chatId && supportSessionId) {\n // Only load if we haven't loaded history for this chat session yet\n const sessionKey = `${chatId}-${supportSessionId}`;\n if (historyLoadedRef.current !== sessionKey) {\n historyLoadedRef.current = sessionKey;\n // Check if we have existing messages (from bot conversation during handoff)\n // If yes, preserve them and don't load history\n // If no, load history for new chat\n // Access messages state via a ref or check in the next tick\n const checkAndLoad = () => {\n // Check messages length - if 0, load history; if > 0, preserve existing\n if (messages.length === 0) {\n // No existing messages, load history\n loadMessageHistory(false).catch(console.error);\n }\n // Has existing messages (bot conversation), keep them - don't load history\n };\n // Use setTimeout to ensure we check after state updates\n setTimeout(checkAndLoad, 0);\n }\n } else if (currentMode === \"BOT\") {\n // Reset history loaded flag when switching back to BOT mode\n historyLoadedRef.current = null;\n }\n }, [currentMode, chatId, supportSessionId, loadMessageHistory, messages.length]);\n\n // Handle handoff from Dialogflow\n const handleHandoff = async (webhookChatId?: string, webhookSessionId?: string) => {\n try {\n setIsConnectingToAgent(true);\n\n // Get Dialogflow session ID if available\n const dialogflowSessionId = sessionId;\n\n // STEP 1: Use chat created by webhook if provided, otherwise ensure one exists\n const session = webhookChatId && webhookSessionId\n ? { chat_id: webhookChatId, session_id: webhookSessionId }\n : await chatServiceRef.current.ensureChatInitialized(\n chatId,\n supportSessionId,\n dialogflowSessionId || null\n );\n \n if (!session || !session.chat_id) {\n throw new Error(\"Failed to initialize chat session\");\n }\n \n const currentChatId = session.chat_id;\n const currentSupportSessionId = session.session_id;\n \n // Update state if chat was newly initialized\n if (currentChatId !== chatId) {\n setChatId(currentChatId);\n setSupportSessionId(currentSupportSessionId);\n if (debug) {\n console.log(\"✅ Chat initialized:\", { chatId: currentChatId, sessionId: currentSupportSessionId });\n }\n }\n\n // STEP 2: Only request handoff if the frontend created the chat\n // Skip if webhookChatId is provided — the webhook already created the chat with \"waiting\" status\n if (!webhookChatId) {\n try {\n await chatServiceRef.current.requestHandoff(\n currentChatId,\n currentSupportSessionId,\n \"Customer requested human agent\",\n dialogflowSessionId || null\n );\n\n if (debug) {\n console.log(\"✅ Handoff requested successfully\");\n }\n } catch (handoffError: any) {\n // Handle 401/404 or \"chat not found\" - clear chat_id and retry (but keep session logic)\n if (handoffError.message?.includes(\"Invalid chat_id\") ||\n handoffError.message?.includes(\"Chat not found\") ||\n handoffError.message?.includes(\"unauthorized\") ||\n handoffError.message?.includes(\"400\") ||\n handoffError.message?.includes(\"401\") ||\n handoffError.message?.includes(\"404\") ||\n handoffError.message?.includes(\"expired\")) {\n if (debug) {\n console.log(\"⚠️ Chat expired or not found. Re-initializing chat...\");\n }\n\n // Clear old chat_id (but keep session logic - session_id is managed by sessionManager)\n setChatId(null);\n setSupportSessionId(null);\n\n // Create new chat session (session_id will be automatically included from session manager)\n const newSession = await chatServiceRef.current.startSupportChat(\n dialogflowSessionId || null\n );\n\n if (!newSession || !newSession.chat_id) {\n throw new Error(\"Failed to re-initialize chat session\");\n }\n\n const newChatId = newSession.chat_id;\n const newSessionId = newSession.session_id;\n setChatId(newChatId);\n setSupportSessionId(newSessionId);\n\n // Retry handoff with new chat_id\n await chatServiceRef.current.requestHandoff(\n newChatId,\n newSessionId,\n \"Customer requested human agent\",\n dialogflowSessionId || null\n );\n\n if (debug) {\n console.log(\"✅ Handoff requested successfully after retry\");\n }\n\n // Update for message history loading\n const newSessionKey = `${newChatId}-${newSessionId}`;\n if (historyLoadedRef.current !== newSessionKey) {\n historyLoadedRef.current = newSessionKey;\n await loadMessageHistory(true);\n }\n } else {\n throw handoffError;\n }\n }\n } else if (debug) {\n console.log(\"✅ Using webhook-created chat, skipping requestHandoff\");\n }\n\n // Switch to human mode\n switchToHumanMode();\n // Reset states for new handoff\n setChatResolved(false);\n setAgentAccepted(false);\n\n // Don't load history during handoff - preserve existing bot conversation\n // History will be loaded automatically via useEffect if needed for new sessions\n const sessionKey = `${currentChatId}-${currentSupportSessionId}`;\n historyLoadedRef.current = sessionKey;\n } catch (error: any) {\n console.error(\"Error handling handoff:\", error);\n const errorMessage: Message = {\n id: uid(\"error\"),\n text: debug\n ? `Handoff error: ${error.message}`\n : \"Failed to connect to agent. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n setIsConnectingToAgent(false);\n }\n };\n\n // Create new session\n const createSession = async (forceRecreate: boolean = false, reuseSessionId: boolean = false) => {\n // If sessionId exists and we're not forcing recreation, return existing session\n // Unless reuseSessionId is true (then we'll pass it to backend to potentially reuse)\n if (sessionId && !forceRecreate && !reuseSessionId) return sessionId;\n\n // Prevent race condition: if already creating, wait and return existing session\n if (creatingSessionRef.current) {\n // Wait a bit for the concurrent call to complete\n await new Promise(resolve => setTimeout(resolve, 100));\n if (sessionId) return sessionId; // Return if session was created by concurrent call\n throw new Error('Session creation in progress. Please try again.');\n }\n\n creatingSessionRef.current = true;\n\n try {\n setIsInitializing(true);\n const dfConfig = getDialogflowConfig();\n if (!dfConfig) {\n throw new Error('Dialogflow configuration is missing. Please provide dfProjectId and dfAgentId.');\n }\n \n // Pass existing sessionId if reuseSessionId is true and sessionId exists\n // Backend can decide whether to reuse it or create a new one\n const existingSessionId = (reuseSessionId && sessionId) ? sessionId : null;\n const data = await createDialogflowSession(dfConfig, existingSessionId);\n setSessionId(data.session_id);\n\n // Add welcome message from backend\n if (data.message) {\n if (debug) {\n console.log('Session response richContent:', data.richContent);\n console.log('Full session response:', data);\n }\n \n const welcomeMessage: Message = {\n id: uid(\"welcome\"),\n text: data.message,\n sender: \"bot\",\n timestamp: new Date(),\n richContent: data.richContent,\n };\n // Preserve existing messages instead of replacing (fix message replacement bug)\n setMessages((prev) => {\n // Only replace if no messages exist, otherwise prepend welcome message\n if (prev.length === 0) {\n return [welcomeMessage];\n }\n return [welcomeMessage, ...prev];\n });\n }\n\n return data.session_id;\n } catch (error: any) {\n console.error(\"Error creating session:\", error);\n if (debug) {\n console.error(\"Full error details:\", {\n message: error.message,\n stack: error.stack,\n config: getDialogflowConfig(),\n });\n }\n // Show error message to user\n const errorMessage: Message = {\n id: uid(\"error\"),\n text: debug \n ? `Error: ${error.message || 'Failed to create session. Please check your Dialogflow configuration.'}`\n : fallbackWelcomeMessage,\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n return null;\n } finally {\n setIsInitializing(false);\n creatingSessionRef.current = false; // Release lock\n }\n };\n\n // Update createSession ref when function is defined (fixes stale closure issue)\n createSessionRef.current = createSession;\n\n // Note: Dialogflow manages conversation history internally\n // History is maintained through the session, so we don't need to load it separately\n\n // Send message to backend API\n const sendingRef = useRef(false);\n const sendMessage = async (text: string, displayText?: string, skipUserMessage: boolean = false) => {\n if (!text.trim() || sendingRef.current) return;\n sendingRef.current = true;\n try {\n await sendMessageInner(text, displayText, skipUserMessage);\n } finally {\n sendingRef.current = false;\n }\n };\n\n const sendMessageInner = async (text: string, displayText?: string, skipUserMessage: boolean = false) => {\n if (!text.trim()) return;\n\n // Handle HUMAN mode\n if (currentMode === \"HUMAN\") {\n if (!chatId || !supportSessionId) {\n const errorMessage: Message = {\n id: uid(\"msg\"),\n text: \"Chat session not initialized. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n return;\n }\n\n // Add user message unless skipped\n if (!skipUserMessage) {\n const userMessage: Message = {\n id: uid(\"msg\"),\n text: displayText || text.trim(),\n sender: \"user\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, userMessage]);\n }\n\n // Send typing_stop before sending message\n chatServiceRef.current.sendTypingIndicator(\"typing_stop\");\n \n // Clear typing timeout\n if (typingTimeoutRef.current) {\n clearTimeout(typingTimeoutRef.current);\n typingTimeoutRef.current = null;\n }\n\n setInputValue(\"\");\n setIsLoading(true);\n\n try {\n // Try WebSocket first, fallback to REST API\n const sentViaWs = chatServiceRef.current.sendMessageViaWebSocket(text.trim());\n \n if (!sentViaWs) {\n // Fallback to REST API\n await chatServiceRef.current.sendMessageToAgent(chatId, supportSessionId, text.trim());\n }\n } catch (error: any) {\n // chat_resolved is a normal terminal success condition, not an error.\n if (\n error instanceof ChatResolvedError ||\n error?.name === \"ChatResolvedError\" ||\n error?.message === \"chat_resolved\"\n ) {\n enterResolvedState(chatId);\n return;\n }\n\n console.error(\"Error sending message to agent:\", error);\n \n // Handle 401/404 - clear chat_id and reinitialize (but keep session logic)\n if (error.message?.includes(\"Chat not found\") ||\n error.message?.includes(\"unauthorized\") ||\n error.message?.includes(\"401\") ||\n error.message?.includes(\"404\")) {\n if (debug) {\n console.log(\"⚠️ Chat expired. Re-initializing...\");\n }\n \n // Clear chat_id (session_id is managed by sessionManager)\n setChatId(null);\n setSupportSessionId(null);\n \n // Try to reinitialize chat\n try {\n const newSession = await chatServiceRef.current.startSupportChat(\n sessionId || null\n );\n setChatId(newSession.chat_id);\n setSupportSessionId(newSession.session_id);\n \n // Retry sending message\n try {\n await chatServiceRef.current.sendMessageToAgent(\n newSession.chat_id,\n newSession.session_id,\n text.trim()\n );\n } catch (retryError: any) {\n if (\n retryError instanceof ChatResolvedError ||\n retryError?.name === \"ChatResolvedError\" ||\n retryError?.message === \"chat_resolved\"\n ) {\n enterResolvedState(newSession.chat_id);\n return;\n }\n throw retryError;\n }\n return; // Success, exit early\n } catch (retryError: any) {\n if (\n retryError instanceof ChatResolvedError ||\n retryError?.name === \"ChatResolvedError\" ||\n retryError?.message === \"chat_resolved\"\n ) {\n enterResolvedState(chatId);\n return;\n }\n // If retry fails, show error\n const errorMessage: Message = {\n id: uid(\"msg\"),\n text: debug\n ? `Error: ${retryError.message || 'Failed to send message.'}`\n : \"Sorry, I'm having trouble sending your message. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n }\n } else {\n const errorMessage: Message = {\n id: uid(\"msg\"),\n text: debug\n ? `Error: ${error.message || 'Failed to send message to agent.'}`\n : \"Sorry, I'm having trouble sending your message. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n }\n } finally {\n setIsLoading(false);\n }\n return;\n }\n\n // Handle BOT mode (Dialogflow)\n // Ensure we have a session\n let currentSessionId = sessionId;\n if (!currentSessionId) {\n try {\n currentSessionId = await createSession();\n if (!currentSessionId) {\n const errorMessage: Message = {\n id: uid(\"msg\"),\n text: debug \n ? \"Failed to create session. Please check the console for details.\"\n : \"Sorry, I'm having trouble connecting. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n return;\n }\n } catch (error: any) {\n console.error(\"Error in createSession:\", error);\n const errorMessage: Message = {\n id: uid(\"msg\"),\n text: debug \n ? `Connection Error: ${error.message || 'Please check your Dialogflow configuration.'}`\n : \"Sorry, I'm having trouble connecting. Please check your configuration.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n return;\n }\n }\n\n // Add user message unless skipped (e.g., when chip button already added it)\n if (!skipUserMessage) {\n const userMessage: Message = {\n id: uid(\"msg\"),\n text: displayText || text.trim(),\n sender: \"user\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, userMessage]);\n }\n \n setInputValue(\"\");\n setIsLoading(true);\n\n try {\n const dfConfig = getDialogflowConfig();\n if (!dfConfig) {\n throw new Error('Dialogflow configuration is missing. Please provide dfProjectId and dfAgentId.');\n }\n \n const data = await sendDialogflowMessage(text.trim(), currentSessionId, dfConfig);\n\n if (debug) {\n console.log('Chat response richContent:', data.richContent);\n console.log('Full chat response:', data);\n console.log('Handoff detected:', data.handoff);\n }\n \n // Check for handoff\n if (data.handoff === true) {\n // Add bot response first only if there is actual text or rich content\n if (data.response || data.richContent) {\n const botMessage: Message = {\n id: uid(\"msg\"),\n text: data.response,\n sender: \"bot\",\n timestamp: new Date(data.timestamp || Date.now()),\n richContent: data.richContent,\n };\n setMessages((prev) => [...prev, botMessage]);\n }\n\n // Proceed directly with handoff — pass chat_id/session_id created by the webhook\n await handleHandoff(data.chat_id, data.support_session_id);\n return;\n }\n \n // Only add a bot message if the backend returned actual text or rich content\n if (data.response || data.richContent) {\n const botMessage: Message = {\n id: uid(\"msg\"),\n text: data.response,\n sender: \"bot\",\n timestamp: new Date(data.timestamp || Date.now()),\n richContent: data.richContent,\n };\n setMessages((prev) => [...prev, botMessage]);\n }\n } catch (error: any) {\n console.error(\"Error sending message:\", error);\n if (debug) {\n console.error(\"Full error details:\", {\n message: error.message,\n stack: error.stack,\n sessionId: currentSessionId,\n config: getDialogflowConfig(),\n });\n }\n const errorMessage: Message = {\n id: uid(\"msg\"),\n text: debug\n ? `Error: ${error.message || 'Failed to send message. Please check your Dialogflow configuration.'}`\n : error.message?.includes(\"Failed to fetch\") || error.message?.includes(\"CORS\")\n ? \"Unable to connect to Dialogflow. Please check your configuration and network.\"\n : \"Sorry, I'm having trouble processing your message. Please try again.\",\n sender: \"bot\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, errorMessage]);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n sendMessage(inputValue);\n };\n\n // Handle input change - send typing indicators (only in HUMAN mode)\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value;\n setInputValue(value);\n\n // Only send typing indicators in HUMAN mode with WebSocket connected\n if (currentMode === \"HUMAN\" && wsConnected) {\n // Send typing_start\n chatServiceRef.current.sendTypingIndicator(\"typing_start\");\n\n // Clear existing timeout\n if (typingTimeoutRef.current) {\n clearTimeout(typingTimeoutRef.current);\n }\n\n // Send typing_stop after 2 seconds of inactivity\n typingTimeoutRef.current = setTimeout(() => {\n chatServiceRef.current.sendTypingIndicator(\"typing_stop\");\n typingTimeoutRef.current = null;\n }, 2000);\n }\n };\n\n // Cleanup typing timeouts on unmount\n useEffect(() => {\n return () => {\n if (typingTimeoutRef.current) {\n clearTimeout(typingTimeoutRef.current);\n }\n if (agentTypingTimeoutRef.current) {\n clearTimeout(agentTypingTimeoutRef.current);\n }\n };\n }, []);\n\n const openChat = async () => {\n setIsOpen(true);\n setShowWelcomePopup(false);\n\n // Create session when chat opens if it doesn't exist\n if (!sessionId) {\n await createSession();\n }\n // Note: Dialogflow maintains conversation history internally through the session\n };\n\n const closeChat = () => {\n setIsOpen(false);\n // Disconnect WebSocket when closing chat\n if (currentMode === \"HUMAN\") {\n chatServiceRef.current.disconnectWebSocket();\n }\n };\n\n // Check if message is a handoff message\n const isHandoffMessage = (text: string): boolean => {\n return (\n text.includes(\"👤\") ||\n text.includes(\"being connected\") ||\n text.includes(\"live support agent\") ||\n text.includes(\"transfer your conversation\") ||\n text.includes(\"✅\") ||\n text.includes(\"🔄\")\n );\n };\n\n // Cleanup WebSocket on unmount\n useEffect(() => {\n return () => {\n chatServiceRef.current.disconnectWebSocket();\n };\n }, []);\n\n return (\n <>\n {/* Welcome Popup */}\n {showWelcomePopup && !isOpen && (\n <div className=\"custom-welcome-popup\" onClick={openChat}>\n <div className=\"custom-welcome-header\">\n <div className=\"custom-welcome-title\">{welcomeTitle}</div>\n <button\n className=\"custom-close-popup\"\n onClick={(e) => {\n e.stopPropagation();\n setShowWelcomePopup(false);\n }}\n >\n ×\n </button>\n </div>\n <div className=\"custom-welcome-message\">\n {welcomeMessage}\n </div>\n <div className=\"custom-welcome-cta\">{welcomeCta}</div>\n </div>\n )}\n\n {/* Chat Toggle Button */}\n {!isOpen && (\n <button\n className=\"custom-chat-toggle-btn\"\n onClick={openChat}\n aria-label=\"Open chat\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\n </svg>\n </button>\n )}\n\n {/* Chat Window */}\n {isOpen && (\n <div className=\"custom-chat-window\">\n <div className=\"custom-chat-header\">\n <div className=\"custom-chat-header-content\">\n <div className=\"custom-chat-title\">{title}</div>\n <div className=\"custom-chat-subtitle\">\n {subtitle}\n {currentMode === \"HUMAN\" && (\n <span className=\"custom-mode-indicator\">\n {\" \"}\n • {wsConnected ? \"🟢 Connected\" : \"🟡 Connecting...\"}\n </span>\n )}\n </div>\n {currentMode === \"HUMAN\" && (\n <>\n <div className=\"custom-mode-badge\">Human Support Mode</div>\n <div className=\"custom-agent-info\">\n <span className=\"custom-agent-label\">Agent:</span>\n <span className=\"custom-agent-name\">{currentAgent.name}</span>\n </div>\n </>\n )}\n {currentMode === \"BOT\" && (\n <div className=\"custom-mode-badge\">Bot Mode</div>\n )}\n </div>\n <button\n className=\"custom-chat-close-btn\"\n onClick={closeChat}\n aria-label=\"Close chat\"\n >\n ×\n </button>\n </div>\n\n <div className=\"custom-chat-messages\">\n {isInitializing && messages.length === 0 && (\n <div className=\"custom-chat-empty\">\n <div className=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n <p>Initializing chat...</p>\n </div>\n )}\n {!isInitializing && messages.length === 0 && (\n <div className=\"custom-chat-empty\">\n <div className=\"custom-chat-empty-icon\">👋</div>\n <p>{emptyStateMessage}</p>\n </div>\n )}\n {messages.map((message) => (\n <div\n key={message.id}\n className={`custom-message custom-message-${message.sender} ${\n isHandoffMessage(message.text) ? \"custom-handoff-message\" : \"\"\n }`}\n >\n <div \n className={`custom-message-content ${\n isHandoffMessage(message.text) ? \"custom-handoff-content\" : \"\"\n }`}\n dangerouslySetInnerHTML={{ \n __html: linkifyText(message.text).replace(/\\n/g, \"<br>\") \n }}\n />\n {(() => {\n // Debug: Log rich content structure\n if (debug && message.richContent) {\n console.log('Rendering message with richContent:', message.richContent);\n console.log('richContent type:', typeof message.richContent);\n console.log('richContent is array:', Array.isArray(message.richContent));\n console.log('richContent length:', message.richContent?.length);\n }\n \n // Check if richContent exists and has data\n if (message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0) {\n return (\n <div className=\"custom-chips-container\">\n {message.richContent.map((contentGroup, groupIndex) => {\n if (debug) {\n console.log(`Processing contentGroup ${groupIndex}:`, contentGroup);\n }\n if (!Array.isArray(contentGroup)) {\n // Handle case where contentGroup is not an array (single RichContent object)\n const content = contentGroup as RichContent;\n if (content && content.type === \"chips\" && content.options) {\n return (\n <div key={groupIndex} className=\"custom-chips-group\">\n {content.options.map((chip: ChipOption, chipIndex: number) => (\n <button\n key={chipIndex}\n className=\"custom-chip-button\"\n onClick={() => {\n const userMessage: Message = {\n id: uid(\"msg\"),\n text: chip.text,\n sender: \"user\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, userMessage]);\n // Send the chip text instead of payload for better intent matching\n // Dialogflow will match the text to the intent\n sendMessage(chip.text, chip.text, true);\n }}\n type=\"button\"\n >\n {chip.text}\n </button>\n ))}\n </div>\n );\n }\n return null;\n }\n return contentGroup.map((content: RichContent, contentIndex: number) => {\n if (debug) {\n console.log(`Processing content ${groupIndex}-${contentIndex}:`, content);\n }\n if (content && content.type === \"chips\" && content.options) {\n return (\n <div key={`${groupIndex}-${contentIndex}`} className=\"custom-chips-group\">\n {content.options.map((chip: ChipOption, chipIndex: number) => (\n <button\n key={chipIndex}\n className=\"custom-chip-button\"\n onClick={() => {\n const userMessage: Message = {\n id: uid(\"msg\"),\n text: chip.text,\n sender: \"user\",\n timestamp: new Date(),\n };\n setMessages((prev) => [...prev, userMessage]);\n // Send the chip text instead of payload for better intent matching\n sendMessage(chip.text, chip.text, true);\n }}\n type=\"button\"\n >\n {chip.text}\n </button>\n ))}\n </div>\n );\n }\n return null;\n });\n })}\n </div>\n );\n }\n return null;\n })()}\n <div className=\"custom-message-time\">\n {message.timestamp.toLocaleTimeString([], {\n hour: \"2-digit\",\n minute: \"2-digit\",\n })}\n </div>\n </div>\n ))}\n {isLoading && (\n <div className=\"custom-message custom-message-bot\">\n <div className=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n )}\n {isConnectingToAgent && (\n <div className=\"custom-message custom-message-bot\">\n <div className=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n )}\n {currentMode === \"HUMAN\" && agentTyping && (\n <div className=\"custom-message custom-message-bot\">\n <div className=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form className=\"custom-chat-input-form\" onSubmit={handleSubmit}>\n <input\n type=\"text\"\n className=\"custom-chat-input\"\n value={inputValue}\n onChange={handleInputChange}\n placeholder={inputPlaceholder}\n disabled={isLoading || isInitializing || isStartingNewChat}\n />\n <button\n type=\"submit\"\n className=\"custom-chat-send-btn\"\n disabled={!inputValue.trim() || isLoading || isInitializing || isStartingNewChat}\n >\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </form>\n </div>\n )}\n </>\n );\n} ","/**\n * Framework Detection Utility\n * Detects which framework is available in the runtime environment\n */\n\nexport type Framework = 'react' | 'vue' | 'next' | 'nuxt' | 'vite' | 'vanilla';\n\nexport interface FrameworkInfo {\n name: Framework;\n version?: string;\n isSSR: boolean;\n}\n\n/**\n * Detects the framework in the current environment\n */\nexport function detectFramework(): FrameworkInfo {\n const isSSR = typeof window === 'undefined';\n \n // Check for Next.js\n // Use safe property access to avoid bundling process.env\n if (typeof process !== 'undefined' && typeof (process as any).env !== 'undefined') {\n const env = (process as any).env;\n if (env?.NEXT_RUNTIME) {\n return {\n name: 'next',\n version: env.NEXT_VERSION,\n isSSR,\n };\n }\n }\n \n // Check for Nuxt\n if (typeof process !== 'undefined' && typeof (process as any).env !== 'undefined') {\n const env = (process as any).env;\n if (env?.NUXT || (globalThis as any).__NUXT__) {\n return {\n name: 'nuxt',\n version: env.NUXT_VERSION,\n isSSR,\n };\n }\n }\n \n // Also check for Nuxt via globalThis (SSR-safe)\n if ((globalThis as any).__NUXT__) {\n return {\n name: 'nuxt',\n version: undefined,\n isSSR,\n };\n }\n \n // Check for Vite (development)\n if (typeof import.meta !== 'undefined') {\n const meta = import.meta as any;\n if (meta.env?.DEV) {\n return {\n name: 'vite',\n version: meta.env?.VITE_VERSION,\n isSSR,\n };\n }\n }\n \n // Check for React\n if (detectReact()) {\n return {\n name: 'react',\n version: getReactVersion(),\n isSSR,\n };\n }\n \n // Check for Vue\n if (detectVue()) {\n return {\n name: 'vue',\n version: getVueVersion(),\n isSSR,\n };\n }\n \n // Default to vanilla\n return {\n name: 'vanilla',\n isSSR,\n };\n}\n\n/**\n * Detects if React is available\n */\nfunction detectReact(): boolean {\n // Check global React\n if (typeof window !== 'undefined') {\n if ((window as any).React || (window as any).react) {\n return true;\n }\n }\n \n // Note: Removed module.hot check as it's Node-specific and not available in browser ESM\n \n // For ESM environments, we can't use require.resolve\n // Instead, we check for common React indicators\n if (typeof document !== 'undefined') {\n // Check if React DevTools are present (indicates React is loaded)\n if ((window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__) {\n return true;\n }\n }\n \n return false;\n}\n\n/**\n * Gets React version if available\n */\nfunction getReactVersion(): string | undefined {\n try {\n if (typeof window !== 'undefined' && (window as any).React?.version) {\n return (window as any).React.version;\n }\n \n // In ESM environments, we can't use require\n // Try to get version from React DevTools hook if available\n if (typeof window !== 'undefined' && (window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__) {\n const hook = (window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__;\n if (hook.renderers && hook.renderers.size > 0) {\n const renderer = Array.from(hook.renderers.values())[0] as any;\n return renderer.version;\n }\n }\n } catch {\n // Version not available\n }\n \n return undefined;\n}\n\n/**\n * Detects if Vue is available\n */\nfunction detectVue(): boolean {\n // Check global Vue\n if (typeof window !== 'undefined') {\n if ((window as any).Vue || (window as any).vue) {\n return true;\n }\n }\n \n // For ESM environments, we can't use require.resolve\n // Check for Vue DevTools or other indicators\n if (typeof window !== 'undefined') {\n // Check if Vue DevTools are present\n if ((window as any).__VUE_DEVTOOLS_GLOBAL_HOOK__) {\n return true;\n }\n }\n \n return false;\n}\n\n/**\n * Gets Vue version if available\n */\nfunction getVueVersion(): string | undefined {\n try {\n if (typeof window !== 'undefined' && (window as any).Vue?.version) {\n return (window as any).Vue.version;\n }\n \n // In ESM environments, we can't use require\n // Try to get version from Vue DevTools hook if available\n if (typeof window !== 'undefined' && (window as any).__VUE_DEVTOOLS_GLOBAL_HOOK__) {\n const hook = (window as any).__VUE_DEVTOOLS_GLOBAL_HOOK__;\n if (hook.apps && hook.apps.length > 0) {\n const app = hook.apps[0];\n return app.version;\n }\n }\n } catch {\n // Version not available\n }\n \n return undefined;\n}\n\n/**\n * Forces a specific framework (useful for testing or explicit configuration)\n */\nlet forcedFramework: Framework | null = null;\n\nexport function setFramework(framework: Framework): void {\n forcedFramework = framework;\n}\n\nexport function getFramework(): FrameworkInfo {\n if (forcedFramework) {\n return {\n name: forcedFramework,\n isSSR: typeof window === 'undefined',\n };\n }\n return detectFramework();\n}\n","'use strict';\n\nvar m = require('react-dom');\nif (process.env.NODE_ENV === 'production') {\n exports.createRoot = m.createRoot;\n exports.hydrateRoot = m.hydrateRoot;\n} else {\n var i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;\n exports.createRoot = function(c, o) {\n i.usingClientEntryPoint = true;\n try {\n return m.createRoot(c, o);\n } finally {\n i.usingClientEntryPoint = false;\n }\n };\n exports.hydrateRoot = function(c, h, o) {\n i.usingClientEntryPoint = true;\n try {\n return m.hydrateRoot(c, h, o);\n } finally {\n i.usingClientEntryPoint = false;\n }\n };\n}\n","/**\n * Vanilla JavaScript Entry Point\n * Uses the original ChatWidget.tsx component via ReactDOM\n * Reuses the same component to reduce code duplication\n */\n\nimport React from 'react';\nimport { createRoot, Root } from 'react-dom/client';\nimport ChatWidgetComponent from '../components/ChatWidget';\nimport type { ChatWidgetProps } from '../components/ChatWidget';\nimport '../styles/chatWidget.css';\n\n/**\n * Vanilla JS Chat Widget\n * Renders the original React component using ReactDOM\n * This reuses the same component code, reducing duplication\n */\nexport class ChatWidget {\n private container: HTMLElement;\n private config: ChatWidgetProps;\n private root: Root | null = null;\n\n constructor(container: HTMLElement | string, config: ChatWidgetProps) {\n this.config = config;\n \n // Get container element\n if (typeof container === 'string') {\n const element = document.querySelector(container);\n if (!element) {\n throw new Error(`Container element \"${container}\" not found`);\n }\n this.container = element as HTMLElement;\n } else {\n this.container = container;\n }\n\n // Create React root and render the component\n // This reuses the same ChatWidget.tsx component\n this.root = createRoot(this.container);\n this.render();\n }\n\n private render(): void {\n // Render the original React component using ReactDOM\n // This reuses the same component code, reducing duplication\n if (this.root) {\n this.root.render(React.createElement(ChatWidgetComponent, this.config));\n }\n }\n\n /**\n * Update configuration\n */\n updateConfig(config: Partial<ChatWidgetProps>): void {\n this.config = { ...this.config, ...config };\n this.render();\n }\n\n /**\n * Destroy the widget\n */\n destroy(): void {\n if (this.root) {\n this.root.unmount();\n this.root = null;\n }\n }\n}\n\n/**\n * Factory function for easier usage\n */\nexport function createChatWidget(\n container: HTMLElement | string,\n config: ChatWidgetProps\n): ChatWidget {\n return new ChatWidget(container, config);\n}\n\nexport default ChatWidget;\n"],"names":["ChatWidget","m","welcomeMessage","ChatWidgetComponent"],"mappings":"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","x_google_ignoreList":[3]}
|
package/dist/nuxt.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./ChatWidget-
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./ChatWidget-CkiqiScx.cjs");exports.ChatWidget=e.ChatWidgetComponent,exports.WidgetStateManager=e.WidgetStateManager,exports.default=e.ChatWidgetComponent,exports.useChatWidget=e.useChatWidget;
|
|
2
2
|
//# sourceMappingURL=nuxt.cjs.js.map
|
package/dist/nuxt.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as ChatWidgetComponent } from "./ChatWidget-
|
|
2
|
-
import { W, u } from "./ChatWidget-
|
|
1
|
+
import { C as ChatWidgetComponent } from "./ChatWidget-CsEN9biV.js";
|
|
2
|
+
import { W, u } from "./ChatWidget-CsEN9biV.js";
|
|
3
3
|
export {
|
|
4
4
|
ChatWidgetComponent as ChatWidget,
|
|
5
5
|
W as WidgetStateManager,
|
package/dist/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.custom-chat-widget,.custom-welcome-popup,.custom-chat-window,.custom-chat-toggle-btn{font-family:Segoe UI,-apple-system,BlinkMacSystemFont,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.custom-welcome-popup{position:fixed;bottom:20px;right:90px;background:linear-gradient(135deg,#2e1e53 0% 100%);color:#fff;padding:20px;border-radius:12px;box-shadow:0 8px 24px #00000026;max-width:350px;z-index:99998;animation:customSlideIn .4s ease-out;cursor:pointer;transition:transform .2s}.custom-welcome-popup:hover{transform:translateY(-2px);box-shadow:0 10px 28px #0003}@keyframes customSlideIn{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}.custom-welcome-header{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:12px}.custom-welcome-title{display:flex;align-items:center;gap:8px;font-size:16px;font-weight:600;font-family:Segoe UI,-apple-system,BlinkMacSystemFont,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.custom-close-popup{background:none;border:none;color:#fff;font-size:24px;cursor:pointer;padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;opacity:.8;transition:opacity .2s}.custom-close-popup:hover{opacity:1}.custom-welcome-message{font-size:14px;line-height:1.5;margin-bottom:10px}.custom-welcome-cta{font-size:13px;opacity:.9;font-style:italic}.custom-chat-toggle-btn{position:fixed;bottom:20px;right:20px;width:60px;height:60px;border-radius:50%;background:linear-gradient(135deg,#2e1e53 0% 100%);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 12px #00000026;z-index:99999;transition:transform .2s,box-shadow .2s}.custom-chat-toggle-btn:hover{transform:scale(1.1);box-shadow:0 6px 16px #0003}.custom-chat-toggle-btn:active{transform:scale(.95)}.custom-chat-window{position:fixed;bottom:20px;right:20px;width:380px;height:600px;max-height:calc(100vh - 40px);background:#fff;border-radius:16px;box-shadow:0 8px 32px #0003;display:flex;flex-direction:column;z-index:99999;animation:customChatSlideUp .3s ease-out;overflow:hidden}@keyframes customChatSlideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}.custom-chat-header{background:#2e1e53;color:#fff;padding:20px;display:flex;justify-content:space-between;align-items:flex-start;flex-shrink:0}.custom-chat-header-content{flex:1}.custom-chat-title{font-size:18px;font-weight:600;margin-bottom:4px}.custom-chat-subtitle{font-size:12px;opacity:.9}.custom-mode-indicator{font-size:11px;margin-left:4px;opacity:.85}.custom-mode-badge{font-size:10px;margin-top:6px;padding:4px 8px;background:#ffffff26;border-radius:12px;display:inline-block;font-weight:500;letter-spacing:.5px}.custom-agent-info{font-size:11px;margin-top:4px;opacity:.9;display:flex;align-items:center;gap:4px}.custom-agent-label{opacity:.8}.custom-agent-name{font-weight:500}.custom-chat-close-btn{background:none;border:none;color:#fff;font-size:28px;cursor:pointer;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;opacity:.8;transition:opacity .2s;line-height:1;border-radius:50%}.custom-chat-close-btn:hover{opacity:1;background:#ffffff1a}.custom-chat-messages{flex:1;overflow-y:auto;padding:20px;display:flex;flex-direction:column;gap:12px;background:#f8f9fa}.custom-chat-messages::-webkit-scrollbar{width:6px}.custom-chat-messages::-webkit-scrollbar-track{background:transparent}.custom-chat-messages::-webkit-scrollbar-thumb{background:#ddd;border-radius:3px}.custom-chat-messages::-webkit-scrollbar-thumb:hover{background:#bbb}.custom-chat-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;text-align:center;color:#666}.custom-chat-empty-icon{font-size:48px;margin-bottom:12px}.custom-chat-empty p{font-size:16px;line-height:1.5}.custom-message{display:flex;flex-direction:column;max-width:75%;animation:customMessageFadeIn .3s ease-out}@keyframes customMessageFadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.custom-message-user{align-self:flex-end}.custom-message-bot,.custom-message-agent{align-self:flex-start}.custom-message-content{padding:12px 16px;border-radius:16px;word-wrap:break-word;line-height:1.5;font-size:14px}.custom-message-user .custom-message-content{background:#2e1e53;color:#fff;border-bottom-right-radius:4px}.custom-message-bot .custom-message-content,.custom-message-agent .custom-message-content{background:#fff;color:#333;border-bottom-left-radius:4px;box-shadow:0 2px 4px #0000001a}.custom-message-time{font-size:10px;color:#999;margin-top:4px;padding:0 4px}.custom-chips-container{margin-top:12px;display:flex;flex-direction:column;gap:8px}.custom-chips-group{display:flex;flex-wrap:wrap;gap:8px}.custom-chip-button{background:#fff;border:1.5px solid #2e1e53;color:#2e1e53;padding:8px 16px;border-radius:20px;font-size:13px;font-weight:500;cursor:pointer;transition:all .2s ease;white-space:
|
|
1
|
+
.custom-chat-widget,.custom-welcome-popup,.custom-chat-window,.custom-chat-toggle-btn{font-family:Segoe UI,-apple-system,BlinkMacSystemFont,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.custom-welcome-popup{position:fixed;bottom:20px;right:90px;background:linear-gradient(135deg,#2e1e53 0% 100%);color:#fff;padding:20px;border-radius:12px;box-shadow:0 8px 24px #00000026;max-width:350px;z-index:99998;animation:customSlideIn .4s ease-out;cursor:pointer;transition:transform .2s}.custom-welcome-popup:hover{transform:translateY(-2px);box-shadow:0 10px 28px #0003}@keyframes customSlideIn{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}.custom-welcome-header{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:12px}.custom-welcome-title{display:flex;align-items:center;gap:8px;font-size:16px;font-weight:600;font-family:Segoe UI,-apple-system,BlinkMacSystemFont,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.custom-close-popup{background:none;border:none;color:#fff;font-size:24px;cursor:pointer;padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;opacity:.8;transition:opacity .2s}.custom-close-popup:hover{opacity:1}.custom-welcome-message{font-size:14px;line-height:1.5;margin-bottom:10px}.custom-welcome-cta{font-size:13px;opacity:.9;font-style:italic}.custom-chat-toggle-btn{position:fixed;bottom:20px;right:20px;width:60px;height:60px;border-radius:50%;background:linear-gradient(135deg,#2e1e53 0% 100%);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 12px #00000026;z-index:99999;transition:transform .2s,box-shadow .2s}.custom-chat-toggle-btn:hover{transform:scale(1.1);box-shadow:0 6px 16px #0003}.custom-chat-toggle-btn:active{transform:scale(.95)}.custom-chat-window{position:fixed;bottom:20px;right:20px;width:380px;height:600px;max-height:calc(100vh - 40px);background:#fff;border-radius:16px;box-shadow:0 8px 32px #0003;display:flex;flex-direction:column;z-index:99999;animation:customChatSlideUp .3s ease-out;overflow:hidden}@keyframes customChatSlideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}.custom-chat-header{background:#2e1e53;color:#fff;padding:20px;display:flex;justify-content:space-between;align-items:flex-start;flex-shrink:0}.custom-chat-header-content{flex:1}.custom-chat-title{font-size:18px;font-weight:600;margin-bottom:4px}.custom-chat-subtitle{font-size:12px;opacity:.9}.custom-mode-indicator{font-size:11px;margin-left:4px;opacity:.85}.custom-mode-badge{font-size:10px;margin-top:6px;padding:4px 8px;background:#ffffff26;border-radius:12px;display:inline-block;font-weight:500;letter-spacing:.5px}.custom-agent-info{font-size:11px;margin-top:4px;opacity:.9;display:flex;align-items:center;gap:4px}.custom-agent-label{opacity:.8}.custom-agent-name{font-weight:500}.custom-chat-close-btn{background:none;border:none;color:#fff;font-size:28px;cursor:pointer;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;opacity:.8;transition:opacity .2s;line-height:1;border-radius:50%}.custom-chat-close-btn:hover{opacity:1;background:#ffffff1a}.custom-chat-messages{flex:1;overflow-y:auto;padding:20px;display:flex;flex-direction:column;gap:12px;background:#f8f9fa}.custom-chat-messages::-webkit-scrollbar{width:6px}.custom-chat-messages::-webkit-scrollbar-track{background:transparent}.custom-chat-messages::-webkit-scrollbar-thumb{background:#ddd;border-radius:3px}.custom-chat-messages::-webkit-scrollbar-thumb:hover{background:#bbb}.custom-chat-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;text-align:center;color:#666}.custom-chat-empty-icon{font-size:48px;margin-bottom:12px}.custom-chat-empty p{font-size:16px;line-height:1.5}.custom-message{display:flex;flex-direction:column;max-width:75%;animation:customMessageFadeIn .3s ease-out}@keyframes customMessageFadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.custom-message-user{align-self:flex-end}.custom-message-bot,.custom-message-agent{align-self:flex-start}.custom-message-content{padding:12px 16px;border-radius:16px;word-wrap:break-word;line-height:1.5;font-size:14px}.custom-message-user .custom-message-content{background:#2e1e53;color:#fff;border-bottom-right-radius:4px}.custom-message-bot .custom-message-content,.custom-message-agent .custom-message-content{background:#fff;color:#333;border-bottom-left-radius:4px;box-shadow:0 2px 4px #0000001a}.custom-message-time{font-size:10px;color:#999;margin-top:4px;padding:0 4px}.custom-chips-container{margin-top:12px;display:flex;flex-direction:column;gap:8px}.custom-chips-group{display:flex;flex-wrap:wrap;gap:8px}.custom-chip-button{background:#fff;border:1.5px solid #2e1e53;color:#2e1e53;padding:8px 16px;border-radius:20px;font-size:13px;font-weight:500;cursor:pointer;transition:all .2s ease;white-space:normal;word-break:break-word;max-width:100%;text-align:left;box-shadow:0 1px 3px #0000001a}.custom-chip-button:hover{background:linear-gradient(135deg,#2e1e53 0% 100%);color:#fff;transform:translateY(-1px);box-shadow:0 2px 6px #2d7a4f4d}.custom-chip-button:active{transform:translateY(0);box-shadow:0 1px 3px #0000001a}.custom-typing-indicator{display:flex;gap:4px;padding:12px 16px;background:#fff;border-radius:16px 16px 16px 4px;box-shadow:0 2px 4px #0000001a;width:fit-content}.custom-typing-indicator span{width:8px;height:8px;border-radius:50%;background:#999;animation:customTypingBounce 1.4s infinite ease-in-out}.custom-typing-indicator span:nth-child(1){animation-delay:-.32s}.custom-typing-indicator span:nth-child(2){animation-delay:-.16s}@keyframes customTypingBounce{0%,80%,to{transform:scale(.8);opacity:.5}40%{transform:scale(1);opacity:1}}.custom-agent-typing-indicator{display:flex;align-items:center;gap:8px;padding:8px 16px;margin:4px 0;color:#666;font-size:14px;font-style:italic}.custom-typing-dots{display:inline-flex;gap:2px}.custom-typing-dots span{display:inline-block;width:4px;height:4px;border-radius:50%;background-color:#666;animation:customTypingBounce 1.4s infinite ease-in-out}.custom-typing-dots span:nth-child(2){animation-delay:-.16s}.custom-typing-dots span:nth-child(3){animation-delay:-.32s}.custom-typing-text{color:#666}.custom-chat-input-form{display:flex;padding:16px;background:#fff;border-top:1px solid #e0e0e0;gap:8px;flex-shrink:0}.custom-chat-resolved-banner{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 16px;border-top:1px solid #e0e0e0;background:#f6f8ff;color:#1f2a44;flex-shrink:0}.custom-chat-resolved-text{flex:1;font-size:13px;line-height:1.35}.custom-chat-resolved-btn{background:#2e1e53;color:#fff;border:none;border-radius:10px;padding:10px 12px;font-size:12px;font-weight:600;cursor:pointer;transition:transform .15s,opacity .15s;flex-shrink:0}.custom-chat-resolved-btn:hover:not(:disabled){transform:scale(1.02)}.custom-chat-resolved-btn:disabled{opacity:.6;cursor:not-allowed}.custom-chat-input{flex:1;padding:12px 16px;border:1px solid #e0e0e0;border-radius:24px;outline:none;font-size:14px;transition:border-color .2s;font-family:inherit}.custom-chat-input:focus{border-color:#2e1e53}.custom-chat-input:disabled{background:#f5f5f5;cursor:not-allowed}.custom-chat-send-btn{width:44px;height:44px;border-radius:50%;background:#2e1e53;color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform .2s,opacity .2s;flex-shrink:0}.custom-chat-send-btn:hover:not(:disabled){transform:scale(1.05)}.custom-chat-send-btn:active:not(:disabled){transform:scale(.95)}.custom-chat-send-btn:disabled{opacity:.5;cursor:not-allowed}@media (max-width: 480px){.custom-welcome-popup{right:10px;left:10px;bottom:90px;max-width:none}.custom-chat-window{width:calc(100vw - 20px);height:calc(100vh - 20px);bottom:10px;right:10px;border-radius:12px}.custom-chat-toggle-btn{bottom:10px;right:10px;width:56px;height:56px}.custom-message{max-width:85%}}
|
package/dist/vue.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./ChatWidget-
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./ChatWidget-CkiqiScx.cjs");exports.ChatWidget=e.ChatWidgetComponent,exports.WidgetStateManager=e.WidgetStateManager,exports.default=e.ChatWidgetComponent,exports.useChatWidget=e.useChatWidget;
|
|
2
2
|
//# sourceMappingURL=vue.cjs.js.map
|
package/dist/vue.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as ChatWidgetComponent } from "./ChatWidget-
|
|
2
|
-
import { W, u } from "./ChatWidget-
|
|
1
|
+
import { C as ChatWidgetComponent } from "./ChatWidget-CsEN9biV.js";
|
|
2
|
+
import { W, u } from "./ChatWidget-CsEN9biV.js";
|
|
3
3
|
export {
|
|
4
4
|
ChatWidgetComponent as ChatWidget,
|
|
5
5
|
W as WidgetStateManager,
|
package/package.json
CHANGED