@theonexai/chartsconnect-chat-widget 1.0.49 → 1.0.50
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-D3LK85TL.js → ChatWidget-BYXJ0hwt.js} +45 -42
- package/dist/{ChatWidget-D3LK85TL.js.map → ChatWidget-BYXJ0hwt.js.map} +1 -1
- package/dist/{ChatWidget-17GeGDTN.cjs → ChatWidget-DVme0jD5.cjs} +2 -2
- package/dist/{ChatWidget-17GeGDTN.cjs.map → ChatWidget-DVme0jD5.cjs.map} +1 -1
- package/dist/components/ChatWidget.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 +11 -9
- 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
|
@@ -877,58 +877,59 @@ const _hoisted_5 = {
|
|
|
877
877
|
const _hoisted_6 = { class: "custom-chat-header" };
|
|
878
878
|
const _hoisted_7 = { class: "custom-chat-header-content" };
|
|
879
879
|
const _hoisted_8 = { class: "custom-chat-title" };
|
|
880
|
-
const _hoisted_9 = {
|
|
880
|
+
const _hoisted_9 = { class: "custom-mode-row" };
|
|
881
|
+
const _hoisted_10 = {
|
|
881
882
|
key: 0,
|
|
882
883
|
class: "custom-mode-badge"
|
|
883
884
|
};
|
|
884
|
-
const
|
|
885
|
+
const _hoisted_11 = {
|
|
885
886
|
key: 1,
|
|
886
887
|
class: "custom-mode-badge"
|
|
887
888
|
};
|
|
888
|
-
const
|
|
889
|
+
const _hoisted_12 = {
|
|
889
890
|
key: 2,
|
|
890
891
|
class: "custom-agent-info"
|
|
891
892
|
};
|
|
892
|
-
const
|
|
893
|
-
const
|
|
894
|
-
const
|
|
893
|
+
const _hoisted_13 = { class: "custom-agent-name" };
|
|
894
|
+
const _hoisted_14 = { class: "custom-mode-indicator" };
|
|
895
|
+
const _hoisted_15 = {
|
|
895
896
|
key: 0,
|
|
896
897
|
class: "custom-chat-empty"
|
|
897
898
|
};
|
|
898
|
-
const
|
|
899
|
+
const _hoisted_16 = {
|
|
899
900
|
key: 1,
|
|
900
901
|
class: "custom-chat-empty"
|
|
901
902
|
};
|
|
902
|
-
const
|
|
903
|
-
const
|
|
903
|
+
const _hoisted_17 = ["innerHTML"];
|
|
904
|
+
const _hoisted_18 = {
|
|
904
905
|
key: 0,
|
|
905
906
|
class: "custom-chips-container"
|
|
906
907
|
};
|
|
907
|
-
const
|
|
908
|
+
const _hoisted_19 = {
|
|
908
909
|
key: 0,
|
|
909
910
|
class: "custom-chips-group"
|
|
910
911
|
};
|
|
911
|
-
const
|
|
912
|
-
const
|
|
912
|
+
const _hoisted_20 = ["onClick"];
|
|
913
|
+
const _hoisted_21 = {
|
|
913
914
|
key: 0,
|
|
914
915
|
class: "custom-chips-group"
|
|
915
916
|
};
|
|
916
|
-
const
|
|
917
|
-
const
|
|
918
|
-
const
|
|
917
|
+
const _hoisted_22 = ["onClick"];
|
|
918
|
+
const _hoisted_23 = { class: "custom-message-time" };
|
|
919
|
+
const _hoisted_24 = {
|
|
919
920
|
key: 2,
|
|
920
921
|
class: "custom-message custom-message-bot"
|
|
921
922
|
};
|
|
922
|
-
const
|
|
923
|
+
const _hoisted_25 = {
|
|
923
924
|
key: 3,
|
|
924
925
|
class: "custom-message custom-message-bot"
|
|
925
926
|
};
|
|
926
|
-
const
|
|
927
|
+
const _hoisted_26 = {
|
|
927
928
|
key: 4,
|
|
928
929
|
class: "custom-message custom-message-bot"
|
|
929
930
|
};
|
|
930
|
-
const
|
|
931
|
-
const
|
|
931
|
+
const _hoisted_27 = ["value", "placeholder", "disabled"];
|
|
932
|
+
const _hoisted_28 = ["disabled"];
|
|
932
933
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
933
934
|
...{
|
|
934
935
|
inheritAttrs: false
|
|
@@ -1077,13 +1078,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1077
1078
|
createElementVNode("div", _hoisted_6, [
|
|
1078
1079
|
createElementVNode("div", _hoisted_7, [
|
|
1079
1080
|
createElementVNode("div", _hoisted_8, toDisplayString(config.value.title), 1),
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1081
|
+
createElementVNode("div", _hoisted_9, [
|
|
1082
|
+
unref(state).chatMode === "human" ? (openBlock(), createElementBlock("div", _hoisted_10, " Human Support Mode ")) : createCommentVNode("", true),
|
|
1083
|
+
unref(state).chatMode === "ai" ? (openBlock(), createElementBlock("div", _hoisted_11, " AI Assistant ")) : createCommentVNode("", true),
|
|
1084
|
+
unref(state).chatMode === "human" ? (openBlock(), createElementBlock("div", _hoisted_12, [
|
|
1085
|
+
_cache[1] || (_cache[1] = createElementVNode("span", { class: "custom-agent-label" }, "Agent:", -1)),
|
|
1086
|
+
createElementVNode("span", _hoisted_13, toDisplayString(unref(currentAgent).name), 1),
|
|
1087
|
+
createElementVNode("span", _hoisted_14, " • " + toDisplayString(unref(wsConnected) ? "🟢 Connected" : "🟡 Connecting..."), 1)
|
|
1088
|
+
])) : createCommentVNode("", true)
|
|
1089
|
+
])
|
|
1087
1090
|
]),
|
|
1088
1091
|
createElementVNode("button", {
|
|
1089
1092
|
class: "custom-chat-close-btn",
|
|
@@ -1096,14 +1099,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1096
1099
|
ref_key: "messagesContainer",
|
|
1097
1100
|
ref: messagesContainer
|
|
1098
1101
|
}, [
|
|
1099
|
-
isInitializing.value && unref(state).messages.length === 0 ? (openBlock(), createElementBlock("div",
|
|
1102
|
+
isInitializing.value && unref(state).messages.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_15, [..._cache[2] || (_cache[2] = [
|
|
1100
1103
|
createElementVNode("div", { class: "custom-typing-indicator" }, [
|
|
1101
1104
|
createElementVNode("span"),
|
|
1102
1105
|
createElementVNode("span"),
|
|
1103
1106
|
createElementVNode("span")
|
|
1104
1107
|
], -1),
|
|
1105
1108
|
createElementVNode("p", null, "Initializing chat...", -1)
|
|
1106
|
-
])])) : !isInitializing.value && unref(state).messages.length === 0 ? (openBlock(), createElementBlock("div",
|
|
1109
|
+
])])) : !isInitializing.value && unref(state).messages.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_16, [
|
|
1107
1110
|
_cache[3] || (_cache[3] = createElementVNode("div", { class: "custom-chat-empty-icon" }, "👋", -1)),
|
|
1108
1111
|
createElementVNode("p", null, toDisplayString(config.value.emptyStateMessage), 1)
|
|
1109
1112
|
])) : createCommentVNode("", true),
|
|
@@ -1119,33 +1122,33 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1119
1122
|
createElementVNode("div", {
|
|
1120
1123
|
class: normalizeClass(["custom-message-content", { "custom-handoff-content": isHandoffMessage(message.text) }]),
|
|
1121
1124
|
innerHTML: unref(renderMarkdown)(message.text)
|
|
1122
|
-
}, null, 10,
|
|
1123
|
-
message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0 ? (openBlock(), createElementBlock("div",
|
|
1125
|
+
}, null, 10, _hoisted_17),
|
|
1126
|
+
message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_18, [
|
|
1124
1127
|
(openBlock(true), createElementBlock(Fragment, null, renderList(message.richContent, (contentGroup, groupIndex) => {
|
|
1125
1128
|
return openBlock(), createElementBlock(Fragment, { key: groupIndex }, [
|
|
1126
1129
|
!Array.isArray(contentGroup) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
|
|
1127
|
-
contentGroup.type === "chips" && contentGroup.options ? (openBlock(), createElementBlock("div",
|
|
1130
|
+
contentGroup.type === "chips" && contentGroup.options ? (openBlock(), createElementBlock("div", _hoisted_19, [
|
|
1128
1131
|
(openBlock(true), createElementBlock(Fragment, null, renderList(contentGroup.options, (chip, chipIndex) => {
|
|
1129
1132
|
return openBlock(), createElementBlock("button", {
|
|
1130
1133
|
key: chipIndex,
|
|
1131
1134
|
class: "custom-chip-button",
|
|
1132
1135
|
type: "button",
|
|
1133
1136
|
onClick: ($event) => handleChipClick(chip.text, chip.payload)
|
|
1134
|
-
}, toDisplayString(chip.text), 9,
|
|
1137
|
+
}, toDisplayString(chip.text), 9, _hoisted_20);
|
|
1135
1138
|
}), 128))
|
|
1136
1139
|
])) : createCommentVNode("", true)
|
|
1137
1140
|
], 64)) : (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(contentGroup, (content, contentIndex) => {
|
|
1138
1141
|
return openBlock(), createElementBlock(Fragment, {
|
|
1139
1142
|
key: `${groupIndex}-${contentIndex}`
|
|
1140
1143
|
}, [
|
|
1141
|
-
content.type === "chips" && content.options ? (openBlock(), createElementBlock("div",
|
|
1144
|
+
content.type === "chips" && content.options ? (openBlock(), createElementBlock("div", _hoisted_21, [
|
|
1142
1145
|
(openBlock(true), createElementBlock(Fragment, null, renderList(content.options, (chip, chipIndex) => {
|
|
1143
1146
|
return openBlock(), createElementBlock("button", {
|
|
1144
1147
|
key: chipIndex,
|
|
1145
1148
|
class: "custom-chip-button",
|
|
1146
1149
|
type: "button",
|
|
1147
1150
|
onClick: ($event) => handleChipClick(chip.text, chip.payload)
|
|
1148
|
-
}, toDisplayString(chip.text), 9,
|
|
1151
|
+
}, toDisplayString(chip.text), 9, _hoisted_22);
|
|
1149
1152
|
}), 128))
|
|
1150
1153
|
])) : createCommentVNode("", true)
|
|
1151
1154
|
], 64);
|
|
@@ -1153,24 +1156,24 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1153
1156
|
], 64);
|
|
1154
1157
|
}), 128))
|
|
1155
1158
|
])) : createCommentVNode("", true),
|
|
1156
|
-
createElementVNode("div",
|
|
1159
|
+
createElementVNode("div", _hoisted_23, toDisplayString(formatTime(message.timestamp)), 1)
|
|
1157
1160
|
], 2);
|
|
1158
1161
|
}), 128)),
|
|
1159
|
-
unref(state).isLoading ? (openBlock(), createElementBlock("div",
|
|
1162
|
+
unref(state).isLoading ? (openBlock(), createElementBlock("div", _hoisted_24, [..._cache[4] || (_cache[4] = [
|
|
1160
1163
|
createElementVNode("div", { class: "custom-typing-indicator" }, [
|
|
1161
1164
|
createElementVNode("span"),
|
|
1162
1165
|
createElementVNode("span"),
|
|
1163
1166
|
createElementVNode("span")
|
|
1164
1167
|
], -1)
|
|
1165
1168
|
])])) : createCommentVNode("", true),
|
|
1166
|
-
unref(isConnectingToAgent) ? (openBlock(), createElementBlock("div",
|
|
1169
|
+
unref(isConnectingToAgent) ? (openBlock(), createElementBlock("div", _hoisted_25, [..._cache[5] || (_cache[5] = [
|
|
1167
1170
|
createElementVNode("div", { class: "custom-typing-indicator" }, [
|
|
1168
1171
|
createElementVNode("span"),
|
|
1169
1172
|
createElementVNode("span"),
|
|
1170
1173
|
createElementVNode("span")
|
|
1171
1174
|
], -1)
|
|
1172
1175
|
])])) : createCommentVNode("", true),
|
|
1173
|
-
unref(state).chatMode === "human" && unref(agentTyping) ? (openBlock(), createElementBlock("div",
|
|
1176
|
+
unref(state).chatMode === "human" && unref(agentTyping) ? (openBlock(), createElementBlock("div", _hoisted_26, [..._cache[6] || (_cache[6] = [
|
|
1174
1177
|
createElementVNode("div", { class: "custom-typing-indicator" }, [
|
|
1175
1178
|
createElementVNode("span"),
|
|
1176
1179
|
createElementVNode("span"),
|
|
@@ -1195,7 +1198,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1195
1198
|
onInput: handleInput,
|
|
1196
1199
|
placeholder: config.value.inputPlaceholder,
|
|
1197
1200
|
disabled: unref(state).isLoading || isInitializing.value || isStartingNewChat.value
|
|
1198
|
-
}, null, 40,
|
|
1201
|
+
}, null, 40, _hoisted_27),
|
|
1199
1202
|
createElementVNode("button", {
|
|
1200
1203
|
type: "submit",
|
|
1201
1204
|
class: "custom-chat-send-btn",
|
|
@@ -1219,7 +1222,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1219
1222
|
}),
|
|
1220
1223
|
createElementVNode("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
|
|
1221
1224
|
], -1)
|
|
1222
|
-
])], 8,
|
|
1225
|
+
])], 8, _hoisted_28)
|
|
1223
1226
|
], 32)
|
|
1224
1227
|
])) : createCommentVNode("", true)
|
|
1225
1228
|
], 16);
|
|
@@ -1233,10 +1236,10 @@ const _export_sfc = (sfc, props) => {
|
|
|
1233
1236
|
}
|
|
1234
1237
|
return target;
|
|
1235
1238
|
};
|
|
1236
|
-
const ChatWidgetComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
1239
|
+
const ChatWidgetComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-615fa3a7"]]);
|
|
1237
1240
|
export {
|
|
1238
1241
|
ChatWidgetComponent as C,
|
|
1239
1242
|
WidgetStateManager as W,
|
|
1240
1243
|
useChatWidget as u
|
|
1241
1244
|
};
|
|
1242
|
-
//# sourceMappingURL=ChatWidget-
|
|
1245
|
+
//# sourceMappingURL=ChatWidget-BYXJ0hwt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatWidget-D3LK85TL.js","sources":["../src/core/stateManager.ts","../src/composables/useChatWidget.ts","../src/components/ChatWidget.vue"],"sourcesContent":["/**\n * State Manager - Framework Agnostic\n * Manages widget state independently of framework\n */\n\nimport type { WidgetState, WidgetConfig, ChatMessage } from './types';\nimport {\n createDialogflowSession,\n sendDialogflowMessage,\n type DialogflowBackendConfig,\n} from '../services/dialogflowBackendService';\nimport { \n createChatService, \n ChatResolvedError,\n type WebSocketMessage\n} from '../services/chatService';\n\nexport class WidgetStateManager {\n private state: WidgetState;\n private config: WidgetConfig;\n private listeners: Set<(state: WidgetState) => void> = new Set();\n private chatMode: 'ai' | 'human' = 'ai';\n private chatId: string | null = null;\n private supportSessionId: string | null = null;\n private chatService: ReturnType<typeof createChatService> | null = null;\n \n // Additional state for human support\n private wsConnected: boolean = false;\n private agentTyping: boolean = false;\n private currentAgent: { name: string; id?: string } = { name: 'Agent' };\n private isConnectingToAgent: boolean = false;\n private agentAccepted: boolean = false;\n private chatResolved: boolean = false;\n private historyLoaded: string | null = null;\n \n // Typing timeout refs (stored as class properties since we can't use refs)\n private typingTimeout: NodeJS.Timeout | null = null;\n private agentTypingTimeout: NodeJS.Timeout | null = null;\n private handoffTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\n constructor(config: WidgetConfig) {\n this.config = config;\n this.state = {\n isOpen: false,\n showWelcomePopup: false,\n messages: [],\n inputValue: '',\n isLoading: false,\n error: null,\n sessionId: null,\n chatMode: 'ai',\n };\n \n // Initialize ChatService\n this.chatService = createChatService({\n baseUrl: this.config.backendBaseUrl || 'http://localhost:8012',\n wsUrl: this.config.backendWsUrl || 'ws://localhost:8012',\n debug: this.config.debug || false,\n });\n \n // Load chat mode and chat IDs from localStorage if available\n if (typeof window !== 'undefined' && window.localStorage) {\n const savedMode = localStorage.getItem('chartsconnectect_chat_mode');\n this.chatMode = savedMode === 'HUMAN' ? 'human' : 'ai';\n this.state.chatMode = this.chatMode;\n \n this.chatId = localStorage.getItem('chartsconnect_chat_id');\n this.supportSessionId = localStorage.getItem('chartsconnect_session_id');\n }\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(listener: (state: WidgetState) => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n /**\n * Get current state\n */\n getState(): WidgetState {\n return { ...this.state };\n }\n\n /**\n * Update state and notify listeners\n */\n private setState(updates: Partial<WidgetState>): void {\n this.state = { ...this.state, ...updates };\n this.listeners.forEach(listener => listener(this.getState()));\n }\n\n /**\n * Update configuration\n */\n updateConfig(config: Partial<WidgetConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Open chat\n */\n async openChat(): Promise<void> {\n this.setState({ isOpen: true });\n if (this.state.showWelcomePopup) {\n this.setState({ showWelcomePopup: false });\n }\n \n // Initialize Dialogflow session when chat opens (if in AI mode and no session exists)\n if (this.state.chatMode === 'ai' && !this.state.sessionId && this.config.dfProjectId && this.config.dfAgentId) {\n try {\n this.setState({ isLoading: true });\n const dialogflowConfig: DialogflowBackendConfig = {\n dfProjectId: this.config.dfProjectId,\n dfLocation: this.config.dfLocation || 'us-central1',\n dfAgentId: this.config.dfAgentId,\n languageCode: this.config.languageCode || 'en',\n backendBaseUrl: this.config.backendBaseUrl || 'http://localhost:8012',\n };\n \n const session = await createDialogflowSession(dialogflowConfig);\n this.setState({ \n sessionId: session.session_id,\n isLoading: false,\n });\n \n // Add welcome message from Dialogflow if available\n if (session.message) {\n const welcomeMessage: ChatMessage = {\n id: `welcome-${Date.now()}`,\n text: session.message,\n sender: 'bot',\n timestamp: new Date(),\n richContent: session.richContent,\n };\n this.setState({\n messages: [welcomeMessage],\n });\n }\n } catch (error: any) {\n console.error('Error initializing Dialogflow session:', error);\n this.setState({ \n isLoading: false,\n error: error.message || 'Failed to initialize chat',\n });\n \n // Show fallback welcome message\n const fallbackMessage: ChatMessage = {\n id: `fallback-${Date.now()}`,\n text: this.config.fallbackWelcomeMessage || 'Hello! How can I help you today?',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [fallbackMessage],\n });\n }\n }\n }\n\n /**\n * Close chat\n */\n closeChat(): void {\n this.setState({ isOpen: false });\n }\n\n /**\n * Close welcome popup\n */\n closeWelcomePopup(): void {\n this.setState({ showWelcomePopup: false });\n }\n\n /**\n * Toggle chat\n */\n toggleChat(): void {\n const willBeOpen = !this.state.isOpen;\n this.setState({ isOpen: willBeOpen });\n if (willBeOpen && this.state.showWelcomePopup) {\n this.setState({ showWelcomePopup: false });\n }\n }\n\n /**\n * Set input value\n */\n setInputValue(value: string): void {\n this.setState({ inputValue: value });\n }\n\n /**\n * Clear error\n */\n clearError(): void {\n this.setState({ error: null });\n }\n\n /**\n * Send message\n */\n async sendMessage(text: string, skipUserMessage: boolean = false): Promise<void> {\n if (!text.trim() || this.state.isLoading) {\n return;\n }\n\n // Add user message unless skipped (e.g., when chip button already added it)\n if (!skipUserMessage) {\n const userMessage: ChatMessage = {\n id: `user-${Date.now()}`,\n text: text.trim(),\n sender: 'user',\n timestamp: new Date(),\n };\n\n this.setState({\n messages: [...this.state.messages, userMessage],\n inputValue: '',\n isLoading: true,\n error: null,\n });\n } else {\n this.setState({\n inputValue: '',\n isLoading: true,\n error: null,\n });\n }\n\n try {\n if (this.state.chatMode === 'human') {\n // Human support mode\n await this.sendHumanMessage(text);\n } else {\n // AI mode (Dialogflow)\n await this.sendAIMessage(text);\n }\n } catch (error: any) {\n console.error('Error sending message:', error);\n \n // chat_resolved is a normal terminal condition, not an error\n if (error instanceof ChatResolvedError || error?.name === 'ChatResolvedError' || error?.message === 'chat_resolved') {\n this.enterResolvedState(this.chatId);\n return;\n }\n \n // Add error message to chat\n const errorMessage: ChatMessage = {\n id: `error-${Date.now()}`,\n text: this.config.debug \n ? `Error: ${error.message || 'Failed to send message'}`\n : error.message?.includes('CORS') || error.message?.includes('Failed to fetch')\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 \n this.setState({\n messages: [...this.state.messages, errorMessage],\n error: error.message || 'Failed to send message',\n isLoading: false,\n });\n }\n }\n\n /**\n * Send message to Dialogflow\n */\n private async sendAIMessage(text: string): Promise<void> {\n if (!this.config.dfProjectId || !this.config.dfAgentId) {\n throw new Error('Dialogflow configuration is missing');\n }\n\n const dialogflowConfig: DialogflowBackendConfig = {\n dfProjectId: this.config.dfProjectId!,\n dfLocation: this.config.dfLocation || 'us-central1',\n dfAgentId: this.config.dfAgentId!,\n languageCode: this.config.languageCode || 'en',\n backendBaseUrl: this.config.backendBaseUrl || 'http://localhost:8012',\n };\n\n // Create session if needed\n if (!this.state.sessionId) {\n const session = await createDialogflowSession(dialogflowConfig);\n this.setState({ sessionId: session.session_id });\n }\n\n // Send message (correct parameter order: message, sessionId, config)\n if (this.config.debug) {\n console.log('Sending message to Dialogflow:', {\n message: text,\n sessionId: this.state.sessionId,\n hasConfig: !!dialogflowConfig,\n });\n }\n \n const response = await sendDialogflowMessage(\n text,\n this.state.sessionId!,\n dialogflowConfig\n );\n\n if (this.config.debug) {\n console.log('Dialogflow response:', {\n response: response.response,\n hasRichContent: !!response.richContent,\n richContent: response.richContent,\n });\n }\n\n // Check for handoff\n if (response.handoff === true) {\n // Add bot response first\n const botMessage: ChatMessage = {\n id: `bot-${Date.now()}`,\n text: response.response || this.config.fallbackWelcomeMessage || 'No response',\n sender: 'bot',\n timestamp: new Date(),\n richContent: response.richContent,\n };\n this.setState({\n messages: [...this.state.messages, botMessage],\n isLoading: false,\n });\n \n // Proceed directly with handoff — user details collected by Dialogflow via webhook\n await this.handleHandoff();\n return;\n }\n \n const botMessage: ChatMessage = {\n id: `bot-${Date.now()}`,\n text: response.response || this.config.fallbackWelcomeMessage || 'No response',\n sender: 'bot',\n timestamp: new Date(),\n richContent: response.richContent,\n };\n\n this.setState({\n messages: [...this.state.messages, botMessage],\n isLoading: false,\n });\n }\n\n /**\n * Send message to human support\n */\n private async sendHumanMessage(text: string): Promise<void> {\n if (!this.chatId || !this.supportSessionId) {\n const errorMessage: ChatMessage = {\n id: `error-${Date.now()}`,\n text: 'Chat session not initialized. Please try again.',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, errorMessage],\n isLoading: false,\n });\n return;\n }\n\n if (!this.chatService) {\n throw new Error('Chat service not initialized');\n }\n\n // Send typing_stop before sending message\n this.chatService.sendTypingIndicator('typing_stop');\n if (this.typingTimeout) {\n clearTimeout(this.typingTimeout);\n this.typingTimeout = null;\n }\n\n try {\n // Try WebSocket first, fallback to REST API\n const sentViaWs = this.chatService.sendMessageViaWebSocket(text.trim());\n \n if (!sentViaWs) {\n // Fallback to REST API\n await this.chatService.sendMessageToAgent(this.chatId, this.supportSessionId, text.trim());\n }\n \n this.setState({ isLoading: false });\n } catch (error: any) {\n // chat_resolved is a normal terminal condition, not an error\n if (error instanceof ChatResolvedError || error?.name === 'ChatResolvedError' || error?.message === 'chat_resolved') {\n this.enterResolvedState(this.chatId);\n return;\n }\n\n // Handle 401/404 - clear chat_id and reinitialize\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 (this.config.debug) {\n console.log('⚠️ Chat expired. Re-initializing...');\n }\n \n // Clear chat_id\n this.chatId = null;\n this.supportSessionId = null;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.removeItem('chartsconnect_chat_id');\n localStorage.removeItem('chartsconnect_session_id');\n }\n \n // Try to reinitialize chat\n try {\n const newSession = await this.chatService.startSupportChat(\n this.state.sessionId || null\n );\n this.chatId = newSession.chat_id;\n this.supportSessionId = newSession.session_id;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem('chartsconnect_chat_id', this.chatId);\n localStorage.setItem('chartsconnect_session_id', this.supportSessionId);\n }\n \n // Retry sending message\n if (this.chatId && this.supportSessionId) {\n await this.chatService.sendMessageToAgent(\n this.chatId,\n this.supportSessionId,\n text.trim()\n );\n }\n this.setState({ isLoading: false });\n return;\n } catch (retryError: any) {\n if (retryError instanceof ChatResolvedError || retryError?.message === 'chat_resolved') {\n this.enterResolvedState(this.chatId);\n return;\n }\n throw retryError;\n }\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Switch to human mode\n */\n switchToHumanMode(): void {\n this.chatMode = 'human';\n this.setState({ chatMode: 'human' });\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem('chartsconnect_chat_mode', 'HUMAN');\n }\n }\n\n /**\n * Switch to AI mode\n */\n switchToBotMode(): void {\n this.chatMode = 'ai';\n this.setState({ chatMode: 'ai' });\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem('chartsconnect_chat_mode', 'BOT');\n }\n }\n\n /**\n * Initialize welcome popup\n */\n initializeWelcomePopup(): void {\n if (this.config.showWelcomePopup !== false) {\n const delay = this.config.welcomePopupDelay || 1500;\n setTimeout(() => {\n if (!this.state.isOpen) {\n this.setState({ showWelcomePopup: true });\n }\n }, delay);\n }\n }\n\n /**\n * Handle handoff from Dialogflow to human support\n */\n async handleHandoff(): Promise<void> {\n if (!this.chatService) {\n throw new Error('Chat service not initialized');\n }\n\n try {\n this.isConnectingToAgent = true;\n \n // Get Dialogflow session ID if available\n const dialogflowSessionId = this.state.sessionId;\n \n // STEP 1: Ensure chat is initialized\n const session = await this.chatService.ensureChatInitialized(\n this.chatId,\n this.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 !== this.chatId) {\n this.chatId = currentChatId;\n this.supportSessionId = currentSupportSessionId;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem('chartsconnect_chat_id', this.chatId);\n localStorage.setItem('chartsconnect_session_id', this.supportSessionId);\n }\n if (this.config.debug) {\n console.log('✅ Chat initialized:', { chatId: currentChatId, sessionId: currentSupportSessionId });\n }\n }\n\n // STEP 2: Request handoff\n try {\n await this.chatService.requestHandoff(\n currentChatId,\n currentSupportSessionId,\n 'Customer requested human agent',\n dialogflowSessionId || null\n );\n \n if (this.config.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\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 (this.config.debug) {\n console.log('⚠️ Chat expired or not found. Re-initializing chat...');\n }\n \n // Clear old chat_id\n this.chatId = null;\n this.supportSessionId = null;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.removeItem('chartsconnect_chat_id');\n localStorage.removeItem('chartsconnect_session_id');\n }\n \n // Create new chat session\n const newSession = await this.chatService.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 this.chatId = newSession.chat_id;\n this.supportSessionId = newSession.session_id;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem('chartsconnect_chat_id', this.chatId);\n localStorage.setItem('chartsconnect_session_id', this.supportSessionId);\n }\n \n // Retry handoff with new chat_id\n await this.chatService.requestHandoff(\n this.chatId,\n this.supportSessionId,\n 'Customer requested human agent',\n dialogflowSessionId || null\n );\n \n if (this.config.debug) {\n console.log('✅ Handoff requested successfully after retry');\n }\n } else {\n throw handoffError;\n }\n }\n\n // Switch to human mode\n this.switchToHumanMode();\n this.chatResolved = false;\n this.agentAccepted = false;\n\n // Connect WebSocket with handlers\n if (currentChatId && currentSupportSessionId) {\n this.chatService.connectWebSocket(\n currentChatId,\n currentSupportSessionId,\n (message: WebSocketMessage) => {\n this.handleWebSocketMessage(message);\n },\n (connected: boolean) => {\n this.wsConnected = connected;\n }\n );\n }\n\n // Frontend safety timer: fallback if backend timeout message is missed\n // Slightly longer than backend (200s vs 180s) to give backend priority\n if (this.handoffTimeoutId) {\n clearTimeout(this.handoffTimeoutId);\n }\n this.handoffTimeoutId = setTimeout(() => {\n if (!this.agentAccepted && this.chatMode === 'human') {\n console.warn('Handoff timeout (frontend safety net)');\n this.enterResolvedState(\n this.chatId || null,\n 'All our agents are currently busy. Don\\'t worry \\u2014 I\\'m connecting you back to our AI assistant. Feel free to try reaching a live agent again shortly!'\n );\n }\n }, 200000); // 3 min 20 sec\n\n this.isConnectingToAgent = false;\n } catch (error: any) {\n console.error('Error handling handoff:', error);\n const errorMessage: ChatMessage = {\n id: `error-${Date.now()}`,\n text: this.config.debug\n ? `Handoff error: ${error.message}`\n : 'Failed to connect to agent. Please try again.',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, errorMessage],\n });\n this.isConnectingToAgent = false;\n }\n }\n\n /**\n * Handle WebSocket messages\n */\n private handleWebSocketMessage(message: WebSocketMessage): void {\n switch (message.type) {\n case 'message':\n if (message.content) {\n // Only display messages from agent\n if (message.sender_type === 'agent' || !message.sender_type) {\n const agentMessage: ChatMessage = {\n id: message.id || `agent-${Date.now()}`,\n text: message.content,\n sender: 'agent',\n timestamp: new Date(message.timestamp || Date.now()),\n };\n \n // Avoid duplicate messages\n const existingIds = new Set(this.state.messages.map(m => m.id));\n if (!existingIds.has(agentMessage.id)) {\n this.setState({\n messages: [...this.state.messages, agentMessage],\n });\n }\n \n // Hide typing indicator when message received\n this.agentTyping = false;\n if (this.agentTypingTimeout) {\n clearTimeout(this.agentTypingTimeout);\n this.agentTypingTimeout = null;\n }\n }\n }\n break;\n\n case 'typing_start':\n if (message.sender_type === 'agent') {\n this.agentTyping = true;\n // Auto-hide after 3 seconds if no message received\n if (this.agentTypingTimeout) {\n clearTimeout(this.agentTypingTimeout);\n }\n this.agentTypingTimeout = setTimeout(() => {\n this.agentTyping = false;\n }, 3000);\n }\n break;\n\n case 'typing_stop':\n if (message.sender_type === 'agent') {\n this.agentTyping = false;\n if (this.agentTypingTimeout) {\n clearTimeout(this.agentTypingTimeout);\n this.agentTypingTimeout = null;\n }\n }\n break;\n\n case 'agent_changed':\n if (message.to_agent) {\n this.currentAgent = {\n id: message.to_agent_id,\n name: message.to_agent,\n };\n\n // Add system message to chat\n const systemMessage: ChatMessage = {\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 this.setState({\n messages: [...this.state.messages, systemMessage],\n });\n }\n break;\n\n case 'agent_accepted':\n this.agentAccepted = true;\n this.isConnectingToAgent = false;\n if (this.handoffTimeoutId) {\n clearTimeout(this.handoffTimeoutId);\n this.handoffTimeoutId = null;\n }\n const acceptedMessage: ChatMessage = {\n id: message.id || `agent-accepted-${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 const existingIds = new Set(this.state.messages.map(m => m.id));\n if (!existingIds.has(acceptedMessage.id)) {\n this.setState({\n messages: [...this.state.messages, acceptedMessage],\n });\n }\n if (message.to_agent) {\n this.currentAgent = {\n name: message.to_agent,\n id: message.to_agent_id,\n };\n }\n break;\n\n case 'handoff_timeout':\n this.enterResolvedState(\n message.chat_id || null,\n message.message || 'All our agents are currently busy. Don\\'t worry \\u2014 I\\'m connecting you back to our AI assistant. Feel free to try reaching a live agent again shortly!'\n );\n break;\n\n case 'chat_resolved':\n case 'chat_ended':\n this.enterResolvedState(message.chat_id || null);\n break;\n\n case 'chat_info':\n if (message.status === 'active') {\n this.isConnectingToAgent = false;\n this.agentAccepted = true;\n } else if (message.status === 'resolved' || message.status === 'ended') {\n this.enterResolvedState(message.chat_id || null);\n }\n if (message.agent_id) {\n this.currentAgent = {\n ...this.currentAgent,\n id: message.agent_id,\n };\n }\n break;\n\n case 'error':\n console.error('WebSocket error:', message.error);\n const errorMessage: ChatMessage = {\n id: `error-${Date.now()}`,\n text: message.error || 'An error occurred. Please try again.',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, errorMessage],\n });\n break;\n }\n }\n\n /**\n * Enter resolved state\n */\n private enterResolvedState(resolvedChatId?: string | null, customMessage?: string): void {\n this.chatResolved = true;\n this.isConnectingToAgent = false;\n this.agentAccepted = false;\n this.agentTyping = false;\n if (this.agentTypingTimeout) {\n clearTimeout(this.agentTypingTimeout);\n this.agentTypingTimeout = null;\n }\n if (this.handoffTimeoutId) {\n clearTimeout(this.handoffTimeoutId);\n this.handoffTimeoutId = null;\n }\n\n // Stop WS + prevent any reuse of the old chat_id\n if (this.chatService) {\n this.chatService.disconnectWebSocket();\n }\n this.chatId = null;\n this.supportSessionId = null;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.removeItem('chartsconnect_chat_id');\n localStorage.removeItem('chartsconnect_session_id');\n }\n \n // Add thank you / timeout message before reset\n const thankYouMessage: ChatMessage = {\n id: `resolved-${Date.now()}`,\n text: customMessage || 'Thank you for contacting us!',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, thankYouMessage],\n });\n \n // Automatically reset to BOT mode after showing thank you message\n setTimeout(async () => {\n this.switchToBotMode();\n this.chatResolved = false;\n this.setState({\n messages: [],\n sessionId: null, // Clear session ID to force recreation\n });\n // Recreate Dialogflow session to start fresh\n if (this.config.dfProjectId && this.config.dfAgentId && this.state.isOpen) {\n try {\n this.setState({ isLoading: true });\n const dialogflowConfig: DialogflowBackendConfig = {\n dfProjectId: this.config.dfProjectId,\n dfLocation: this.config.dfLocation || 'us-central1',\n dfAgentId: this.config.dfAgentId,\n languageCode: this.config.languageCode || 'en',\n backendBaseUrl: this.config.backendBaseUrl || 'http://localhost:8012',\n };\n \n const session = await createDialogflowSession(dialogflowConfig);\n this.setState({ \n sessionId: session.session_id,\n isLoading: false,\n });\n \n // Add welcome message from Dialogflow if available\n if (session.message) {\n const welcomeMessage: ChatMessage = {\n id: `welcome-${Date.now()}`,\n text: session.message,\n sender: 'bot',\n timestamp: new Date(),\n richContent: session.richContent,\n };\n this.setState({\n messages: [welcomeMessage],\n });\n }\n } catch (error: any) {\n console.error('Error recreating Dialogflow session after handoff:', error);\n this.setState({ \n isLoading: false,\n error: error.message || 'Failed to initialize chat',\n });\n \n // Show fallback welcome message\n const fallbackMessage: ChatMessage = {\n id: `fallback-${Date.now()}`,\n text: this.config.fallbackWelcomeMessage || 'Hello! How can I help you today?',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [fallbackMessage],\n });\n }\n }\n }, 2000);\n }\n\n /**\n * Load message history\n */\n async loadMessageHistory(preserveExisting: boolean = false): Promise<void> {\n if (!this.chatService || !this.chatId || !this.supportSessionId) {\n return;\n }\n\n try {\n if (this.chatId && this.supportSessionId) {\n const history = await this.chatService.loadMessageHistory(this.chatId, this.supportSessionId);\n \n const historyMessages: ChatMessage[] = history.map((msg: any) => ({\n id: msg.id || `history-${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 const existingIds = new Set(this.state.messages.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 = [...this.state.messages, ...newMessages].sort((a, b) => \n a.timestamp.getTime() - b.timestamp.getTime()\n );\n \n this.setState({\n messages: combined,\n });\n } else {\n // Replace all messages\n this.setState({\n messages: historyMessages,\n });\n }\n }\n } catch (error: any) {\n console.error('Error loading message history:', error);\n if (this.config.debug) {\n const errorMessage: ChatMessage = {\n id: `error-${Date.now()}`,\n text: `Failed to load chat history: ${error.message}`,\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, errorMessage],\n });\n }\n }\n }\n\n /**\n * Get additional state for UI (not in WidgetState but needed by components)\n */\n getAdditionalState() {\n return {\n wsConnected: this.wsConnected,\n agentTyping: this.agentTyping,\n currentAgent: this.currentAgent,\n isConnectingToAgent: this.isConnectingToAgent,\n agentAccepted: this.agentAccepted,\n chatResolved: this.chatResolved,\n };\n }\n\n /**\n * Cleanup\n */\n destroy(): void {\n if (this.typingTimeout) {\n clearTimeout(this.typingTimeout);\n }\n if (this.agentTypingTimeout) {\n clearTimeout(this.agentTypingTimeout);\n }\n if (this.handoffTimeoutId) {\n clearTimeout(this.handoffTimeoutId);\n this.handoffTimeoutId = null;\n }\n if (this.chatService) {\n this.chatService.disconnectWebSocket();\n }\n this.listeners.clear();\n }\n}\n","/**\n * useChatWidget Composable\n * Headless mode for Vue 3 - use logic without UI\n */\n\nimport { ref, computed, onUnmounted, watch, readonly, type Ref } from 'vue';\nimport { WidgetStateManager } from '../core/stateManager';\nimport type { WidgetConfig, WidgetState, ChatMessage } from '../core/types';\n\nexport interface UseChatWidgetReturn {\n // State\n state: Readonly<Ref<WidgetState>>;\n isOpen: Readonly<Ref<boolean>>;\n messages: Readonly<Ref<ChatMessage[]>>;\n isLoading: Readonly<Ref<boolean>>;\n error: Readonly<Ref<string | null>>;\n chatMode: Readonly<Ref<'ai' | 'human'>>;\n\n // Additional state\n wsConnected: Readonly<Ref<boolean>>;\n agentTyping: Readonly<Ref<boolean>>;\n currentAgent: Readonly<Ref<{ name: string; id?: string }>>;\n isConnectingToAgent: Readonly<Ref<boolean>>;\n\n // Actions\n openChat: () => Promise<void>;\n closeChat: () => void;\n sendMessage: (text: string) => Promise<void>;\n toggleChat: () => Promise<void>;\n setInputValue: (value: string) => void;\n clearError: () => void;\n\n // Manager instance (for advanced usage)\n manager: WidgetStateManager;\n}\n\n/**\n * Headless chat widget composable\n * Use this for custom UI implementations\n */\nexport function useChatWidget(config: WidgetConfig): UseChatWidgetReturn {\n // Create state manager\n const manager = new WidgetStateManager(config);\n\n // Reactive state\n const state = ref<WidgetState>(manager.getState());\n const wsConnected = ref(false);\n const agentTyping = ref(false);\n const currentAgent = ref<{ name: string; id?: string }>({ name: 'Agent' });\n const isConnectingToAgent = ref(false);\n\n // Subscribe to state changes\n const unsubscribe = manager.subscribe((newState) => {\n state.value = { ...newState };\n \n // Update additional state\n const additional = manager.getAdditionalState();\n wsConnected.value = additional.wsConnected;\n agentTyping.value = additional.agentTyping;\n currentAgent.value = additional.currentAgent;\n isConnectingToAgent.value = additional.isConnectingToAgent;\n });\n\n // Computed properties\n const isOpen = computed(() => state.value.isOpen);\n const messages = computed(() => state.value.messages);\n const isLoading = computed(() => state.value.isLoading);\n const error = computed(() => state.value.error);\n const chatMode = computed(() => state.value.chatMode);\n\n // Actions\n const openChat = async () => {\n await manager.openChat();\n };\n\n const closeChat = () => {\n manager.closeChat();\n };\n\n const sendMessage = async (text: string) => {\n await manager.sendMessage(text);\n };\n\n const toggleChat = async () => {\n await manager.toggleChat();\n };\n\n const setInputValue = (value: string) => {\n manager.setInputValue(value);\n };\n\n const clearError = () => {\n manager.clearError();\n };\n\n // Cleanup on unmount\n onUnmounted(() => {\n unsubscribe();\n manager.destroy();\n });\n\n // Watch config changes\n watch(\n () => config,\n (newConfig) => {\n manager.updateConfig(newConfig);\n },\n { deep: true }\n );\n\n return {\n state: state as Readonly<Ref<WidgetState>>,\n isOpen: isOpen as Readonly<Ref<boolean>>,\n messages: messages as Readonly<Ref<ChatMessage[]>>,\n isLoading: isLoading as Readonly<Ref<boolean>>,\n error: error as Readonly<Ref<string | null>>,\n chatMode: chatMode as Readonly<Ref<'ai' | 'human'>>,\n wsConnected: wsConnected as Readonly<Ref<boolean>>,\n agentTyping: agentTyping as Readonly<Ref<boolean>>,\n currentAgent: currentAgent as Readonly<Ref<{ name: string; id?: string }>>,\n isConnectingToAgent: isConnectingToAgent as Readonly<Ref<boolean>>,\n openChat,\n closeChat,\n sendMessage,\n toggleChat,\n setInputValue,\n clearError,\n manager,\n };\n}\n","<template>\n <div class=\"custom-chat-widget\" v-bind=\"$attrs\">\n <!-- Welcome Popup -->\n <div\n v-if=\"state.showWelcomePopup && !state.isOpen\"\n class=\"custom-welcome-popup\"\n @click=\"handleOpenChat\"\n >\n <div class=\"custom-welcome-header\">\n <div class=\"custom-welcome-title\">{{ config.welcomeTitle }}</div>\n <button\n class=\"custom-close-popup\"\n @click.stop=\"handleCloseWelcomePopup\"\n aria-label=\"Close welcome popup\"\n >\n ×\n </button>\n </div>\n <div class=\"custom-welcome-message\">{{ config.welcomeMessage }}</div>\n <div class=\"custom-welcome-cta\">{{ config.welcomeCta }}</div>\n </div>\n\n <!-- Chat Toggle Button -->\n <button\n v-if=\"!state.isOpen\"\n class=\"custom-chat-toggle-btn\"\n @click=\"handleOpenChat\"\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 stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"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 <!-- Chat Window -->\n <div v-if=\"state.isOpen\" class=\"custom-chat-window\">\n <div class=\"custom-chat-header\">\n <div class=\"custom-chat-header-content\">\n <div class=\"custom-chat-title\">{{ config.title }}</div>\n <div v-if=\"state.chatMode === 'human'\" class=\"custom-mode-badge\">\n Human Support Mode\n </div>\n <div v-if=\"state.chatMode === 'ai'\" class=\"custom-mode-badge\">\n AI Assistant\n </div>\n <div v-if=\"state.chatMode === 'human'\" class=\"custom-agent-info\">\n <span class=\"custom-agent-label\">Agent:</span>\n <span class=\"custom-agent-name\">{{ currentAgent.name }}</span>\n <span class=\"custom-mode-indicator\">\n • {{ wsConnected ? '🟢 Connected' : '🟡 Connecting...' }}\n </span>\n </div>\n </div>\n <button\n class=\"custom-chat-close-btn\"\n @click=\"handleCloseChat\"\n aria-label=\"Close chat\"\n >\n ×\n </button>\n </div>\n\n <div class=\"custom-chat-messages\" ref=\"messagesContainer\">\n <!-- Empty State -->\n <div v-if=\"isInitializing && state.messages.length === 0\" class=\"custom-chat-empty\">\n <div class=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n <p>Initializing chat...</p>\n </div>\n <div v-else-if=\"!isInitializing && state.messages.length === 0\" class=\"custom-chat-empty\">\n <div class=\"custom-chat-empty-icon\">👋</div>\n <p>{{ config.emptyStateMessage }}</p>\n </div>\n\n <!-- Messages -->\n <div\n v-for=\"message in state.messages\"\n :key=\"message.id\"\n :class=\"[\n 'custom-message', \n `custom-message-${message.sender}`,\n { 'custom-handoff-message': isHandoffMessage(message.text) }\n ]\"\n >\n <div \n class=\"custom-message-content\"\n :class=\"{ 'custom-handoff-content': isHandoffMessage(message.text) }\"\n v-html=\"renderMarkdown(message.text)\"\n ></div>\n \n <!-- Rich Content (Chips) -->\n <div\n v-if=\"message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0\"\n class=\"custom-chips-container\"\n >\n <template v-for=\"(contentGroup, groupIndex) in message.richContent\" :key=\"groupIndex\">\n <template v-if=\"!Array.isArray(contentGroup)\">\n <div\n v-if=\"contentGroup.type === 'chips' && contentGroup.options\"\n class=\"custom-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in contentGroup.options\"\n :key=\"chipIndex\"\n class=\"custom-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n <template v-else>\n <template\n v-for=\"(content, contentIndex) in contentGroup\"\n :key=\"`${groupIndex}-${contentIndex}`\"\n >\n <div\n v-if=\"content.type === 'chips' && content.options\"\n class=\"custom-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in content.options\"\n :key=\"chipIndex\"\n class=\"custom-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n </template>\n </template>\n </div>\n\n <div class=\"custom-message-time\">\n {{ formatTime(message.timestamp) }}\n </div>\n </div>\n\n <!-- Loading Indicator -->\n <div v-if=\"state.isLoading\" class=\"custom-message custom-message-bot\">\n <div class=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n\n <!-- Connecting to Agent Indicator -->\n <div v-if=\"isConnectingToAgent\" class=\"custom-message custom-message-bot\">\n <div class=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n\n <!-- Agent Typing Indicator -->\n <div v-if=\"state.chatMode === 'human' && agentTyping\" class=\"custom-message custom-message-bot\">\n <div class=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n\n <div ref=\"messagesEndRef\"></div>\n </div>\n\n <!-- Input Form -->\n <form class=\"custom-chat-input-form\" @submit.prevent=\"handleSubmit\">\n <input\n ref=\"inputRef\"\n type=\"text\"\n class=\"custom-chat-input\"\n :value=\"state.inputValue\"\n @input=\"handleInput\"\n :placeholder=\"config.inputPlaceholder\"\n :disabled=\"state.isLoading || isInitializing || isStartingNewChat\"\n />\n <button\n type=\"submit\"\n class=\"custom-chat-send-btn\"\n :disabled=\"!state.inputValue.trim() || state.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 stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"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 </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted, nextTick, watch } from 'vue';\nimport { useChatWidget } from '../composables/useChatWidget';\nimport { renderMarkdown } from '../utils/sanitize';\nimport type { WidgetConfig } from '../core/types';\n\n// Handle attributes properly to avoid Vue warnings\n// For Vue 3.3+, defineOptions is available as a compiler macro\n// @ts-ignore - defineOptions is a compiler macro\ndefineOptions({\n inheritAttrs: false, // We handle attrs manually via v-bind=\"$attrs\"\n});\n\n// Props\nconst props = withDefaults(defineProps<WidgetConfig>(), {\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: 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});\n\n// Use headless composable\nconst {\n state,\n isOpen,\n messages,\n isLoading,\n error,\n chatMode,\n wsConnected,\n agentTyping,\n currentAgent,\n isConnectingToAgent: isConnectingToAgentFromComposable,\n openChat,\n closeChat,\n sendMessage,\n toggleChat,\n setInputValue,\n clearError,\n manager,\n} = useChatWidget(props);\n\n// Refs\nconst messagesEndRef = ref<HTMLDivElement | null>(null);\nconst inputRef = ref<HTMLInputElement | null>(null);\nconst messagesContainer = ref<HTMLDivElement | null>(null);\n\n// Computed config (for reactivity)\nconst config = computed(() => props);\n\n// Computed state for initialization and connection (matching React component)\nconst isInitializing = computed(() => {\n return state.value.isLoading && state.value.messages.length === 0 && !state.value.sessionId;\n});\n\nconst isStartingNewChat = computed(() => {\n // This would be tracked in manager if needed, for now return false\n return false;\n});\n\n// Use isConnectingToAgent from composable (already computed in manager)\nconst isConnectingToAgent = isConnectingToAgentFromComposable;\n\n// Auto-scroll to bottom when messages change\nwatch(\n () => messages.value.length,\n () => {\n nextTick(() => {\n messagesEndRef.value?.scrollIntoView({ behavior: 'smooth' });\n });\n }\n);\n\n// Handlers\nconst handleOpenChat = async () => {\n // Ensure immediate UI response\n if (!state.value.isOpen) {\n state.value.isOpen = true;\n state.value.showWelcomePopup = false;\n }\n await openChat();\n};\n\nconst handleCloseChat = () => {\n closeChat();\n};\n\nconst handleCloseWelcomePopup = () => {\n manager.closeWelcomePopup();\n};\n\nconst handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement;\n setInputValue(target.value);\n};\n\nconst handleSubmit = async (event: Event) => {\n event.preventDefault();\n if (state.value.inputValue.trim()) {\n await sendMessage(state.value.inputValue);\n }\n // Keep focus on input so user can continue typing\n inputRef.value?.focus();\n};\n\nconst handleChipClick = async (chipText: string, payload?: string) => {\n const messageToSend = chipText || payload || '';\n await sendMessage(messageToSend);\n};\n\n// Utility functions\nconst formatTime = (date: Date): string => {\n return date.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n });\n};\n\n// Check if message is a handoff message\nconst isHandoffMessage = (text: string): boolean => {\n return text.includes('👤') || \n text.includes('being connected') || \n text.includes('live support agent') ||\n text.includes('transfer your conversation');\n};\n\n// Initialize welcome popup on mount (SSR-safe)\nonMounted(() => {\n if (config.value.showWelcomePopup && typeof window !== 'undefined') {\n manager.initializeWelcomePopup();\n }\n});\n</script>\n\n<style scoped>\n/* Styles are imported separately by users */\n/* This ensures SSR compatibility */\n</style>\n"],"names":["botMessage","existingIds","_openBlock","_createElementBlock","_mergeProps","$attrs","_unref","_createElementVNode","_toDisplayString","_Fragment","_renderList","_normalizeClass"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ChatWidget-BYXJ0hwt.js","sources":["../src/core/stateManager.ts","../src/composables/useChatWidget.ts","../src/components/ChatWidget.vue"],"sourcesContent":["/**\n * State Manager - Framework Agnostic\n * Manages widget state independently of framework\n */\n\nimport type { WidgetState, WidgetConfig, ChatMessage } from './types';\nimport {\n createDialogflowSession,\n sendDialogflowMessage,\n type DialogflowBackendConfig,\n} from '../services/dialogflowBackendService';\nimport { \n createChatService, \n ChatResolvedError,\n type WebSocketMessage\n} from '../services/chatService';\n\nexport class WidgetStateManager {\n private state: WidgetState;\n private config: WidgetConfig;\n private listeners: Set<(state: WidgetState) => void> = new Set();\n private chatMode: 'ai' | 'human' = 'ai';\n private chatId: string | null = null;\n private supportSessionId: string | null = null;\n private chatService: ReturnType<typeof createChatService> | null = null;\n \n // Additional state for human support\n private wsConnected: boolean = false;\n private agentTyping: boolean = false;\n private currentAgent: { name: string; id?: string } = { name: 'Agent' };\n private isConnectingToAgent: boolean = false;\n private agentAccepted: boolean = false;\n private chatResolved: boolean = false;\n private historyLoaded: string | null = null;\n \n // Typing timeout refs (stored as class properties since we can't use refs)\n private typingTimeout: NodeJS.Timeout | null = null;\n private agentTypingTimeout: NodeJS.Timeout | null = null;\n private handoffTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\n constructor(config: WidgetConfig) {\n this.config = config;\n this.state = {\n isOpen: false,\n showWelcomePopup: false,\n messages: [],\n inputValue: '',\n isLoading: false,\n error: null,\n sessionId: null,\n chatMode: 'ai',\n };\n \n // Initialize ChatService\n this.chatService = createChatService({\n baseUrl: this.config.backendBaseUrl || 'http://localhost:8012',\n wsUrl: this.config.backendWsUrl || 'ws://localhost:8012',\n debug: this.config.debug || false,\n });\n \n // Load chat mode and chat IDs from localStorage if available\n if (typeof window !== 'undefined' && window.localStorage) {\n const savedMode = localStorage.getItem('chartsconnectect_chat_mode');\n this.chatMode = savedMode === 'HUMAN' ? 'human' : 'ai';\n this.state.chatMode = this.chatMode;\n \n this.chatId = localStorage.getItem('chartsconnect_chat_id');\n this.supportSessionId = localStorage.getItem('chartsconnect_session_id');\n }\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(listener: (state: WidgetState) => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n /**\n * Get current state\n */\n getState(): WidgetState {\n return { ...this.state };\n }\n\n /**\n * Update state and notify listeners\n */\n private setState(updates: Partial<WidgetState>): void {\n this.state = { ...this.state, ...updates };\n this.listeners.forEach(listener => listener(this.getState()));\n }\n\n /**\n * Update configuration\n */\n updateConfig(config: Partial<WidgetConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Open chat\n */\n async openChat(): Promise<void> {\n this.setState({ isOpen: true });\n if (this.state.showWelcomePopup) {\n this.setState({ showWelcomePopup: false });\n }\n \n // Initialize Dialogflow session when chat opens (if in AI mode and no session exists)\n if (this.state.chatMode === 'ai' && !this.state.sessionId && this.config.dfProjectId && this.config.dfAgentId) {\n try {\n this.setState({ isLoading: true });\n const dialogflowConfig: DialogflowBackendConfig = {\n dfProjectId: this.config.dfProjectId,\n dfLocation: this.config.dfLocation || 'us-central1',\n dfAgentId: this.config.dfAgentId,\n languageCode: this.config.languageCode || 'en',\n backendBaseUrl: this.config.backendBaseUrl || 'http://localhost:8012',\n };\n \n const session = await createDialogflowSession(dialogflowConfig);\n this.setState({ \n sessionId: session.session_id,\n isLoading: false,\n });\n \n // Add welcome message from Dialogflow if available\n if (session.message) {\n const welcomeMessage: ChatMessage = {\n id: `welcome-${Date.now()}`,\n text: session.message,\n sender: 'bot',\n timestamp: new Date(),\n richContent: session.richContent,\n };\n this.setState({\n messages: [welcomeMessage],\n });\n }\n } catch (error: any) {\n console.error('Error initializing Dialogflow session:', error);\n this.setState({ \n isLoading: false,\n error: error.message || 'Failed to initialize chat',\n });\n \n // Show fallback welcome message\n const fallbackMessage: ChatMessage = {\n id: `fallback-${Date.now()}`,\n text: this.config.fallbackWelcomeMessage || 'Hello! How can I help you today?',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [fallbackMessage],\n });\n }\n }\n }\n\n /**\n * Close chat\n */\n closeChat(): void {\n this.setState({ isOpen: false });\n }\n\n /**\n * Close welcome popup\n */\n closeWelcomePopup(): void {\n this.setState({ showWelcomePopup: false });\n }\n\n /**\n * Toggle chat\n */\n toggleChat(): void {\n const willBeOpen = !this.state.isOpen;\n this.setState({ isOpen: willBeOpen });\n if (willBeOpen && this.state.showWelcomePopup) {\n this.setState({ showWelcomePopup: false });\n }\n }\n\n /**\n * Set input value\n */\n setInputValue(value: string): void {\n this.setState({ inputValue: value });\n }\n\n /**\n * Clear error\n */\n clearError(): void {\n this.setState({ error: null });\n }\n\n /**\n * Send message\n */\n async sendMessage(text: string, skipUserMessage: boolean = false): Promise<void> {\n if (!text.trim() || this.state.isLoading) {\n return;\n }\n\n // Add user message unless skipped (e.g., when chip button already added it)\n if (!skipUserMessage) {\n const userMessage: ChatMessage = {\n id: `user-${Date.now()}`,\n text: text.trim(),\n sender: 'user',\n timestamp: new Date(),\n };\n\n this.setState({\n messages: [...this.state.messages, userMessage],\n inputValue: '',\n isLoading: true,\n error: null,\n });\n } else {\n this.setState({\n inputValue: '',\n isLoading: true,\n error: null,\n });\n }\n\n try {\n if (this.state.chatMode === 'human') {\n // Human support mode\n await this.sendHumanMessage(text);\n } else {\n // AI mode (Dialogflow)\n await this.sendAIMessage(text);\n }\n } catch (error: any) {\n console.error('Error sending message:', error);\n \n // chat_resolved is a normal terminal condition, not an error\n if (error instanceof ChatResolvedError || error?.name === 'ChatResolvedError' || error?.message === 'chat_resolved') {\n this.enterResolvedState(this.chatId);\n return;\n }\n \n // Add error message to chat\n const errorMessage: ChatMessage = {\n id: `error-${Date.now()}`,\n text: this.config.debug \n ? `Error: ${error.message || 'Failed to send message'}`\n : error.message?.includes('CORS') || error.message?.includes('Failed to fetch')\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 \n this.setState({\n messages: [...this.state.messages, errorMessage],\n error: error.message || 'Failed to send message',\n isLoading: false,\n });\n }\n }\n\n /**\n * Send message to Dialogflow\n */\n private async sendAIMessage(text: string): Promise<void> {\n if (!this.config.dfProjectId || !this.config.dfAgentId) {\n throw new Error('Dialogflow configuration is missing');\n }\n\n const dialogflowConfig: DialogflowBackendConfig = {\n dfProjectId: this.config.dfProjectId!,\n dfLocation: this.config.dfLocation || 'us-central1',\n dfAgentId: this.config.dfAgentId!,\n languageCode: this.config.languageCode || 'en',\n backendBaseUrl: this.config.backendBaseUrl || 'http://localhost:8012',\n };\n\n // Create session if needed\n if (!this.state.sessionId) {\n const session = await createDialogflowSession(dialogflowConfig);\n this.setState({ sessionId: session.session_id });\n }\n\n // Send message (correct parameter order: message, sessionId, config)\n if (this.config.debug) {\n console.log('Sending message to Dialogflow:', {\n message: text,\n sessionId: this.state.sessionId,\n hasConfig: !!dialogflowConfig,\n });\n }\n \n const response = await sendDialogflowMessage(\n text,\n this.state.sessionId!,\n dialogflowConfig\n );\n\n if (this.config.debug) {\n console.log('Dialogflow response:', {\n response: response.response,\n hasRichContent: !!response.richContent,\n richContent: response.richContent,\n });\n }\n\n // Check for handoff\n if (response.handoff === true) {\n // Add bot response first\n const botMessage: ChatMessage = {\n id: `bot-${Date.now()}`,\n text: response.response || this.config.fallbackWelcomeMessage || 'No response',\n sender: 'bot',\n timestamp: new Date(),\n richContent: response.richContent,\n };\n this.setState({\n messages: [...this.state.messages, botMessage],\n isLoading: false,\n });\n \n // Proceed directly with handoff — user details collected by Dialogflow via webhook\n await this.handleHandoff();\n return;\n }\n \n const botMessage: ChatMessage = {\n id: `bot-${Date.now()}`,\n text: response.response || this.config.fallbackWelcomeMessage || 'No response',\n sender: 'bot',\n timestamp: new Date(),\n richContent: response.richContent,\n };\n\n this.setState({\n messages: [...this.state.messages, botMessage],\n isLoading: false,\n });\n }\n\n /**\n * Send message to human support\n */\n private async sendHumanMessage(text: string): Promise<void> {\n if (!this.chatId || !this.supportSessionId) {\n const errorMessage: ChatMessage = {\n id: `error-${Date.now()}`,\n text: 'Chat session not initialized. Please try again.',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, errorMessage],\n isLoading: false,\n });\n return;\n }\n\n if (!this.chatService) {\n throw new Error('Chat service not initialized');\n }\n\n // Send typing_stop before sending message\n this.chatService.sendTypingIndicator('typing_stop');\n if (this.typingTimeout) {\n clearTimeout(this.typingTimeout);\n this.typingTimeout = null;\n }\n\n try {\n // Try WebSocket first, fallback to REST API\n const sentViaWs = this.chatService.sendMessageViaWebSocket(text.trim());\n \n if (!sentViaWs) {\n // Fallback to REST API\n await this.chatService.sendMessageToAgent(this.chatId, this.supportSessionId, text.trim());\n }\n \n this.setState({ isLoading: false });\n } catch (error: any) {\n // chat_resolved is a normal terminal condition, not an error\n if (error instanceof ChatResolvedError || error?.name === 'ChatResolvedError' || error?.message === 'chat_resolved') {\n this.enterResolvedState(this.chatId);\n return;\n }\n\n // Handle 401/404 - clear chat_id and reinitialize\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 (this.config.debug) {\n console.log('⚠️ Chat expired. Re-initializing...');\n }\n \n // Clear chat_id\n this.chatId = null;\n this.supportSessionId = null;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.removeItem('chartsconnect_chat_id');\n localStorage.removeItem('chartsconnect_session_id');\n }\n \n // Try to reinitialize chat\n try {\n const newSession = await this.chatService.startSupportChat(\n this.state.sessionId || null\n );\n this.chatId = newSession.chat_id;\n this.supportSessionId = newSession.session_id;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem('chartsconnect_chat_id', this.chatId);\n localStorage.setItem('chartsconnect_session_id', this.supportSessionId);\n }\n \n // Retry sending message\n if (this.chatId && this.supportSessionId) {\n await this.chatService.sendMessageToAgent(\n this.chatId,\n this.supportSessionId,\n text.trim()\n );\n }\n this.setState({ isLoading: false });\n return;\n } catch (retryError: any) {\n if (retryError instanceof ChatResolvedError || retryError?.message === 'chat_resolved') {\n this.enterResolvedState(this.chatId);\n return;\n }\n throw retryError;\n }\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Switch to human mode\n */\n switchToHumanMode(): void {\n this.chatMode = 'human';\n this.setState({ chatMode: 'human' });\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem('chartsconnect_chat_mode', 'HUMAN');\n }\n }\n\n /**\n * Switch to AI mode\n */\n switchToBotMode(): void {\n this.chatMode = 'ai';\n this.setState({ chatMode: 'ai' });\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem('chartsconnect_chat_mode', 'BOT');\n }\n }\n\n /**\n * Initialize welcome popup\n */\n initializeWelcomePopup(): void {\n if (this.config.showWelcomePopup !== false) {\n const delay = this.config.welcomePopupDelay || 1500;\n setTimeout(() => {\n if (!this.state.isOpen) {\n this.setState({ showWelcomePopup: true });\n }\n }, delay);\n }\n }\n\n /**\n * Handle handoff from Dialogflow to human support\n */\n async handleHandoff(): Promise<void> {\n if (!this.chatService) {\n throw new Error('Chat service not initialized');\n }\n\n try {\n this.isConnectingToAgent = true;\n \n // Get Dialogflow session ID if available\n const dialogflowSessionId = this.state.sessionId;\n \n // STEP 1: Ensure chat is initialized\n const session = await this.chatService.ensureChatInitialized(\n this.chatId,\n this.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 !== this.chatId) {\n this.chatId = currentChatId;\n this.supportSessionId = currentSupportSessionId;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem('chartsconnect_chat_id', this.chatId);\n localStorage.setItem('chartsconnect_session_id', this.supportSessionId);\n }\n if (this.config.debug) {\n console.log('✅ Chat initialized:', { chatId: currentChatId, sessionId: currentSupportSessionId });\n }\n }\n\n // STEP 2: Request handoff\n try {\n await this.chatService.requestHandoff(\n currentChatId,\n currentSupportSessionId,\n 'Customer requested human agent',\n dialogflowSessionId || null\n );\n \n if (this.config.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\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 (this.config.debug) {\n console.log('⚠️ Chat expired or not found. Re-initializing chat...');\n }\n \n // Clear old chat_id\n this.chatId = null;\n this.supportSessionId = null;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.removeItem('chartsconnect_chat_id');\n localStorage.removeItem('chartsconnect_session_id');\n }\n \n // Create new chat session\n const newSession = await this.chatService.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 this.chatId = newSession.chat_id;\n this.supportSessionId = newSession.session_id;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem('chartsconnect_chat_id', this.chatId);\n localStorage.setItem('chartsconnect_session_id', this.supportSessionId);\n }\n \n // Retry handoff with new chat_id\n await this.chatService.requestHandoff(\n this.chatId,\n this.supportSessionId,\n 'Customer requested human agent',\n dialogflowSessionId || null\n );\n \n if (this.config.debug) {\n console.log('✅ Handoff requested successfully after retry');\n }\n } else {\n throw handoffError;\n }\n }\n\n // Switch to human mode\n this.switchToHumanMode();\n this.chatResolved = false;\n this.agentAccepted = false;\n\n // Connect WebSocket with handlers\n if (currentChatId && currentSupportSessionId) {\n this.chatService.connectWebSocket(\n currentChatId,\n currentSupportSessionId,\n (message: WebSocketMessage) => {\n this.handleWebSocketMessage(message);\n },\n (connected: boolean) => {\n this.wsConnected = connected;\n }\n );\n }\n\n // Frontend safety timer: fallback if backend timeout message is missed\n // Slightly longer than backend (200s vs 180s) to give backend priority\n if (this.handoffTimeoutId) {\n clearTimeout(this.handoffTimeoutId);\n }\n this.handoffTimeoutId = setTimeout(() => {\n if (!this.agentAccepted && this.chatMode === 'human') {\n console.warn('Handoff timeout (frontend safety net)');\n this.enterResolvedState(\n this.chatId || null,\n 'All our agents are currently busy. Don\\'t worry \\u2014 I\\'m connecting you back to our AI assistant. Feel free to try reaching a live agent again shortly!'\n );\n }\n }, 200000); // 3 min 20 sec\n\n this.isConnectingToAgent = false;\n } catch (error: any) {\n console.error('Error handling handoff:', error);\n const errorMessage: ChatMessage = {\n id: `error-${Date.now()}`,\n text: this.config.debug\n ? `Handoff error: ${error.message}`\n : 'Failed to connect to agent. Please try again.',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, errorMessage],\n });\n this.isConnectingToAgent = false;\n }\n }\n\n /**\n * Handle WebSocket messages\n */\n private handleWebSocketMessage(message: WebSocketMessage): void {\n switch (message.type) {\n case 'message':\n if (message.content) {\n // Only display messages from agent\n if (message.sender_type === 'agent' || !message.sender_type) {\n const agentMessage: ChatMessage = {\n id: message.id || `agent-${Date.now()}`,\n text: message.content,\n sender: 'agent',\n timestamp: new Date(message.timestamp || Date.now()),\n };\n \n // Avoid duplicate messages\n const existingIds = new Set(this.state.messages.map(m => m.id));\n if (!existingIds.has(agentMessage.id)) {\n this.setState({\n messages: [...this.state.messages, agentMessage],\n });\n }\n \n // Hide typing indicator when message received\n this.agentTyping = false;\n if (this.agentTypingTimeout) {\n clearTimeout(this.agentTypingTimeout);\n this.agentTypingTimeout = null;\n }\n }\n }\n break;\n\n case 'typing_start':\n if (message.sender_type === 'agent') {\n this.agentTyping = true;\n // Auto-hide after 3 seconds if no message received\n if (this.agentTypingTimeout) {\n clearTimeout(this.agentTypingTimeout);\n }\n this.agentTypingTimeout = setTimeout(() => {\n this.agentTyping = false;\n }, 3000);\n }\n break;\n\n case 'typing_stop':\n if (message.sender_type === 'agent') {\n this.agentTyping = false;\n if (this.agentTypingTimeout) {\n clearTimeout(this.agentTypingTimeout);\n this.agentTypingTimeout = null;\n }\n }\n break;\n\n case 'agent_changed':\n if (message.to_agent) {\n this.currentAgent = {\n id: message.to_agent_id,\n name: message.to_agent,\n };\n\n // Add system message to chat\n const systemMessage: ChatMessage = {\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 this.setState({\n messages: [...this.state.messages, systemMessage],\n });\n }\n break;\n\n case 'agent_accepted':\n this.agentAccepted = true;\n this.isConnectingToAgent = false;\n if (this.handoffTimeoutId) {\n clearTimeout(this.handoffTimeoutId);\n this.handoffTimeoutId = null;\n }\n const acceptedMessage: ChatMessage = {\n id: message.id || `agent-accepted-${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 const existingIds = new Set(this.state.messages.map(m => m.id));\n if (!existingIds.has(acceptedMessage.id)) {\n this.setState({\n messages: [...this.state.messages, acceptedMessage],\n });\n }\n if (message.to_agent) {\n this.currentAgent = {\n name: message.to_agent,\n id: message.to_agent_id,\n };\n }\n break;\n\n case 'handoff_timeout':\n this.enterResolvedState(\n message.chat_id || null,\n message.message || 'All our agents are currently busy. Don\\'t worry \\u2014 I\\'m connecting you back to our AI assistant. Feel free to try reaching a live agent again shortly!'\n );\n break;\n\n case 'chat_resolved':\n case 'chat_ended':\n this.enterResolvedState(message.chat_id || null);\n break;\n\n case 'chat_info':\n if (message.status === 'active') {\n this.isConnectingToAgent = false;\n this.agentAccepted = true;\n } else if (message.status === 'resolved' || message.status === 'ended') {\n this.enterResolvedState(message.chat_id || null);\n }\n if (message.agent_id) {\n this.currentAgent = {\n ...this.currentAgent,\n id: message.agent_id,\n };\n }\n break;\n\n case 'error':\n console.error('WebSocket error:', message.error);\n const errorMessage: ChatMessage = {\n id: `error-${Date.now()}`,\n text: message.error || 'An error occurred. Please try again.',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, errorMessage],\n });\n break;\n }\n }\n\n /**\n * Enter resolved state\n */\n private enterResolvedState(resolvedChatId?: string | null, customMessage?: string): void {\n this.chatResolved = true;\n this.isConnectingToAgent = false;\n this.agentAccepted = false;\n this.agentTyping = false;\n if (this.agentTypingTimeout) {\n clearTimeout(this.agentTypingTimeout);\n this.agentTypingTimeout = null;\n }\n if (this.handoffTimeoutId) {\n clearTimeout(this.handoffTimeoutId);\n this.handoffTimeoutId = null;\n }\n\n // Stop WS + prevent any reuse of the old chat_id\n if (this.chatService) {\n this.chatService.disconnectWebSocket();\n }\n this.chatId = null;\n this.supportSessionId = null;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.removeItem('chartsconnect_chat_id');\n localStorage.removeItem('chartsconnect_session_id');\n }\n \n // Add thank you / timeout message before reset\n const thankYouMessage: ChatMessage = {\n id: `resolved-${Date.now()}`,\n text: customMessage || 'Thank you for contacting us!',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, thankYouMessage],\n });\n \n // Automatically reset to BOT mode after showing thank you message\n setTimeout(async () => {\n this.switchToBotMode();\n this.chatResolved = false;\n this.setState({\n messages: [],\n sessionId: null, // Clear session ID to force recreation\n });\n // Recreate Dialogflow session to start fresh\n if (this.config.dfProjectId && this.config.dfAgentId && this.state.isOpen) {\n try {\n this.setState({ isLoading: true });\n const dialogflowConfig: DialogflowBackendConfig = {\n dfProjectId: this.config.dfProjectId,\n dfLocation: this.config.dfLocation || 'us-central1',\n dfAgentId: this.config.dfAgentId,\n languageCode: this.config.languageCode || 'en',\n backendBaseUrl: this.config.backendBaseUrl || 'http://localhost:8012',\n };\n \n const session = await createDialogflowSession(dialogflowConfig);\n this.setState({ \n sessionId: session.session_id,\n isLoading: false,\n });\n \n // Add welcome message from Dialogflow if available\n if (session.message) {\n const welcomeMessage: ChatMessage = {\n id: `welcome-${Date.now()}`,\n text: session.message,\n sender: 'bot',\n timestamp: new Date(),\n richContent: session.richContent,\n };\n this.setState({\n messages: [welcomeMessage],\n });\n }\n } catch (error: any) {\n console.error('Error recreating Dialogflow session after handoff:', error);\n this.setState({ \n isLoading: false,\n error: error.message || 'Failed to initialize chat',\n });\n \n // Show fallback welcome message\n const fallbackMessage: ChatMessage = {\n id: `fallback-${Date.now()}`,\n text: this.config.fallbackWelcomeMessage || 'Hello! How can I help you today?',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [fallbackMessage],\n });\n }\n }\n }, 2000);\n }\n\n /**\n * Load message history\n */\n async loadMessageHistory(preserveExisting: boolean = false): Promise<void> {\n if (!this.chatService || !this.chatId || !this.supportSessionId) {\n return;\n }\n\n try {\n if (this.chatId && this.supportSessionId) {\n const history = await this.chatService.loadMessageHistory(this.chatId, this.supportSessionId);\n \n const historyMessages: ChatMessage[] = history.map((msg: any) => ({\n id: msg.id || `history-${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 const existingIds = new Set(this.state.messages.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 = [...this.state.messages, ...newMessages].sort((a, b) => \n a.timestamp.getTime() - b.timestamp.getTime()\n );\n \n this.setState({\n messages: combined,\n });\n } else {\n // Replace all messages\n this.setState({\n messages: historyMessages,\n });\n }\n }\n } catch (error: any) {\n console.error('Error loading message history:', error);\n if (this.config.debug) {\n const errorMessage: ChatMessage = {\n id: `error-${Date.now()}`,\n text: `Failed to load chat history: ${error.message}`,\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, errorMessage],\n });\n }\n }\n }\n\n /**\n * Get additional state for UI (not in WidgetState but needed by components)\n */\n getAdditionalState() {\n return {\n wsConnected: this.wsConnected,\n agentTyping: this.agentTyping,\n currentAgent: this.currentAgent,\n isConnectingToAgent: this.isConnectingToAgent,\n agentAccepted: this.agentAccepted,\n chatResolved: this.chatResolved,\n };\n }\n\n /**\n * Cleanup\n */\n destroy(): void {\n if (this.typingTimeout) {\n clearTimeout(this.typingTimeout);\n }\n if (this.agentTypingTimeout) {\n clearTimeout(this.agentTypingTimeout);\n }\n if (this.handoffTimeoutId) {\n clearTimeout(this.handoffTimeoutId);\n this.handoffTimeoutId = null;\n }\n if (this.chatService) {\n this.chatService.disconnectWebSocket();\n }\n this.listeners.clear();\n }\n}\n","/**\n * useChatWidget Composable\n * Headless mode for Vue 3 - use logic without UI\n */\n\nimport { ref, computed, onUnmounted, watch, readonly, type Ref } from 'vue';\nimport { WidgetStateManager } from '../core/stateManager';\nimport type { WidgetConfig, WidgetState, ChatMessage } from '../core/types';\n\nexport interface UseChatWidgetReturn {\n // State\n state: Readonly<Ref<WidgetState>>;\n isOpen: Readonly<Ref<boolean>>;\n messages: Readonly<Ref<ChatMessage[]>>;\n isLoading: Readonly<Ref<boolean>>;\n error: Readonly<Ref<string | null>>;\n chatMode: Readonly<Ref<'ai' | 'human'>>;\n\n // Additional state\n wsConnected: Readonly<Ref<boolean>>;\n agentTyping: Readonly<Ref<boolean>>;\n currentAgent: Readonly<Ref<{ name: string; id?: string }>>;\n isConnectingToAgent: Readonly<Ref<boolean>>;\n\n // Actions\n openChat: () => Promise<void>;\n closeChat: () => void;\n sendMessage: (text: string) => Promise<void>;\n toggleChat: () => Promise<void>;\n setInputValue: (value: string) => void;\n clearError: () => void;\n\n // Manager instance (for advanced usage)\n manager: WidgetStateManager;\n}\n\n/**\n * Headless chat widget composable\n * Use this for custom UI implementations\n */\nexport function useChatWidget(config: WidgetConfig): UseChatWidgetReturn {\n // Create state manager\n const manager = new WidgetStateManager(config);\n\n // Reactive state\n const state = ref<WidgetState>(manager.getState());\n const wsConnected = ref(false);\n const agentTyping = ref(false);\n const currentAgent = ref<{ name: string; id?: string }>({ name: 'Agent' });\n const isConnectingToAgent = ref(false);\n\n // Subscribe to state changes\n const unsubscribe = manager.subscribe((newState) => {\n state.value = { ...newState };\n \n // Update additional state\n const additional = manager.getAdditionalState();\n wsConnected.value = additional.wsConnected;\n agentTyping.value = additional.agentTyping;\n currentAgent.value = additional.currentAgent;\n isConnectingToAgent.value = additional.isConnectingToAgent;\n });\n\n // Computed properties\n const isOpen = computed(() => state.value.isOpen);\n const messages = computed(() => state.value.messages);\n const isLoading = computed(() => state.value.isLoading);\n const error = computed(() => state.value.error);\n const chatMode = computed(() => state.value.chatMode);\n\n // Actions\n const openChat = async () => {\n await manager.openChat();\n };\n\n const closeChat = () => {\n manager.closeChat();\n };\n\n const sendMessage = async (text: string) => {\n await manager.sendMessage(text);\n };\n\n const toggleChat = async () => {\n await manager.toggleChat();\n };\n\n const setInputValue = (value: string) => {\n manager.setInputValue(value);\n };\n\n const clearError = () => {\n manager.clearError();\n };\n\n // Cleanup on unmount\n onUnmounted(() => {\n unsubscribe();\n manager.destroy();\n });\n\n // Watch config changes\n watch(\n () => config,\n (newConfig) => {\n manager.updateConfig(newConfig);\n },\n { deep: true }\n );\n\n return {\n state: state as Readonly<Ref<WidgetState>>,\n isOpen: isOpen as Readonly<Ref<boolean>>,\n messages: messages as Readonly<Ref<ChatMessage[]>>,\n isLoading: isLoading as Readonly<Ref<boolean>>,\n error: error as Readonly<Ref<string | null>>,\n chatMode: chatMode as Readonly<Ref<'ai' | 'human'>>,\n wsConnected: wsConnected as Readonly<Ref<boolean>>,\n agentTyping: agentTyping as Readonly<Ref<boolean>>,\n currentAgent: currentAgent as Readonly<Ref<{ name: string; id?: string }>>,\n isConnectingToAgent: isConnectingToAgent as Readonly<Ref<boolean>>,\n openChat,\n closeChat,\n sendMessage,\n toggleChat,\n setInputValue,\n clearError,\n manager,\n };\n}\n","<template>\n <div class=\"custom-chat-widget\" v-bind=\"$attrs\">\n <!-- Welcome Popup -->\n <div\n v-if=\"state.showWelcomePopup && !state.isOpen\"\n class=\"custom-welcome-popup\"\n @click=\"handleOpenChat\"\n >\n <div class=\"custom-welcome-header\">\n <div class=\"custom-welcome-title\">{{ config.welcomeTitle }}</div>\n <button\n class=\"custom-close-popup\"\n @click.stop=\"handleCloseWelcomePopup\"\n aria-label=\"Close welcome popup\"\n >\n ×\n </button>\n </div>\n <div class=\"custom-welcome-message\">{{ config.welcomeMessage }}</div>\n <div class=\"custom-welcome-cta\">{{ config.welcomeCta }}</div>\n </div>\n\n <!-- Chat Toggle Button -->\n <button\n v-if=\"!state.isOpen\"\n class=\"custom-chat-toggle-btn\"\n @click=\"handleOpenChat\"\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 stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"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 <!-- Chat Window -->\n <div v-if=\"state.isOpen\" class=\"custom-chat-window\">\n <div class=\"custom-chat-header\">\n <div class=\"custom-chat-header-content\">\n <div class=\"custom-chat-title\">{{ config.title }}</div>\n <div class=\"custom-mode-row\">\n <div v-if=\"state.chatMode === 'human'\" class=\"custom-mode-badge\">\n Human Support Mode\n </div>\n <div v-if=\"state.chatMode === 'ai'\" class=\"custom-mode-badge\">\n AI Assistant\n </div>\n <div v-if=\"state.chatMode === 'human'\" class=\"custom-agent-info\">\n <span class=\"custom-agent-label\">Agent:</span>\n <span class=\"custom-agent-name\">{{ currentAgent.name }}</span>\n <span class=\"custom-mode-indicator\">\n • {{ wsConnected ? '🟢 Connected' : '🟡 Connecting...' }}\n </span>\n </div>\n </div>\n </div>\n <button\n class=\"custom-chat-close-btn\"\n @click=\"handleCloseChat\"\n aria-label=\"Close chat\"\n >\n ×\n </button>\n </div>\n\n <div class=\"custom-chat-messages\" ref=\"messagesContainer\">\n <!-- Empty State -->\n <div v-if=\"isInitializing && state.messages.length === 0\" class=\"custom-chat-empty\">\n <div class=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n <p>Initializing chat...</p>\n </div>\n <div v-else-if=\"!isInitializing && state.messages.length === 0\" class=\"custom-chat-empty\">\n <div class=\"custom-chat-empty-icon\">👋</div>\n <p>{{ config.emptyStateMessage }}</p>\n </div>\n\n <!-- Messages -->\n <div\n v-for=\"message in state.messages\"\n :key=\"message.id\"\n :class=\"[\n 'custom-message', \n `custom-message-${message.sender}`,\n { 'custom-handoff-message': isHandoffMessage(message.text) }\n ]\"\n >\n <div \n class=\"custom-message-content\"\n :class=\"{ 'custom-handoff-content': isHandoffMessage(message.text) }\"\n v-html=\"renderMarkdown(message.text)\"\n ></div>\n \n <!-- Rich Content (Chips) -->\n <div\n v-if=\"message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0\"\n class=\"custom-chips-container\"\n >\n <template v-for=\"(contentGroup, groupIndex) in message.richContent\" :key=\"groupIndex\">\n <template v-if=\"!Array.isArray(contentGroup)\">\n <div\n v-if=\"contentGroup.type === 'chips' && contentGroup.options\"\n class=\"custom-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in contentGroup.options\"\n :key=\"chipIndex\"\n class=\"custom-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n <template v-else>\n <template\n v-for=\"(content, contentIndex) in contentGroup\"\n :key=\"`${groupIndex}-${contentIndex}`\"\n >\n <div\n v-if=\"content.type === 'chips' && content.options\"\n class=\"custom-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in content.options\"\n :key=\"chipIndex\"\n class=\"custom-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n </template>\n </template>\n </div>\n\n <div class=\"custom-message-time\">\n {{ formatTime(message.timestamp) }}\n </div>\n </div>\n\n <!-- Loading Indicator -->\n <div v-if=\"state.isLoading\" class=\"custom-message custom-message-bot\">\n <div class=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n\n <!-- Connecting to Agent Indicator -->\n <div v-if=\"isConnectingToAgent\" class=\"custom-message custom-message-bot\">\n <div class=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n\n <!-- Agent Typing Indicator -->\n <div v-if=\"state.chatMode === 'human' && agentTyping\" class=\"custom-message custom-message-bot\">\n <div class=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n\n <div ref=\"messagesEndRef\"></div>\n </div>\n\n <!-- Input Form -->\n <form class=\"custom-chat-input-form\" @submit.prevent=\"handleSubmit\">\n <input\n ref=\"inputRef\"\n type=\"text\"\n class=\"custom-chat-input\"\n :value=\"state.inputValue\"\n @input=\"handleInput\"\n :placeholder=\"config.inputPlaceholder\"\n :disabled=\"state.isLoading || isInitializing || isStartingNewChat\"\n />\n <button\n type=\"submit\"\n class=\"custom-chat-send-btn\"\n :disabled=\"!state.inputValue.trim() || state.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 stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"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 </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted, nextTick, watch } from 'vue';\nimport { useChatWidget } from '../composables/useChatWidget';\nimport { renderMarkdown } from '../utils/sanitize';\nimport type { WidgetConfig } from '../core/types';\n\n// Handle attributes properly to avoid Vue warnings\n// For Vue 3.3+, defineOptions is available as a compiler macro\n// @ts-ignore - defineOptions is a compiler macro\ndefineOptions({\n inheritAttrs: false, // We handle attrs manually via v-bind=\"$attrs\"\n});\n\n// Props\nconst props = withDefaults(defineProps<WidgetConfig>(), {\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: 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});\n\n// Use headless composable\nconst {\n state,\n isOpen,\n messages,\n isLoading,\n error,\n chatMode,\n wsConnected,\n agentTyping,\n currentAgent,\n isConnectingToAgent: isConnectingToAgentFromComposable,\n openChat,\n closeChat,\n sendMessage,\n toggleChat,\n setInputValue,\n clearError,\n manager,\n} = useChatWidget(props);\n\n// Refs\nconst messagesEndRef = ref<HTMLDivElement | null>(null);\nconst inputRef = ref<HTMLInputElement | null>(null);\nconst messagesContainer = ref<HTMLDivElement | null>(null);\n\n// Computed config (for reactivity)\nconst config = computed(() => props);\n\n// Computed state for initialization and connection (matching React component)\nconst isInitializing = computed(() => {\n return state.value.isLoading && state.value.messages.length === 0 && !state.value.sessionId;\n});\n\nconst isStartingNewChat = computed(() => {\n // This would be tracked in manager if needed, for now return false\n return false;\n});\n\n// Use isConnectingToAgent from composable (already computed in manager)\nconst isConnectingToAgent = isConnectingToAgentFromComposable;\n\n// Auto-scroll to bottom when messages change\nwatch(\n () => messages.value.length,\n () => {\n nextTick(() => {\n messagesEndRef.value?.scrollIntoView({ behavior: 'smooth' });\n });\n }\n);\n\n// Handlers\nconst handleOpenChat = async () => {\n // Ensure immediate UI response\n if (!state.value.isOpen) {\n state.value.isOpen = true;\n state.value.showWelcomePopup = false;\n }\n await openChat();\n};\n\nconst handleCloseChat = () => {\n closeChat();\n};\n\nconst handleCloseWelcomePopup = () => {\n manager.closeWelcomePopup();\n};\n\nconst handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement;\n setInputValue(target.value);\n};\n\nconst handleSubmit = async (event: Event) => {\n event.preventDefault();\n if (state.value.inputValue.trim()) {\n await sendMessage(state.value.inputValue);\n }\n // Keep focus on input so user can continue typing\n inputRef.value?.focus();\n};\n\nconst handleChipClick = async (chipText: string, payload?: string) => {\n const messageToSend = chipText || payload || '';\n await sendMessage(messageToSend);\n};\n\n// Utility functions\nconst formatTime = (date: Date): string => {\n return date.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n });\n};\n\n// Check if message is a handoff message\nconst isHandoffMessage = (text: string): boolean => {\n return text.includes('👤') || \n text.includes('being connected') || \n text.includes('live support agent') ||\n text.includes('transfer your conversation');\n};\n\n// Initialize welcome popup on mount (SSR-safe)\nonMounted(() => {\n if (config.value.showWelcomePopup && typeof window !== 'undefined') {\n manager.initializeWelcomePopup();\n }\n});\n</script>\n\n<style scoped>\n/* Styles are imported separately by users */\n/* This ensures SSR compatibility */\n</style>\n"],"names":["botMessage","existingIds","_openBlock","_createElementBlock","_mergeProps","$attrs","_unref","_createElementVNode","_toDisplayString","_Fragment","_renderList","_normalizeClass"],"mappings":"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"}
|