@blumessage/react-chat 1.4.0 → 1.4.2

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.
@@ -1,153 +1,198 @@
1
- var __assign = (this && this.__assign) || function () {
2
- __assign = Object.assign || function(t) {
3
- for (var s, i = 1, n = arguments.length; i < n; i++) {
4
- s = arguments[i];
5
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
- t[p] = s[p];
7
- }
8
- return t;
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
9
26
  };
10
- return __assign.apply(this, arguments);
11
- };
12
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
- return new (P || (P = Promise))(function (resolve, reject) {
15
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
- step((generator = generator.apply(thisArg, _arguments || [])).next());
19
- });
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20
37
  };
21
- var __generator = (this && this.__generator) || function (thisArg, body) {
22
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
23
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
- function verb(n) { return function (v) { return step([n, v]); }; }
25
- function step(op) {
26
- if (f) throw new TypeError("Generator is already executing.");
27
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
- if (y = 0, t) op = [op[0] & 2, t.value];
30
- switch (op[0]) {
31
- case 0: case 1: t = op; break;
32
- case 4: _.label++; return { value: op[1], done: false };
33
- case 5: _.label++; y = op[1]; op = [0]; continue;
34
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
- default:
36
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
- if (t[2]) _.ops.pop();
41
- _.trys.pop(); continue;
42
- }
43
- op = body.call(thisArg, _);
44
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.BlumessageChat = void 0;
40
+ const jsx_runtime_1 = require("react/jsx-runtime");
41
+ const react_1 = __importStar(require("react"));
42
+ const react_markdown_1 = __importDefault(require("react-markdown"));
43
+ const remark_gfm_1 = __importDefault(require("remark-gfm"));
44
+ const lucide_react_1 = require("lucide-react");
45
+ // Custom CSS animations that don't depend on Tailwind
46
+ const customStyles = `
47
+ @keyframes bounce {
48
+ 0%, 100% {
49
+ transform: translateY(0);
46
50
  }
47
- };
48
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
49
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
50
- if (ar || !(i in from)) {
51
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
52
- ar[i] = from[i];
53
- }
51
+ 50% {
52
+ transform: translateY(-25%);
54
53
  }
55
- return to.concat(ar || Array.prototype.slice.call(from));
56
- };
57
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
58
- import React, { useState, useEffect, useRef, forwardRef, useImperativeHandle } from "react";
59
- import ReactMarkdown from 'react-markdown';
60
- import remarkGfm from 'remark-gfm';
61
- import { MessageCircle, AlertTriangle, Loader2, Send, X, Maximize, Minimize2, Bot, MessageSquare, Phone, Mail, Headphones, Users, User, Heart, Star, Zap } from "lucide-react";
62
- // Custom CSS animations that don't depend on Tailwind
63
- var customStyles = "\n @keyframes bounce {\n 0%, 100% {\n transform: translateY(0);\n }\n 50% {\n transform: translateY(-25%);\n }\n }\n \n @keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n }\n \n .blumessage-animate-bounce {\n animation: bounce 1s infinite;\n }\n \n .blumessage-animate-spin {\n animation: spin 1s linear infinite;\n }\n \n /* Mobile-specific styles */\n @media (max-width: 768px) {\n .blumessage-mobile-fullscreen {\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n right: 0 !important;\n bottom: 0 !important;\n width: 100% !important;\n height: 100% !important;\n max-width: 100% !important;\n max-height: 100% !important;\n border-radius: 0 !important;\n z-index: 9999 !important;\n }\n \n .blumessage-mobile-chat {\n border-radius: 16px !important;\n }\n \n .blumessage-mobile-button {\n position: fixed !important;\n bottom: 20px !important;\n right: 20px !important;\n left: auto !important;\n top: auto !important;\n }\n }\n \n @media (max-width: 480px) {\n .blumessage-mobile-fullscreen {\n border-radius: 0 !important;\n }\n \n .blumessage-mobile-chat {\n border-radius: 12px !important;\n }\n \n .blumessage-mobile-button {\n bottom: 16px !important;\n right: 16px !important;\n }\n }\n";
54
+ }
55
+
56
+ @keyframes spin {
57
+ 0% {
58
+ transform: rotate(0deg);
59
+ }
60
+ 100% {
61
+ transform: rotate(360deg);
62
+ }
63
+ }
64
+
65
+ .blumessage-animate-bounce {
66
+ animation: bounce 1s infinite;
67
+ }
68
+
69
+ .blumessage-animate-spin {
70
+ animation: spin 1s linear infinite;
71
+ }
72
+
73
+ /* Mobile-specific styles */
74
+ @media (max-width: 768px) {
75
+ .blumessage-mobile-fullscreen {
76
+ position: fixed !important;
77
+ top: 0 !important;
78
+ left: 0 !important;
79
+ right: 0 !important;
80
+ bottom: 0 !important;
81
+ width: 100% !important;
82
+ height: 100% !important;
83
+ max-width: 100% !important;
84
+ max-height: 100% !important;
85
+ border-radius: 0 !important;
86
+ z-index: 9999 !important;
87
+ }
88
+
89
+ .blumessage-mobile-chat {
90
+ border-radius: 16px !important;
91
+ }
92
+
93
+ .blumessage-mobile-button {
94
+ position: fixed !important;
95
+ bottom: 20px !important;
96
+ right: 20px !important;
97
+ left: auto !important;
98
+ top: auto !important;
99
+ }
100
+ }
101
+
102
+ @media (max-width: 480px) {
103
+ .blumessage-mobile-fullscreen {
104
+ border-radius: 0 !important;
105
+ }
106
+
107
+ .blumessage-mobile-chat {
108
+ border-radius: 12px !important;
109
+ }
110
+
111
+ .blumessage-mobile-button {
112
+ bottom: 16px !important;
113
+ right: 16px !important;
114
+ }
115
+ }
116
+ `;
64
117
  // Inject custom styles
65
118
  if (typeof document !== 'undefined' && !document.getElementById('blumessage-styles')) {
66
- var style = document.createElement('style');
119
+ const style = document.createElement('style');
67
120
  style.id = 'blumessage-styles';
68
121
  style.textContent = customStyles;
69
122
  document.head.appendChild(style);
70
123
  }
71
124
  // Session storage key for conversation token
72
- var CONVERSATION_TOKEN_KEY = 'blumessage_conversation_token';
125
+ const CONVERSATION_TOKEN_KEY = 'blumessage_conversation_token';
73
126
  // Utility functions for storage
74
- var saveConversationToken = function (token, persistent) {
75
- if (persistent === void 0) { persistent = false; }
127
+ const saveConversationToken = (token, persistent = false) => {
76
128
  try {
77
- var storage = persistent ? localStorage : sessionStorage;
129
+ const storage = persistent ? localStorage : sessionStorage;
78
130
  storage.setItem(CONVERSATION_TOKEN_KEY, token);
79
131
  }
80
132
  catch (error) {
81
- console.warn("Failed to save conversation token to ".concat(persistent ? 'local' : 'session', " storage:"), error);
133
+ console.warn(`Failed to save conversation token to ${persistent ? 'local' : 'session'} storage:`, error);
82
134
  }
83
135
  };
84
- var getStoredConversationToken = function (persistent) {
85
- if (persistent === void 0) { persistent = false; }
136
+ const getStoredConversationToken = (persistent = false) => {
86
137
  try {
87
- var storage = persistent ? localStorage : sessionStorage;
138
+ const storage = persistent ? localStorage : sessionStorage;
88
139
  return storage.getItem(CONVERSATION_TOKEN_KEY);
89
140
  }
90
141
  catch (error) {
91
- console.warn("Failed to get conversation token from ".concat(persistent ? 'local' : 'session', " storage:"), error);
142
+ console.warn(`Failed to get conversation token from ${persistent ? 'local' : 'session'} storage:`, error);
92
143
  return null;
93
144
  }
94
145
  };
95
- var clearStoredConversationToken = function (persistent) {
96
- if (persistent === void 0) { persistent = false; }
146
+ const clearStoredConversationToken = (persistent = false) => {
97
147
  try {
98
- var storage = persistent ? localStorage : sessionStorage;
148
+ const storage = persistent ? localStorage : sessionStorage;
99
149
  storage.removeItem(CONVERSATION_TOKEN_KEY);
100
150
  }
101
151
  catch (error) {
102
- console.warn("Failed to clear conversation token from ".concat(persistent ? 'local' : 'session', " storage:"), error);
152
+ console.warn(`Failed to clear conversation token from ${persistent ? 'local' : 'session'} storage:`, error);
103
153
  }
104
154
  };
105
155
  // Custom hook for mobile detection
106
- var useIsMobile = function () {
107
- var _a = useState(false), isMobile = _a[0], setIsMobile = _a[1];
108
- useEffect(function () {
109
- var checkIsMobile = function () {
110
- var userAgent = navigator.userAgent || navigator.vendor || window.opera;
111
- var mobileRegex = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i;
112
- var isMobileDevice = mobileRegex.test(userAgent.toLowerCase());
113
- var isSmallScreen = window.innerWidth <= 768;
156
+ const useIsMobile = () => {
157
+ const [isMobile, setIsMobile] = (0, react_1.useState)(false);
158
+ (0, react_1.useEffect)(() => {
159
+ const checkIsMobile = () => {
160
+ const userAgent = navigator.userAgent || navigator.vendor || window.opera;
161
+ const mobileRegex = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i;
162
+ const isMobileDevice = mobileRegex.test(userAgent.toLowerCase());
163
+ const isSmallScreen = window.innerWidth <= 768;
114
164
  setIsMobile(isMobileDevice || isSmallScreen);
115
165
  };
116
166
  checkIsMobile();
117
167
  window.addEventListener('resize', checkIsMobile);
118
- return function () { return window.removeEventListener('resize', checkIsMobile); };
168
+ return () => window.removeEventListener('resize', checkIsMobile);
119
169
  }, []);
120
170
  return isMobile;
121
171
  };
122
- export var BlumessageChat = forwardRef(function (_a, ref) {
123
- var apiKey = _a.apiKey, _b = _a.placeholder, placeholder = _b === void 0 ? "Type your message..." : _b, _c = _a.theme, theme = _c === void 0 ? 'light' : _c, width = _a.width, height = _a.height, _d = _a.size, size = _d === void 0 ? 'medium' : _d, _e = _a.name, name = _e === void 0 ? "Blumessage AI" : _e, _f = _a.subtitle, subtitle = _f === void 0 ? "Online • Instant responses" : _f, _g = _a.initialMessages, initialMessages = _g === void 0 ? [] : _g, onUserMessage = _a.onUserMessage, onAssistantMessage = _a.onAssistantMessage, initialToken = _a.token, onTokenChange = _a.onTokenChange, onChatWidgetOpen = _a.onChatWidgetOpen, onChatWidgetClosed = _a.onChatWidgetClosed, onError = _a.onError, _h = _a.persistent, persistent = _h === void 0 ? false : _h, _j = _a.showTimestamps, showTimestamps = _j === void 0 ? false : _j, _k = _a.typingText, typingText = _k === void 0 ? "Agent is typing..." : _k, _l = _a.emptyStateText, emptyStateText = _l === void 0 ? "Start a conversation!" : _l, _m = _a.markdown, markdown = _m === void 0 ? true : _m,
124
- // Floating button props
125
- _o = _a.floating,
126
- // Floating button props
127
- floating = _o === void 0 ? true : _o, _p = _a.buttonText, buttonText = _p === void 0 ? "Chat with us" : _p, _q = _a.buttonPosition, buttonPosition = _q === void 0 ? 'bottom-right' : _q, buttonStyle = _a.buttonStyle, _r = _a.defaultOpen, defaultOpen = _r === void 0 ? false : _r, _s = _a.maximizeToggleButton, maximizeToggleButton = _s === void 0 ? true : _s, _t = _a.fullScreen, fullScreen = _t === void 0 ? false : _t, _u = _a.icon, icon = _u === void 0 ? 'message-circle' : _u,
128
- // Styling props
129
- _v = _a.primaryColor,
130
- // Styling props
131
- primaryColor = _v === void 0 ? "linear-gradient(to right, #3b82f6,rgb(8, 98, 242))" : _v;
132
- var _w = useState(false), isInitialized = _w[0], setIsInitialized = _w[1];
133
- var _x = useState(null), error = _x[0], setError = _x[1];
134
- var _y = useState(initialMessages), messages = _y[0], setMessages = _y[1];
135
- var _z = useState(''), inputValue = _z[0], setInputValue = _z[1];
136
- var _0 = useState(initialToken || getStoredConversationToken(persistent)), token = _0[0], setToken = _0[1];
137
- var _1 = useState(defaultOpen), isOpen = _1[0], setIsOpen = _1[1];
138
- var _2 = useState(false), isAnimating = _2[0], setIsAnimating = _2[1];
139
- var _3 = useState(false), isLoading = _3[0], setIsLoading = _3[1];
140
- var _4 = useState(false), isMaximized = _4[0], setIsMaximized = _4[1];
141
- var messagesEndRef = useRef(null);
142
- var isInitialLoad = useRef(true);
172
+ exports.BlumessageChat = (0, react_1.forwardRef)(({ apiKey, placeholder = "Type your message...", theme = 'light', width, height, size = 'medium', name = "Blumessage AI", subtitle = "Online • Instant responses", initialMessages = [], onUserMessage, onAssistantMessage, token: initialToken, onTokenChange, onChatWidgetOpen, onChatWidgetClosed, onError, persistent = false, showTimestamps = false, typingText = "Agent is typing...", emptyStateText = "Start a conversation!", markdown = true, disableAutoScroll = false,
173
+ // Floating button props
174
+ floating = true, buttonText = "Chat with us", buttonPosition = 'bottom-right', buttonStyle, defaultOpen = false, maximizeToggleButton = true, fullScreen = false, icon = 'message-circle',
175
+ // Styling props
176
+ primaryColor = "linear-gradient(to right, #3b82f6,rgb(8, 98, 242))" }, ref) => {
177
+ const [isInitialized, setIsInitialized] = (0, react_1.useState)(false);
178
+ const [error, setError] = (0, react_1.useState)(null);
179
+ const [messages, setMessages] = (0, react_1.useState)(initialMessages);
180
+ const [inputValue, setInputValue] = (0, react_1.useState)('');
181
+ const [token, setToken] = (0, react_1.useState)(initialToken || getStoredConversationToken(persistent));
182
+ const [isOpen, setIsOpen] = (0, react_1.useState)(defaultOpen);
183
+ const [isAnimating, setIsAnimating] = (0, react_1.useState)(false);
184
+ const [isLoading, setIsLoading] = (0, react_1.useState)(false);
185
+ const [isMaximized, setIsMaximized] = (0, react_1.useState)(false);
186
+ const messagesEndRef = (0, react_1.useRef)(null);
187
+ const isInitialLoad = (0, react_1.useRef)(true);
143
188
  // Mobile detection
144
- var isMobile = useIsMobile();
189
+ const isMobile = useIsMobile();
145
190
  // Helper function to format timestamp
146
- var formatTimestamp = function (timestamp) {
147
- var date = new Date(timestamp);
148
- var now = new Date();
191
+ const formatTimestamp = (timestamp) => {
192
+ const date = new Date(timestamp);
193
+ const now = new Date();
149
194
  // Check if the message is from today
150
- var isToday = date.toDateString() === now.toDateString();
195
+ const isToday = date.toDateString() === now.toDateString();
151
196
  if (isToday) {
152
197
  // If today: show time only in user's locale format (14:00 or 2:00 PM)
153
198
  return date.toLocaleTimeString(undefined, {
@@ -158,23 +203,23 @@ export var BlumessageChat = forwardRef(function (_a, ref) {
158
203
  }
159
204
  else {
160
205
  // If more than a day: show "17 July, 13:00" format in user's locale
161
- var dateStr = date.toLocaleDateString(undefined, {
206
+ const dateStr = date.toLocaleDateString(undefined, {
162
207
  day: 'numeric',
163
208
  month: 'long'
164
209
  });
165
- var timeStr = date.toLocaleTimeString(undefined, {
210
+ const timeStr = date.toLocaleTimeString(undefined, {
166
211
  hour: '2-digit',
167
212
  minute: '2-digit',
168
213
  hour12: undefined // Let browser decide based on user's locale
169
214
  });
170
- return "".concat(dateStr, ", ").concat(timeStr);
215
+ return `${dateStr}, ${timeStr}`;
171
216
  }
172
217
  };
173
218
  // Helper function to get dimensions based on size
174
- var getDimensions = function () {
219
+ const getDimensions = () => {
175
220
  // If custom width/height are provided, use them
176
221
  if (width && height) {
177
- return { width: width, height: height };
222
+ return { width, height };
178
223
  }
179
224
  // Mobile-first responsive dimensions
180
225
  if (isMobile) {
@@ -193,7 +238,7 @@ export var BlumessageChat = forwardRef(function (_a, ref) {
193
238
  }
194
239
  }
195
240
  // Desktop dimensions based on size
196
- var dimensions;
241
+ let dimensions;
197
242
  switch (size) {
198
243
  case 'small':
199
244
  dimensions = { width: '320px', height: '400px' };
@@ -207,14 +252,14 @@ export var BlumessageChat = forwardRef(function (_a, ref) {
207
252
  }
208
253
  return dimensions;
209
254
  };
210
- var _5 = getDimensions(), actualWidth = _5.width, actualHeight = _5.height;
255
+ const { width: actualWidth, height: actualHeight } = getDimensions();
211
256
  // Function to clear conversation and start fresh
212
- var clearConversation = function () {
257
+ const clearConversation = () => {
213
258
  updateConversationToken(null);
214
259
  setMessages([]);
215
260
  };
216
261
  // Function to update conversation token and notify parent
217
- var updateConversationToken = function (newToken) {
262
+ const updateConversationToken = (newToken) => {
218
263
  setToken(newToken);
219
264
  if (newToken) {
220
265
  saveConversationToken(newToken, persistent);
@@ -227,53 +272,44 @@ export var BlumessageChat = forwardRef(function (_a, ref) {
227
272
  }
228
273
  };
229
274
  // Function to fetch conversation history
230
- var fetchConversationHistory = function (convToken) { return __awaiter(void 0, void 0, void 0, function () {
231
- var response, sessionData, error_1;
232
- return __generator(this, function (_a) {
233
- switch (_a.label) {
234
- case 0:
235
- _a.trys.push([0, 5, , 6]);
236
- console.log("Fetching conversation history for:", convToken);
237
- return [4 /*yield*/, fetch("https://api.blumessage.com/api/v1/conversations/session/".concat(convToken), {
238
- method: 'GET',
239
- headers: {
240
- 'Authorization': "Bearer ".concat(apiKey),
241
- },
242
- })];
243
- case 1:
244
- response = _a.sent();
245
- if (!response.ok) return [3 /*break*/, 3];
246
- return [4 /*yield*/, response.json()];
247
- case 2:
248
- sessionData = _a.sent();
249
- console.log("Conversation history loaded successfully");
250
- return [2 /*return*/, sessionData.messages || []];
251
- case 3:
252
- console.error("Failed to fetch conversation history:", response.status, response.statusText);
253
- // Clear invalid conversation ID from storage
254
- updateConversationToken(null);
255
- if (onError) {
256
- onError("Failed to fetch conversation history: ".concat(response.status, " ").concat(response.statusText), "conversation_history");
257
- }
258
- return [2 /*return*/, []];
259
- case 4: return [3 /*break*/, 6];
260
- case 5:
261
- error_1 = _a.sent();
262
- console.error("Error fetching conversation history:", error_1);
263
- // Clear invalid conversation ID from storage
264
- updateConversationToken(null);
265
- if (onError) {
266
- onError("Error fetching conversation history: ".concat(error_1), "conversation_history");
267
- }
268
- return [2 /*return*/, []];
269
- case 6: return [2 /*return*/];
275
+ const fetchConversationHistory = async (convToken) => {
276
+ try {
277
+ console.log("Fetching conversation history for:", convToken);
278
+ const response = await fetch(`https://api.blumessage.com/api/v1/conversations/session/${convToken}`, {
279
+ method: 'GET',
280
+ headers: {
281
+ 'Authorization': `Bearer ${apiKey}`,
282
+ },
283
+ });
284
+ if (response.ok) {
285
+ const sessionData = await response.json();
286
+ console.log("Conversation history loaded successfully");
287
+ return sessionData.messages || [];
270
288
  }
271
- });
272
- }); };
273
- useEffect(function () {
289
+ else {
290
+ console.error("Failed to fetch conversation history:", response.status, response.statusText);
291
+ // Clear invalid conversation ID from storage
292
+ updateConversationToken(null);
293
+ if (onError) {
294
+ onError(`Failed to fetch conversation history: ${response.status} ${response.statusText}`, "conversation_history");
295
+ }
296
+ return [];
297
+ }
298
+ }
299
+ catch (error) {
300
+ console.error("Error fetching conversation history:", error);
301
+ // Clear invalid conversation ID from storage
302
+ updateConversationToken(null);
303
+ if (onError) {
304
+ onError(`Error fetching conversation history: ${error}`, "conversation_history");
305
+ }
306
+ return [];
307
+ }
308
+ };
309
+ (0, react_1.useEffect)(() => {
274
310
  if (!apiKey) {
275
311
  console.error("Blumessage Chat: API key is required");
276
- var errorMessage = "API key is required";
312
+ const errorMessage = "API key is required";
277
313
  setError(errorMessage);
278
314
  if (onError) {
279
315
  onError(errorMessage, "missing_api_key");
@@ -281,223 +317,196 @@ export var BlumessageChat = forwardRef(function (_a, ref) {
281
317
  return;
282
318
  }
283
319
  // Validate API key with Blumessage API
284
- var validateApiKey = function () { return __awaiter(void 0, void 0, void 0, function () {
285
- var response, errorMessage, err_1, errorMessage;
286
- return __generator(this, function (_a) {
287
- switch (_a.label) {
288
- case 0:
289
- _a.trys.push([0, 2, , 3]);
290
- setIsInitialized(false);
291
- setError(null);
292
- console.log("Initializing Blumessage chat...");
293
- return [4 /*yield*/, fetch('https://api.blumessage.com/api/v1/api-keys/validate', {
294
- method: 'POST',
295
- headers: {
296
- 'Content-Type': 'application/json',
297
- },
298
- body: JSON.stringify({ apiKey: apiKey }),
299
- })];
300
- case 1:
301
- response = _a.sent();
302
- if (response.ok) {
303
- console.log("Blumessage chat initialized successfully");
304
- setIsInitialized(true);
305
- setError(null);
306
- }
307
- else {
308
- console.error("Blumessage chat initialization failed:", response.status, response.statusText);
309
- errorMessage = "Unable to connect - invalid API key";
310
- setError(errorMessage);
311
- setIsInitialized(false);
312
- if (onError) {
313
- onError(errorMessage, "api_key_validation");
314
- }
315
- }
316
- return [3 /*break*/, 3];
317
- case 2:
318
- err_1 = _a.sent();
319
- console.error("Blumessage chat initialization error:", err_1);
320
- errorMessage = "Unable to connect - network error";
321
- setError(errorMessage);
322
- setIsInitialized(false);
323
- if (onError) {
324
- onError(errorMessage, "network_error");
325
- }
326
- return [3 /*break*/, 3];
327
- case 3: return [2 /*return*/];
320
+ const validateApiKey = async () => {
321
+ try {
322
+ setIsInitialized(false);
323
+ setError(null);
324
+ console.log("Initializing Blumessage chat...");
325
+ const response = await fetch('https://api.blumessage.com/api/v1/api-keys/validate', {
326
+ method: 'POST',
327
+ headers: {
328
+ 'Content-Type': 'application/json',
329
+ },
330
+ body: JSON.stringify({ apiKey }),
331
+ });
332
+ if (response.ok) {
333
+ console.log("Blumessage chat initialized successfully");
334
+ setIsInitialized(true);
335
+ setError(null);
328
336
  }
329
- });
330
- }); };
337
+ else {
338
+ console.error("Blumessage chat initialization failed:", response.status, response.statusText);
339
+ const errorMessage = "Unable to connect - invalid API key";
340
+ setError(errorMessage);
341
+ setIsInitialized(false);
342
+ if (onError) {
343
+ onError(errorMessage, "api_key_validation");
344
+ }
345
+ }
346
+ }
347
+ catch (err) {
348
+ console.error("Blumessage chat initialization error:", err);
349
+ const errorMessage = "Unable to connect - network error";
350
+ setError(errorMessage);
351
+ setIsInitialized(false);
352
+ if (onError) {
353
+ onError(errorMessage, "network_error");
354
+ }
355
+ }
356
+ };
331
357
  validateApiKey();
332
358
  }, [apiKey]);
333
359
  // Handle initial message loading (only runs once on mount)
334
- useEffect(function () {
335
- var loadInitialMessages = function () { return __awaiter(void 0, void 0, void 0, function () {
336
- var historyMessages;
337
- return __generator(this, function (_a) {
338
- switch (_a.label) {
339
- case 0:
340
- if (!isInitialLoad.current) return [3 /*break*/, 5];
341
- isInitialLoad.current = false;
342
- if (!(initialMessages.length > 0 && token)) return [3 /*break*/, 1];
343
- // Warn if both are provided - initialMessages takes precedence
344
- console.warn('Both initialMessages and token provided. Using initialMessages and ignoring stored token.');
345
- setMessages(initialMessages);
346
- return [3 /*break*/, 5];
347
- case 1:
348
- if (!(initialMessages.length > 0)) return [3 /*break*/, 2];
349
- // Use provided initial messages
350
- setMessages(initialMessages);
351
- return [3 /*break*/, 5];
352
- case 2:
353
- if (!token) return [3 /*break*/, 4];
354
- return [4 /*yield*/, fetchConversationHistory(token)];
355
- case 3:
356
- historyMessages = _a.sent();
357
- setMessages(historyMessages); // Will be empty array if fetch failed
358
- return [3 /*break*/, 5];
359
- case 4:
360
- // No conversation ID and no initial messages - start with empty array
361
- setMessages([]);
362
- _a.label = 5;
363
- case 5: return [2 /*return*/];
360
+ (0, react_1.useEffect)(() => {
361
+ const loadInitialMessages = async () => {
362
+ if (isInitialLoad.current) {
363
+ isInitialLoad.current = false;
364
+ // Handle message initialization based on conversation state
365
+ if (initialMessages.length > 0 && token) {
366
+ // Warn if both are provided - initialMessages takes precedence
367
+ console.warn('Both initialMessages and token provided. Using initialMessages and ignoring stored token.');
368
+ setMessages(initialMessages);
364
369
  }
365
- });
366
- }); };
370
+ else if (initialMessages.length > 0) {
371
+ // Use provided initial messages
372
+ setMessages(initialMessages);
373
+ }
374
+ else if (token) {
375
+ // Fetch conversation history if we have a stored conversation ID
376
+ const historyMessages = await fetchConversationHistory(token);
377
+ setMessages(historyMessages); // Will be empty array if fetch failed
378
+ }
379
+ else {
380
+ // No conversation ID and no initial messages - start with empty array
381
+ setMessages([]);
382
+ }
383
+ }
384
+ };
367
385
  // Only load initial messages after API key is validated
368
386
  if (isInitialized) {
369
387
  loadInitialMessages();
370
388
  }
371
389
  }, [isInitialized]);
372
- var handleSendMessage = function () { return __awaiter(void 0, void 0, void 0, function () {
373
- var userMessage, currentInput, requestBody, response, apiResponse, assistantMessages, latestAssistantMessage, assistantResponse_1, errorMessage_1, error_2, errorMessage_2;
374
- return __generator(this, function (_a) {
375
- switch (_a.label) {
376
- case 0:
377
- if (!inputValue.trim() || isLoading)
378
- return [2 /*return*/];
379
- userMessage = {
380
- id: Date.now().toString(),
381
- content: inputValue.trim(),
382
- role: 'user',
383
- timestamp: Date.now()
384
- };
385
- // Add user message to UI immediately
386
- setMessages(function (prev) { return __spreadArray(__spreadArray([], prev, true), [userMessage], false); });
387
- currentInput = inputValue.trim();
388
- setInputValue('');
389
- setIsLoading(true);
390
- // Call the callback if provided
391
- if (onUserMessage) {
392
- onUserMessage(userMessage);
393
- }
394
- _a.label = 1;
395
- case 1:
396
- _a.trys.push([1, 6, 7, 8]);
397
- requestBody = {
398
- message: currentInput,
399
- };
400
- // Include token if we have one
401
- if (token) {
402
- requestBody.token = token;
403
- }
404
- return [4 /*yield*/, fetch('https://api.blumessage.com/api/v1/conversations', {
405
- method: 'POST',
406
- headers: {
407
- 'Content-Type': 'application/json',
408
- 'Authorization': "Bearer ".concat(apiKey),
409
- },
410
- body: JSON.stringify(requestBody),
411
- })];
412
- case 2:
413
- response = _a.sent();
414
- if (!response.ok) return [3 /*break*/, 4];
415
- return [4 /*yield*/, response.json()];
416
- case 3:
417
- apiResponse = _a.sent();
418
- // Update token from response (for both first message and continuing conversations)
419
- updateConversationToken(apiResponse.token);
420
- assistantMessages = apiResponse.messages.filter(function (msg) { return msg.role === 'assistant'; });
421
- latestAssistantMessage = assistantMessages[assistantMessages.length - 1];
422
- if (latestAssistantMessage) {
423
- assistantResponse_1 = {
424
- id: (Date.now() + 1).toString(),
425
- content: latestAssistantMessage.content,
426
- role: 'assistant',
427
- timestamp: latestAssistantMessage.timestamp,
428
- };
429
- setMessages(function (prev) { return __spreadArray(__spreadArray([], prev, true), [assistantResponse_1], false); });
430
- if (onAssistantMessage) {
431
- onAssistantMessage(assistantResponse_1);
432
- }
433
- }
434
- return [3 /*break*/, 5];
435
- case 4:
436
- console.error('Failed to send message to Blumessage API:', response.status, response.statusText);
437
- // If token is invalid, clear it
438
- if (response.status === 401 || response.status === 403) {
439
- updateConversationToken(null);
440
- }
441
- errorMessage_1 = {
442
- id: (Date.now() + 1).toString(),
443
- content: "Sorry, I'm having trouble connecting right now. Please try again.",
444
- role: 'assistant',
445
- timestamp: Date.now(),
446
- };
447
- setMessages(function (prev) { return __spreadArray(__spreadArray([], prev, true), [errorMessage_1], false); });
448
- if (onError) {
449
- onError("Failed to send message: ".concat(response.status, " ").concat(response.statusText), "message_send");
450
- }
451
- _a.label = 5;
452
- case 5: return [3 /*break*/, 8];
453
- case 6:
454
- error_2 = _a.sent();
455
- console.error('Error sending message to Blumessage API:', error_2);
456
- errorMessage_2 = {
390
+ const handleSendMessage = async () => {
391
+ if (!inputValue.trim() || isLoading)
392
+ return;
393
+ const userMessage = {
394
+ id: Date.now().toString(),
395
+ content: inputValue.trim(),
396
+ role: 'user',
397
+ timestamp: Date.now()
398
+ };
399
+ // Add user message to UI immediately
400
+ setMessages(prev => [...prev, userMessage]);
401
+ const currentInput = inputValue.trim();
402
+ setInputValue('');
403
+ setIsLoading(true);
404
+ // Call the callback if provided
405
+ if (onUserMessage) {
406
+ onUserMessage(userMessage);
407
+ }
408
+ try {
409
+ // Call Blumessage API
410
+ const requestBody = {
411
+ message: currentInput,
412
+ };
413
+ // Include token if we have one
414
+ if (token) {
415
+ requestBody.token = token;
416
+ }
417
+ const response = await fetch('https://api.blumessage.com/api/v1/conversations', {
418
+ method: 'POST',
419
+ headers: {
420
+ 'Content-Type': 'application/json',
421
+ 'Authorization': `Bearer ${apiKey}`,
422
+ },
423
+ body: JSON.stringify(requestBody),
424
+ });
425
+ if (response.ok) {
426
+ const apiResponse = await response.json();
427
+ // Update token from response (for both first message and continuing conversations)
428
+ updateConversationToken(apiResponse.token);
429
+ // Find the assistant's response (the last message that's not from user)
430
+ const assistantMessages = apiResponse.messages.filter(msg => msg.role === 'assistant');
431
+ const latestAssistantMessage = assistantMessages[assistantMessages.length - 1];
432
+ if (latestAssistantMessage) {
433
+ // Add assistant's response to messages
434
+ const assistantResponse = {
457
435
  id: (Date.now() + 1).toString(),
458
- content: "Sorry, I'm having trouble connecting right now. Please try again.",
436
+ content: latestAssistantMessage.content,
459
437
  role: 'assistant',
460
- timestamp: Date.now(),
438
+ timestamp: latestAssistantMessage.timestamp,
461
439
  };
462
- setMessages(function (prev) { return __spreadArray(__spreadArray([], prev, true), [errorMessage_2], false); });
463
- if (onError) {
464
- onError("Error sending message: ".concat(error_2), "message_send");
440
+ setMessages(prev => [...prev, assistantResponse]);
441
+ if (onAssistantMessage) {
442
+ onAssistantMessage(assistantResponse);
465
443
  }
466
- return [3 /*break*/, 8];
467
- case 7:
468
- setIsLoading(false);
469
- return [7 /*endfinally*/];
470
- case 8: return [2 /*return*/];
444
+ }
471
445
  }
472
- });
473
- }); };
474
- var handleKeyPress = function (e) {
446
+ else {
447
+ console.error('Failed to send message to Blumessage API:', response.status, response.statusText);
448
+ // If token is invalid, clear it
449
+ if (response.status === 401 || response.status === 403) {
450
+ updateConversationToken(null);
451
+ }
452
+ // Add error message
453
+ const errorMessage = {
454
+ id: (Date.now() + 1).toString(),
455
+ content: "Sorry, I'm having trouble connecting right now. Please try again.",
456
+ role: 'assistant',
457
+ timestamp: Date.now(),
458
+ };
459
+ setMessages(prev => [...prev, errorMessage]);
460
+ if (onError) {
461
+ onError(`Failed to send message: ${response.status} ${response.statusText}`, "message_send");
462
+ }
463
+ }
464
+ }
465
+ catch (error) {
466
+ console.error('Error sending message to Blumessage API:', error);
467
+ // Add error message
468
+ const errorMessage = {
469
+ id: (Date.now() + 1).toString(),
470
+ content: "Sorry, I'm having trouble connecting right now. Please try again.",
471
+ role: 'assistant',
472
+ timestamp: Date.now(),
473
+ };
474
+ setMessages(prev => [...prev, errorMessage]);
475
+ if (onError) {
476
+ onError(`Error sending message: ${error}`, "message_send");
477
+ }
478
+ }
479
+ finally {
480
+ setIsLoading(false);
481
+ }
482
+ };
483
+ const handleKeyPress = (e) => {
475
484
  if (e.key === 'Enter' && !e.shiftKey && !isLoading) {
476
485
  e.preventDefault();
477
486
  handleSendMessage();
478
487
  }
479
488
  };
480
489
  // Auto-scroll to bottom when messages change
481
- useEffect(function () {
482
- var _a;
483
- (_a = messagesEndRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: 'smooth' });
490
+ (0, react_1.useEffect)(() => {
491
+ if (!disableAutoScroll) {
492
+ messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
493
+ }
484
494
  }, [messages]);
485
495
  // Auto-scroll to bottom when chat widget opens
486
- useEffect(function () {
487
- if (isOpen && floating) {
496
+ (0, react_1.useEffect)(() => {
497
+ if (isOpen && floating && !disableAutoScroll) {
488
498
  // Add a small delay to ensure the DOM is updated after the animation starts
489
- setTimeout(function () {
490
- var _a;
491
- (_a = messagesEndRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: 'smooth' });
499
+ setTimeout(() => {
500
+ messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
492
501
  }, 50);
493
502
  }
494
- }, [isOpen, floating]);
503
+ }, [isOpen, floating, disableAutoScroll]);
495
504
  // Handle opening the chat with animation
496
- var handleOpenChat = function () {
505
+ const handleOpenChat = () => {
497
506
  if (!isOpen && !isAnimating) {
498
507
  setIsAnimating(true);
499
508
  // Small delay to ensure smooth animation start
500
- setTimeout(function () {
509
+ setTimeout(() => {
501
510
  setIsOpen(true);
502
511
  // Call the callback after the chat is open
503
512
  if (onChatWidgetOpen) {
@@ -505,13 +514,13 @@ export var BlumessageChat = forwardRef(function (_a, ref) {
505
514
  }
506
515
  }, 10);
507
516
  // Animation duration
508
- setTimeout(function () {
517
+ setTimeout(() => {
509
518
  setIsAnimating(false);
510
519
  }, 300);
511
520
  }
512
521
  };
513
522
  // Handle closing the chat with animation
514
- var handleCloseChat = function () {
523
+ const handleCloseChat = () => {
515
524
  if (isOpen && !isAnimating) {
516
525
  setIsAnimating(true);
517
526
  setIsOpen(false);
@@ -522,155 +531,146 @@ export var BlumessageChat = forwardRef(function (_a, ref) {
522
531
  onChatWidgetClosed();
523
532
  }
524
533
  // Wait for animation to complete
525
- setTimeout(function () {
534
+ setTimeout(() => {
526
535
  setIsAnimating(false);
527
536
  }, 300);
528
537
  }
529
538
  };
530
539
  // Handle maximize/minimize toggle
531
- var handleToggleMaximize = function () {
540
+ const handleToggleMaximize = () => {
532
541
  setIsMaximized(!isMaximized);
533
542
  };
534
543
  // Get the icon component based on the icon prop
535
- var getIconComponent = function () {
544
+ const getIconComponent = () => {
536
545
  // More permissive icon matching - handle various naming patterns
537
- var iconName = icon.toLowerCase().replace(/[-_\s]/g, '');
546
+ const iconName = icon.toLowerCase().replace(/[-_\s]/g, '');
538
547
  // Try to match common icon patterns
539
548
  if (iconName.includes('message') || iconName.includes('chat')) {
540
549
  if (iconName.includes('square'))
541
- return MessageSquare;
542
- return MessageCircle;
550
+ return lucide_react_1.MessageSquare;
551
+ return lucide_react_1.MessageCircle;
543
552
  }
544
553
  if (iconName.includes('bot') || iconName.includes('robot'))
545
- return Bot;
554
+ return lucide_react_1.Bot;
546
555
  if (iconName.includes('phone') || iconName.includes('call'))
547
- return Phone;
556
+ return lucide_react_1.Phone;
548
557
  if (iconName.includes('mail') || iconName.includes('email'))
549
- return Mail;
558
+ return lucide_react_1.Mail;
550
559
  if (iconName.includes('headphone') || iconName.includes('support'))
551
- return Headphones;
560
+ return lucide_react_1.Headphones;
552
561
  if (iconName.includes('user')) {
553
562
  if (iconName.includes('users') || iconName.includes('group'))
554
- return Users;
555
- return User;
563
+ return lucide_react_1.Users;
564
+ return lucide_react_1.User;
556
565
  }
557
566
  if (iconName.includes('heart') || iconName.includes('like') || iconName.includes('love'))
558
- return Heart;
567
+ return lucide_react_1.Heart;
559
568
  if (iconName.includes('star') || iconName.includes('favorite'))
560
- return Star;
569
+ return lucide_react_1.Star;
561
570
  if (iconName.includes('zap') || iconName.includes('lightning') || iconName.includes('bolt'))
562
- return Zap;
571
+ return lucide_react_1.Zap;
563
572
  // Default fallback
564
- return MessageCircle;
573
+ return lucide_react_1.MessageCircle;
565
574
  };
566
575
  // Expose methods to parent component via ref
567
- useImperativeHandle(ref, function () { return ({
568
- sendMessage: function (message) { return __awaiter(void 0, void 0, void 0, function () {
569
- var userMessage, currentInput, requestBody, response, apiResponse, assistantMessages, latestAssistantMessage, assistantResponse_2, errorMessage_3, error_3, errorMessage_4;
570
- return __generator(this, function (_a) {
571
- switch (_a.label) {
572
- case 0:
573
- if (!message.trim() || isLoading)
574
- return [2 /*return*/];
575
- userMessage = {
576
- id: Date.now().toString(),
577
- content: message.trim(),
578
- role: 'user',
579
- timestamp: Date.now()
580
- };
581
- // Add user message to UI immediately
582
- setMessages(function (prev) { return __spreadArray(__spreadArray([], prev, true), [userMessage], false); });
583
- currentInput = message.trim();
584
- setIsLoading(true);
585
- // Call the callback if provided
586
- if (onUserMessage) {
587
- onUserMessage(userMessage);
588
- }
589
- _a.label = 1;
590
- case 1:
591
- _a.trys.push([1, 6, 7, 8]);
592
- requestBody = {
593
- message: currentInput,
594
- };
595
- // Include token if we have one
596
- if (token) {
597
- requestBody.token = token;
598
- }
599
- return [4 /*yield*/, fetch('https://api.blumessage.com/api/v1/conversations', {
600
- method: 'POST',
601
- headers: {
602
- 'Content-Type': 'application/json',
603
- 'Authorization': "Bearer ".concat(apiKey),
604
- },
605
- body: JSON.stringify(requestBody),
606
- })];
607
- case 2:
608
- response = _a.sent();
609
- if (!response.ok) return [3 /*break*/, 4];
610
- return [4 /*yield*/, response.json()];
611
- case 3:
612
- apiResponse = _a.sent();
613
- // Update token from response (for both first message and continuing conversations)
614
- updateConversationToken(apiResponse.token);
615
- assistantMessages = apiResponse.messages.filter(function (msg) { return msg.role === 'assistant'; });
616
- latestAssistantMessage = assistantMessages[assistantMessages.length - 1];
617
- if (latestAssistantMessage) {
618
- assistantResponse_2 = {
619
- id: (Date.now() + 1).toString(),
620
- content: latestAssistantMessage.content,
621
- role: 'assistant',
622
- timestamp: latestAssistantMessage.timestamp,
623
- };
624
- setMessages(function (prev) { return __spreadArray(__spreadArray([], prev, true), [assistantResponse_2], false); });
625
- if (onAssistantMessage) {
626
- onAssistantMessage(assistantResponse_2);
627
- }
628
- }
629
- return [3 /*break*/, 5];
630
- case 4:
631
- console.error('Failed to send message to Blumessage API:', response.status, response.statusText);
632
- // If token is invalid, clear it
633
- if (response.status === 401 || response.status === 403) {
634
- updateConversationToken(null);
635
- }
636
- errorMessage_3 = {
637
- id: (Date.now() + 1).toString(),
638
- content: "Sorry, I'm having trouble connecting right now. Please try again.",
639
- role: 'assistant',
640
- timestamp: Date.now(),
641
- };
642
- setMessages(function (prev) { return __spreadArray(__spreadArray([], prev, true), [errorMessage_3], false); });
643
- if (onError) {
644
- onError("Failed to send message: ".concat(response.status, " ").concat(response.statusText), "message_send");
645
- }
646
- _a.label = 5;
647
- case 5: return [3 /*break*/, 8];
648
- case 6:
649
- error_3 = _a.sent();
650
- console.error('Error sending message to Blumessage API:', error_3);
651
- errorMessage_4 = {
576
+ (0, react_1.useImperativeHandle)(ref, () => ({
577
+ sendMessage: async (message) => {
578
+ if (!message.trim() || isLoading)
579
+ return;
580
+ const userMessage = {
581
+ id: Date.now().toString(),
582
+ content: message.trim(),
583
+ role: 'user',
584
+ timestamp: Date.now()
585
+ };
586
+ // Add user message to UI immediately
587
+ setMessages(prev => [...prev, userMessage]);
588
+ const currentInput = message.trim();
589
+ setIsLoading(true);
590
+ // Call the callback if provided
591
+ if (onUserMessage) {
592
+ onUserMessage(userMessage);
593
+ }
594
+ try {
595
+ // Call Blumessage API
596
+ const requestBody = {
597
+ message: currentInput,
598
+ };
599
+ // Include token if we have one
600
+ if (token) {
601
+ requestBody.token = token;
602
+ }
603
+ const response = await fetch('https://api.blumessage.com/api/v1/conversations', {
604
+ method: 'POST',
605
+ headers: {
606
+ 'Content-Type': 'application/json',
607
+ 'Authorization': `Bearer ${apiKey}`,
608
+ },
609
+ body: JSON.stringify(requestBody),
610
+ });
611
+ if (response.ok) {
612
+ const apiResponse = await response.json();
613
+ // Update token from response (for both first message and continuing conversations)
614
+ updateConversationToken(apiResponse.token);
615
+ // Find the assistant's response (the last message that's not from user)
616
+ const assistantMessages = apiResponse.messages.filter(msg => msg.role === 'assistant');
617
+ const latestAssistantMessage = assistantMessages[assistantMessages.length - 1];
618
+ if (latestAssistantMessage) {
619
+ // Add assistant's response to messages
620
+ const assistantResponse = {
652
621
  id: (Date.now() + 1).toString(),
653
- content: "Sorry, I'm having trouble connecting right now. Please try again.",
622
+ content: latestAssistantMessage.content,
654
623
  role: 'assistant',
655
- timestamp: Date.now(),
624
+ timestamp: latestAssistantMessage.timestamp,
656
625
  };
657
- setMessages(function (prev) { return __spreadArray(__spreadArray([], prev, true), [errorMessage_4], false); });
658
- if (onError) {
659
- onError("Error sending message: ".concat(error_3), "message_send");
626
+ setMessages(prev => [...prev, assistantResponse]);
627
+ if (onAssistantMessage) {
628
+ onAssistantMessage(assistantResponse);
660
629
  }
661
- return [3 /*break*/, 8];
662
- case 7:
663
- setIsLoading(false);
664
- return [7 /*endfinally*/];
665
- case 8: return [2 /*return*/];
630
+ }
666
631
  }
667
- });
668
- }); },
669
- openChat: function () {
632
+ else {
633
+ console.error('Failed to send message to Blumessage API:', response.status, response.statusText);
634
+ // If token is invalid, clear it
635
+ if (response.status === 401 || response.status === 403) {
636
+ updateConversationToken(null);
637
+ }
638
+ // Add error message
639
+ const errorMessage = {
640
+ id: (Date.now() + 1).toString(),
641
+ content: "Sorry, I'm having trouble connecting right now. Please try again.",
642
+ role: 'assistant',
643
+ timestamp: Date.now(),
644
+ };
645
+ setMessages(prev => [...prev, errorMessage]);
646
+ if (onError) {
647
+ onError(`Failed to send message: ${response.status} ${response.statusText}`, "message_send");
648
+ }
649
+ }
650
+ }
651
+ catch (error) {
652
+ console.error('Error sending message to Blumessage API:', error);
653
+ // Add error message
654
+ const errorMessage = {
655
+ id: (Date.now() + 1).toString(),
656
+ content: "Sorry, I'm having trouble connecting right now. Please try again.",
657
+ role: 'assistant',
658
+ timestamp: Date.now(),
659
+ };
660
+ setMessages(prev => [...prev, errorMessage]);
661
+ if (onError) {
662
+ onError(`Error sending message: ${error}`, "message_send");
663
+ }
664
+ }
665
+ finally {
666
+ setIsLoading(false);
667
+ }
668
+ },
669
+ openChat: () => {
670
670
  if (!isOpen && !isAnimating) {
671
671
  setIsAnimating(true);
672
672
  // Small delay to ensure smooth animation start
673
- setTimeout(function () {
673
+ setTimeout(() => {
674
674
  setIsOpen(true);
675
675
  // Call the callback after the chat is open
676
676
  if (onChatWidgetOpen) {
@@ -678,12 +678,12 @@ export var BlumessageChat = forwardRef(function (_a, ref) {
678
678
  }
679
679
  }, 10);
680
680
  // Animation duration
681
- setTimeout(function () {
681
+ setTimeout(() => {
682
682
  setIsAnimating(false);
683
683
  }, 300);
684
684
  }
685
685
  },
686
- closeChat: function () {
686
+ closeChat: () => {
687
687
  if (isOpen && !isAnimating) {
688
688
  setIsAnimating(true);
689
689
  setIsOpen(false);
@@ -694,21 +694,21 @@ export var BlumessageChat = forwardRef(function (_a, ref) {
694
694
  onChatWidgetClosed();
695
695
  }
696
696
  // Wait for animation to complete
697
- setTimeout(function () {
697
+ setTimeout(() => {
698
698
  setIsAnimating(false);
699
699
  }, 300);
700
700
  }
701
701
  },
702
- clearConversation: function () {
702
+ clearConversation: () => {
703
703
  setMessages([]);
704
704
  updateConversationToken(null);
705
705
  },
706
- getMessages: function () { return messages; },
707
- getToken: function () { return token; },
708
- }); });
706
+ getMessages: () => messages,
707
+ getToken: () => token,
708
+ }));
709
709
  // Helper function to get position styles for floating button
710
- var getButtonPositionStyles = function () {
711
- var baseStyles = {
710
+ const getButtonPositionStyles = () => {
711
+ const baseStyles = {
712
712
  position: 'fixed',
713
713
  zIndex: 1000,
714
714
  opacity: isOpen ? 0 : 1,
@@ -717,32 +717,38 @@ export var BlumessageChat = forwardRef(function (_a, ref) {
717
717
  };
718
718
  // Mobile-specific positioning
719
719
  if (isMobile) {
720
- return __assign(__assign({}, baseStyles), { bottom: '20px', right: '20px', left: 'auto', top: 'auto' });
720
+ return {
721
+ ...baseStyles,
722
+ bottom: '20px',
723
+ right: '20px',
724
+ left: 'auto',
725
+ top: 'auto'
726
+ };
721
727
  }
722
728
  // Desktop positioning
723
729
  switch (buttonPosition) {
724
730
  case 'bottom-right':
725
- return __assign(__assign({}, baseStyles), { bottom: '24px', right: '24px' });
731
+ return { ...baseStyles, bottom: '24px', right: '24px' };
726
732
  case 'bottom-left':
727
- return __assign(__assign({}, baseStyles), { bottom: '24px', left: '24px' });
733
+ return { ...baseStyles, bottom: '24px', left: '24px' };
728
734
  case 'top-right':
729
- return __assign(__assign({}, baseStyles), { top: '24px', right: '24px' });
735
+ return { ...baseStyles, top: '24px', right: '24px' };
730
736
  case 'top-left':
731
- return __assign(__assign({}, baseStyles), { top: '24px', left: '24px' });
737
+ return { ...baseStyles, top: '24px', left: '24px' };
732
738
  default:
733
- return __assign(__assign({}, baseStyles), { bottom: '24px', right: '24px' });
739
+ return { ...baseStyles, bottom: '24px', right: '24px' };
734
740
  }
735
741
  };
736
742
  // Helper function to get position styles for floating chat window
737
- var getChatPositionStyles = function () {
738
- var getTransform = function () {
743
+ const getChatPositionStyles = () => {
744
+ const getTransform = () => {
739
745
  if (!isOpen) {
740
746
  // Slide down for bottom positions, slide up for top positions
741
- return (buttonPosition === null || buttonPosition === void 0 ? void 0 : buttonPosition.includes('bottom')) ? 'translateY(100%)' : 'translateY(-100%)';
747
+ return buttonPosition?.includes('bottom') ? 'translateY(100%)' : 'translateY(-100%)';
742
748
  }
743
749
  return 'translateY(0)';
744
750
  };
745
- var baseStyles = {
751
+ const baseStyles = {
746
752
  position: 'fixed',
747
753
  zIndex: 999,
748
754
  transform: getTransform(),
@@ -752,13 +758,21 @@ export var BlumessageChat = forwardRef(function (_a, ref) {
752
758
  };
753
759
  // Mobile-specific positioning (always fullscreen on mobile)
754
760
  if (isMobile) {
755
- return __assign(__assign({}, baseStyles), { top: '0', left: '0', right: '0', bottom: '0', transform: isOpen ? 'translateY(0)' : 'translateY(100%)', transformOrigin: 'bottom center' });
761
+ return {
762
+ ...baseStyles,
763
+ top: '0',
764
+ left: '0',
765
+ right: '0',
766
+ bottom: '0',
767
+ transform: isOpen ? 'translateY(0)' : 'translateY(100%)',
768
+ transformOrigin: 'bottom center',
769
+ };
756
770
  }
757
771
  // If fullScreen or maximized, override positioning to be centered and full screen
758
772
  if (fullScreen || isMaximized) {
759
773
  // Set transform origin and direction based on button position for proper animation
760
- var transformOrigin = 'center';
761
- var closedTransform = 'translateY(100%)';
774
+ let transformOrigin = 'center';
775
+ let closedTransform = 'translateY(100%)';
762
776
  switch (buttonPosition) {
763
777
  case 'bottom-right':
764
778
  transformOrigin = 'bottom right';
@@ -780,86 +794,94 @@ export var BlumessageChat = forwardRef(function (_a, ref) {
780
794
  transformOrigin = 'bottom right';
781
795
  closedTransform = 'translateY(100%)';
782
796
  }
783
- return __assign(__assign({}, baseStyles), { top: '20px', left: '20px', right: '20px', bottom: '20px', transform: isOpen ? 'translateY(0)' : closedTransform, transformOrigin: transformOrigin });
797
+ return {
798
+ ...baseStyles,
799
+ top: '20px',
800
+ left: '20px',
801
+ right: '20px',
802
+ bottom: '20px',
803
+ transform: isOpen ? 'translateY(0)' : closedTransform,
804
+ transformOrigin,
805
+ };
784
806
  }
785
807
  // Desktop positioning
786
808
  switch (buttonPosition) {
787
809
  case 'bottom-right':
788
- return __assign(__assign({}, baseStyles), { bottom: '24px', right: '24px', transformOrigin: 'bottom right' });
810
+ return { ...baseStyles, bottom: '24px', right: '24px', transformOrigin: 'bottom right' };
789
811
  case 'bottom-left':
790
- return __assign(__assign({}, baseStyles), { bottom: '24px', left: '24px', transformOrigin: 'bottom left' });
812
+ return { ...baseStyles, bottom: '24px', left: '24px', transformOrigin: 'bottom left' };
791
813
  case 'top-right':
792
- return __assign(__assign({}, baseStyles), { top: '24px', right: '24px', transformOrigin: 'top right' });
814
+ return { ...baseStyles, top: '24px', right: '24px', transformOrigin: 'top right' };
793
815
  case 'top-left':
794
- return __assign(__assign({}, baseStyles), { top: '24px', left: '24px', transformOrigin: 'top left' });
816
+ return { ...baseStyles, top: '24px', left: '24px', transformOrigin: 'top left' };
795
817
  default:
796
- return __assign(__assign({}, baseStyles), { bottom: '24px', right: '24px', transformOrigin: 'bottom right' });
818
+ return { ...baseStyles, bottom: '24px', right: '24px', transformOrigin: 'bottom right' };
797
819
  }
798
820
  };
799
- var renderMessage = function (message) {
800
- return (_jsx("div", { className: "blumessage-flex blumessage-gap-3 blumessage-mb-4 ".concat(message.role === 'user' ? 'blumessage-flex-row-reverse' : ''), children: _jsxs("div", { className: "blumessage-flex blumessage-flex-col blumessage-gap-1 blumessage-max-w-[80%]", children: [_jsx("div", { className: "blumessage-rounded-lg blumessage-px-4 blumessage-py-2 ".concat(message.role === 'user'
821
+ const renderMessage = (message) => {
822
+ return ((0, jsx_runtime_1.jsx)("div", { className: `blumessage-flex blumessage-gap-3 blumessage-mb-4 ${message.role === 'user' ? 'blumessage-flex-row-reverse' : ''}`, children: (0, jsx_runtime_1.jsxs)("div", { className: "blumessage-flex blumessage-flex-col blumessage-gap-1 blumessage-max-w-[80%]", children: [(0, jsx_runtime_1.jsx)("div", { className: `blumessage-rounded-lg blumessage-px-4 blumessage-py-2 ${message.role === 'user'
801
823
  ? 'blumessage-bg-gradient-to-r blumessage-from-blue-500 blumessage-to-purple-600 blumessage-text-white'
802
824
  : theme === 'light'
803
825
  ? 'blumessage-bg-gray-100'
804
- : 'blumessage-bg-gray-700'), children: message.role === 'assistant' ? (_jsx("div", { className: "blumessage-prose ".concat(theme === 'dark' ? 'blumessage-text-white' : 'blumessage-text-gray-900'), children: markdown ? (_jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], children: message.content }, "assistant-".concat(message.id))) : (_jsx("p", { className: "blumessage-text-sm blumessage-whitespace-pre-wrap", children: message.content })) })) : (_jsx("div", { className: "blumessage-text-sm blumessage-whitespace-pre-wrap blumessage-text-white", children: markdown ? (_jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], children: message.content }, "user-".concat(message.id))) : (_jsx("p", { className: "blumessage-text-sm blumessage-whitespace-pre-wrap", children: message.content })) })) }), showTimestamps && (_jsx("span", { className: "blumessage-text-xs blumessage-text-gray-500", children: formatTimestamp(message.timestamp) }))] }) }, message.id));
826
+ : 'blumessage-bg-gray-700'}`, children: message.role === 'assistant' ? ((0, jsx_runtime_1.jsx)("div", { className: `blumessage-prose ${theme === 'dark' ? 'blumessage-text-white' : 'blumessage-text-gray-900'}`, children: markdown ? ((0, jsx_runtime_1.jsx)(react_markdown_1.default, { remarkPlugins: [remark_gfm_1.default], children: message.content }, `assistant-${message.id}`)) : ((0, jsx_runtime_1.jsx)("p", { className: "blumessage-text-sm blumessage-whitespace-pre-wrap", children: message.content })) })) : ((0, jsx_runtime_1.jsx)("div", { className: "blumessage-text-sm blumessage-whitespace-pre-wrap blumessage-text-white", children: markdown ? ((0, jsx_runtime_1.jsx)(react_markdown_1.default, { remarkPlugins: [remark_gfm_1.default], children: message.content }, `user-${message.id}`)) : ((0, jsx_runtime_1.jsx)("p", { className: "blumessage-text-sm blumessage-whitespace-pre-wrap", children: message.content })) })) }), showTimestamps && ((0, jsx_runtime_1.jsx)("span", { className: "blumessage-text-xs blumessage-text-gray-500", children: formatTimestamp(message.timestamp) }))] }) }, message.id));
805
827
  };
806
828
  // Render chat window component
807
- var renderChatWindow = function () {
808
- var isFullscreenMode = fullScreen || isMaximized || isMobile;
809
- var chatContent = (_jsxs("div", { className: "shadow-2xl flex flex-col overflow-hidden border ".concat(isMobile ? 'blumessage-mobile-fullscreen' : '', " ").concat(theme === 'dark'
829
+ const renderChatWindow = () => {
830
+ const isFullscreenMode = fullScreen || isMaximized || isMobile;
831
+ const chatContent = ((0, jsx_runtime_1.jsxs)("div", { className: `shadow-2xl flex flex-col overflow-hidden border ${isMobile ? 'blumessage-mobile-fullscreen' : ''} ${theme === 'dark'
810
832
  ? 'bg-gray-900 border-gray-700'
811
- : 'bg-white border-black/10'), style: {
833
+ : 'bg-white border-black/10'}`, style: {
812
834
  width: isFullscreenMode ? '100%' : actualWidth,
813
835
  height: isFullscreenMode ? '100%' : actualHeight,
814
836
  fontFamily: 'system-ui, -apple-system, sans-serif',
815
837
  borderRadius: isMobile ? '0' : (isFullscreenMode ? '12px' : '24px')
816
- }, children: [_jsxs("div", { className: "border-b ".concat(theme === 'dark'
838
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { className: `border-b ${theme === 'dark'
817
839
  ? 'bg-gray-900 border-gray-700'
818
- : 'bg-white border-gray-100'), style: {
840
+ : 'bg-white border-gray-100'}`, style: {
819
841
  display: 'flex',
820
842
  alignItems: 'center',
821
843
  padding: isMobile ? '12px 16px' : '16px 24px'
822
- }, children: [_jsx("div", { className: "rounded-full flex items-center justify-center", style: {
844
+ }, children: [(0, jsx_runtime_1.jsx)("div", { className: "rounded-full flex items-center justify-center", style: {
823
845
  backgroundImage: primaryColor,
824
846
  width: isMobile ? '40px' : '48px',
825
847
  height: isMobile ? '40px' : '48px',
826
848
  marginRight: isMobile ? '16px' : '24px'
827
- }, children: React.createElement(getIconComponent(), {
849
+ }, children: react_1.default.createElement(getIconComponent(), {
828
850
  className: isMobile ? "w-5 h-5 text-white" : "w-6 h-6 text-white"
829
- }) }), _jsxs("div", { style: { flex: 1 }, children: [_jsx("div", { className: "".concat(isMobile ? 'text-base' : 'text-lg', " font-semibold m-0 leading-6 ").concat(theme === 'dark' ? 'text-gray-100' : 'text-gray-900'), children: name }), _jsx("div", { className: "text-sm m-0 leading-5 ".concat(theme === 'dark' ? 'text-gray-400' : 'text-gray-500'), children: subtitle })] }), floating && (_jsxs("div", { className: "flex items-center gap-1", children: [maximizeToggleButton && !isMobile && (_jsx("button", { onClick: handleToggleMaximize, className: "w-8 h-8 rounded-full flex items-center justify-center cursor-pointer transition-colors ".concat(theme === 'dark'
851
+ }) }), (0, jsx_runtime_1.jsxs)("div", { style: { flex: 1 }, children: [(0, jsx_runtime_1.jsx)("div", { className: `${isMobile ? 'text-base' : 'text-lg'} font-semibold m-0 leading-6 ${theme === 'dark' ? 'text-gray-100' : 'text-gray-900'}`, children: name }), (0, jsx_runtime_1.jsx)("div", { className: `text-sm m-0 leading-5 ${theme === 'dark' ? 'text-gray-400' : 'text-gray-500'}`, children: subtitle })] }), floating && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1", children: [maximizeToggleButton && !isMobile && ((0, jsx_runtime_1.jsx)("button", { onClick: handleToggleMaximize, className: `w-8 h-8 rounded-full flex items-center justify-center cursor-pointer transition-colors ${theme === 'dark'
830
852
  ? 'hover:bg-gray-800 text-gray-400 hover:text-gray-200'
831
- : 'hover:bg-gray-100 text-gray-500 hover:text-gray-700'), children: isMaximized ? _jsx(Minimize2, { className: "w-4 h-4" }) : _jsx(Maximize, { className: "w-4 h-4" }) })), _jsx("button", { onClick: handleCloseChat, className: "w-8 h-8 rounded-full flex items-center justify-center cursor-pointer transition-colors ".concat(theme === 'dark'
853
+ : 'hover:bg-gray-100 text-gray-500 hover:text-gray-700'}`, children: isMaximized ? (0, jsx_runtime_1.jsx)(lucide_react_1.Minimize2, { className: "w-4 h-4" }) : (0, jsx_runtime_1.jsx)(lucide_react_1.Maximize, { className: "w-4 h-4" }) })), (0, jsx_runtime_1.jsx)("button", { onClick: handleCloseChat, className: `w-8 h-8 rounded-full flex items-center justify-center cursor-pointer transition-colors ${theme === 'dark'
832
854
  ? 'hover:bg-gray-800 text-gray-400 hover:text-gray-200'
833
- : 'hover:bg-gray-100 text-gray-500 hover:text-gray-700'), children: _jsx(X, { className: "w-4 h-4" }) })] }))] }), _jsxs("div", { className: "flex-1 overflow-y-auto ".concat(theme === 'dark' ? 'bg-gray-800' : 'bg-gray-50'), style: { padding: isMobile ? '12px 16px' : '16px 24px' }, children: [messages.map(function (message) { return (_jsx("div", { className: "flex ".concat(message.role === 'user' ? 'justify-end' : 'justify-start', " mb-4"), children: _jsx("div", { className: "".concat(isMobile ? 'max-w-[85%]' : 'max-w-[80%]', " inline-block ").concat(message.role === 'user' ? '' : 'text-left'), children: _jsxs("div", { className: "inline-block px-4 py-3 rounded-2xl text-sm leading-6 text-left ".concat(message.role === 'user'
855
+ : 'hover:bg-gray-100 text-gray-500 hover:text-gray-700'}`, children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-4 h-4" }) })] }))] }), (0, jsx_runtime_1.jsxs)("div", { className: `flex-1 overflow-y-auto ${theme === 'dark' ? 'bg-gray-800' : 'bg-gray-50'}`, style: { padding: isMobile ? '12px 16px' : '16px 24px' }, children: [messages.map((message) => ((0, jsx_runtime_1.jsx)("div", { className: `flex ${message.role === 'user' ? 'justify-end' : 'justify-start'} mb-4`, children: (0, jsx_runtime_1.jsx)("div", { className: `${isMobile ? 'max-w-[85%]' : 'max-w-[80%]'} inline-block ${message.role === 'user' ? '' : 'text-left'}`, children: (0, jsx_runtime_1.jsxs)("div", { className: `inline-block px-4 py-3 rounded-2xl text-sm leading-6 text-left ${message.role === 'user'
834
856
  ? 'text-white'
835
857
  : theme === 'dark'
836
858
  ? 'bg-gray-700 text-gray-100 border border-gray-600 shadow-sm'
837
- : 'bg-white text-gray-800 border border-gray-200 shadow-sm'), style: message.role === 'user' ? { backgroundImage: primaryColor } : {}, children: [message.role === 'assistant' ? (markdown ? (_jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], children: message.content }, "assistant-".concat(message.id))) : (_jsx("div", { className: "whitespace-pre-wrap", children: message.content }))) : (_jsx("div", { className: "inline-block", children: markdown ? (_jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], children: message.content }, "user-".concat(message.id))) : (_jsx("div", { className: "whitespace-pre-wrap", children: message.content })) })), showTimestamps && (_jsx("div", { className: "text-[10px] mt-1 opacity-75 ".concat(message.role === 'user'
859
+ : 'bg-white text-gray-800 border border-gray-200 shadow-sm'}`, style: message.role === 'user' ? { backgroundImage: primaryColor } : {}, children: [message.role === 'assistant' ? (markdown ? ((0, jsx_runtime_1.jsx)(react_markdown_1.default, { remarkPlugins: [remark_gfm_1.default], children: message.content }, `assistant-${message.id}`)) : ((0, jsx_runtime_1.jsx)("div", { className: "whitespace-pre-wrap", children: message.content }))) : ((0, jsx_runtime_1.jsx)("div", { className: "inline-block", children: markdown ? ((0, jsx_runtime_1.jsx)(react_markdown_1.default, { remarkPlugins: [remark_gfm_1.default], children: message.content }, `user-${message.id}`)) : ((0, jsx_runtime_1.jsx)("div", { className: "whitespace-pre-wrap", children: message.content })) })), showTimestamps && ((0, jsx_runtime_1.jsx)("div", { className: `text-[10px] mt-1 opacity-75 ${message.role === 'user'
838
860
  ? 'text-white/75'
839
861
  : theme === 'dark'
840
862
  ? 'text-gray-400'
841
- : 'text-gray-500'), style: {
863
+ : 'text-gray-500'}`, style: {
842
864
  textAlign: message.role === 'user' ? 'right' : 'left'
843
- }, children: formatTimestamp(message.timestamp) }))] }) }) }, message.id)); }), isLoading && (_jsx("div", { className: "flex justify-start mb-4", children: _jsx("div", { className: "px-4 py-3 rounded-2xl ".concat(isMobile ? 'max-w-[85%]' : 'max-w-[80%]', " text-sm leading-6 shadow-sm ").concat(theme === 'dark'
865
+ }, children: formatTimestamp(message.timestamp) }))] }) }) }, message.id))), isLoading && ((0, jsx_runtime_1.jsx)("div", { className: "flex justify-start mb-4", children: (0, jsx_runtime_1.jsx)("div", { className: `px-4 py-3 rounded-2xl ${isMobile ? 'max-w-[85%]' : 'max-w-[80%]'} text-sm leading-6 shadow-sm ${theme === 'dark'
844
866
  ? 'bg-gray-700 text-gray-100 border border-gray-600'
845
- : 'bg-white text-gray-800 border border-gray-200'), children: _jsx("div", { className: "".concat(theme === 'dark' ? 'text-gray-300' : 'text-gray-600'), style: { fontStyle: 'italic' }, children: typingText }) }) })), messages.length === 0 && !isLoading && (_jsx("div", { className: "text-center text-sm py-8 ".concat(theme === 'dark' ? 'text-gray-400' : 'text-gray-500'), children: emptyStateText })), _jsx("div", { ref: messagesEndRef })] }), _jsx("div", { className: "border-t ".concat(theme === 'dark'
867
+ : 'bg-white text-gray-800 border border-gray-200'}`, children: (0, jsx_runtime_1.jsx)("div", { className: `${theme === 'dark' ? 'text-gray-300' : 'text-gray-600'}`, style: { fontStyle: 'italic' }, children: typingText }) }) })), messages.length === 0 && !isLoading && ((0, jsx_runtime_1.jsx)("div", { className: `text-center text-sm py-8 ${theme === 'dark' ? 'text-gray-400' : 'text-gray-500'}`, children: emptyStateText })), (0, jsx_runtime_1.jsx)("div", { ref: messagesEndRef })] }), (0, jsx_runtime_1.jsx)("div", { className: `border-t ${theme === 'dark'
846
868
  ? 'bg-gray-900 border-gray-700'
847
- : 'bg-white border-gray-100'), style: { padding: isMobile ? '12px 16px' : '16px 24px' }, children: _jsxs("div", { className: "flex items-center rounded-2xl px-4 py-3 border ".concat(theme === 'dark'
869
+ : 'bg-white border-gray-100'}`, style: { padding: isMobile ? '12px 16px' : '16px 24px' }, children: (0, jsx_runtime_1.jsxs)("div", { className: `flex items-center rounded-2xl px-4 py-3 border ${theme === 'dark'
848
870
  ? 'bg-gray-800 border-gray-600'
849
- : 'bg-gray-50 border-gray-200'), children: [_jsx("textarea", { className: "flex-1 border-none bg-transparent outline-none text-sm font-inherit resize-none ".concat(theme === 'dark' ? 'text-gray-100' : 'text-gray-700'), placeholder: placeholder, value: inputValue, onChange: function (e) { return setInputValue(e.target.value); }, onKeyDown: handleKeyPress, rows: 1, style: {
871
+ : 'bg-gray-50 border-gray-200'}`, children: [(0, jsx_runtime_1.jsx)("textarea", { className: `flex-1 border-none bg-transparent outline-none text-sm font-inherit resize-none ${theme === 'dark' ? 'text-gray-100' : 'text-gray-700'}`, placeholder: placeholder, value: inputValue, onChange: (e) => setInputValue(e.target.value), onKeyDown: handleKeyPress, rows: 1, style: {
850
872
  minHeight: '20px',
851
873
  maxHeight: isMobile ? '100px' : '120px',
852
874
  overflowY: inputValue.split('\n').length > 4 ? 'auto' : 'hidden',
853
875
  lineHeight: '1.5',
854
876
  paddingTop: '2px',
855
877
  paddingBottom: '2px'
856
- }, onInput: function (e) {
857
- var target = e.target;
878
+ }, onInput: (e) => {
879
+ const target = e.target;
858
880
  target.style.height = 'auto';
859
881
  target.style.height = Math.min(target.scrollHeight, isMobile ? 100 : 120) + 'px';
860
- } }), _jsx("button", { className: "w-8 h-8 rounded-full border-none flex items-center justify-center cursor-pointer ml-2 text-white transition-all disabled:opacity-50 disabled:cursor-not-allowed", style: { backgroundImage: primaryColor }, onClick: handleSendMessage, disabled: !inputValue.trim() || isLoading, children: isLoading ? (_jsx(Loader2, { className: "w-4 h-4 blumessage-animate-spin" })) : (_jsx(Send, { className: "w-4 h-4" })) })] }) })] }));
882
+ } }), (0, jsx_runtime_1.jsx)("button", { className: "w-8 h-8 rounded-full border-none flex items-center justify-center cursor-pointer ml-2 text-white transition-all disabled:opacity-50 disabled:cursor-not-allowed", style: { backgroundImage: primaryColor }, onClick: handleSendMessage, disabled: !inputValue.trim() || isLoading, children: isLoading ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "w-4 h-4 blumessage-animate-spin" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.Send, { className: "w-4 h-4" })) })] }) })] }));
861
883
  if (floating) {
862
- return (_jsx("div", { style: getChatPositionStyles(), children: chatContent }));
884
+ return ((0, jsx_runtime_1.jsx)("div", { style: getChatPositionStyles(), children: chatContent }));
863
885
  }
864
886
  return chatContent;
865
887
  };
@@ -868,62 +890,62 @@ export var BlumessageChat = forwardRef(function (_a, ref) {
868
890
  return null;
869
891
  }
870
892
  if (error) {
871
- var isFullscreenMode = fullScreen || isMaximized || isMobile;
872
- var errorContent = (_jsxs("div", { className: "shadow-2xl flex flex-col overflow-hidden border ".concat(isMobile ? 'blumessage-mobile-fullscreen' : '', " ").concat(theme === 'dark'
893
+ const isFullscreenMode = fullScreen || isMaximized || isMobile;
894
+ const errorContent = ((0, jsx_runtime_1.jsxs)("div", { className: `shadow-2xl flex flex-col overflow-hidden border ${isMobile ? 'blumessage-mobile-fullscreen' : ''} ${theme === 'dark'
873
895
  ? 'bg-gray-900 border-gray-700'
874
- : 'bg-white border-black/10'), style: {
896
+ : 'bg-white border-black/10'}`, style: {
875
897
  width: isFullscreenMode ? '100%' : actualWidth,
876
898
  height: isFullscreenMode ? '100%' : actualHeight,
877
899
  fontFamily: 'system-ui, -apple-system, sans-serif',
878
900
  borderRadius: isMobile ? '0' : (isFullscreenMode ? '12px' : '24px')
879
- }, children: [_jsxs("div", { className: "flex items-center border-b ".concat(theme === 'dark'
901
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { className: `flex items-center border-b ${theme === 'dark'
880
902
  ? 'bg-gray-900 border-gray-700'
881
- : 'bg-white border-gray-100'), style: { padding: isMobile ? '12px 16px' : '16px 24px' }, children: [_jsx("div", { className: "rounded-full flex items-center justify-center", style: {
903
+ : 'bg-white border-gray-100'}`, style: { padding: isMobile ? '12px 16px' : '16px 24px' }, children: [(0, jsx_runtime_1.jsx)("div", { className: "rounded-full flex items-center justify-center", style: {
882
904
  backgroundColor: '#ef4444',
883
905
  width: isMobile ? '40px' : '48px',
884
906
  height: isMobile ? '40px' : '48px',
885
907
  marginRight: isMobile ? '16px' : '24px'
886
- }, children: _jsx(AlertTriangle, { className: isMobile ? "w-5 h-5 text-white" : "w-6 h-6 text-white" }) }), _jsxs("div", { className: "flex-1", children: [_jsx("div", { className: "".concat(isMobile ? 'text-base' : 'text-lg', " font-semibold m-0 leading-6 ").concat(theme === 'dark' ? 'text-gray-100' : 'text-gray-900'), children: "Connection Error" }), _jsx("div", { className: "text-sm m-0 leading-5 ".concat(theme === 'dark' ? 'text-gray-400' : 'text-gray-500'), children: "Unable to connect" })] }), floating && (_jsxs("div", { className: "flex items-center gap-1", children: [maximizeToggleButton && !isMobile && (_jsx("button", { onClick: handleToggleMaximize, className: "w-8 h-8 rounded-full flex items-center justify-center cursor-pointer transition-colors ".concat(theme === 'dark'
908
+ }, children: (0, jsx_runtime_1.jsx)(lucide_react_1.AlertTriangle, { className: isMobile ? "w-5 h-5 text-white" : "w-6 h-6 text-white" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1", children: [(0, jsx_runtime_1.jsx)("div", { className: `${isMobile ? 'text-base' : 'text-lg'} font-semibold m-0 leading-6 ${theme === 'dark' ? 'text-gray-100' : 'text-gray-900'}`, children: "Connection Error" }), (0, jsx_runtime_1.jsx)("div", { className: `text-sm m-0 leading-5 ${theme === 'dark' ? 'text-gray-400' : 'text-gray-500'}`, children: "Unable to connect" })] }), floating && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1", children: [maximizeToggleButton && !isMobile && ((0, jsx_runtime_1.jsx)("button", { onClick: handleToggleMaximize, className: `w-8 h-8 rounded-full flex items-center justify-center cursor-pointer transition-colors ${theme === 'dark'
887
909
  ? 'hover:bg-gray-800 text-gray-400 hover:text-gray-200'
888
- : 'hover:bg-gray-100 text-gray-500 hover:text-gray-700'), children: isMaximized ? _jsx(Minimize2, { className: "w-4 h-4" }) : _jsx(Maximize, { className: "w-4 h-4" }) })), _jsx("button", { onClick: handleCloseChat, className: "w-8 h-8 rounded-full flex items-center justify-center cursor-pointer transition-colors ".concat(theme === 'dark'
910
+ : 'hover:bg-gray-100 text-gray-500 hover:text-gray-700'}`, children: isMaximized ? (0, jsx_runtime_1.jsx)(lucide_react_1.Minimize2, { className: "w-4 h-4" }) : (0, jsx_runtime_1.jsx)(lucide_react_1.Maximize, { className: "w-4 h-4" }) })), (0, jsx_runtime_1.jsx)("button", { onClick: handleCloseChat, className: `w-8 h-8 rounded-full flex items-center justify-center cursor-pointer transition-colors ${theme === 'dark'
889
911
  ? 'hover:bg-gray-800 text-gray-400 hover:text-gray-200'
890
- : 'hover:bg-gray-100 text-gray-500 hover:text-gray-700'), children: _jsx(X, { className: "w-4 h-4" }) })] }))] }), _jsx("div", { className: "flex-1 overflow-y-auto ".concat(theme === 'dark' ? 'bg-gray-800' : 'bg-gray-50'), style: { padding: isMobile ? '12px 16px' : '16px 24px' }, children: _jsx("div", { className: "flex justify-start", children: _jsx("div", { className: "px-4 py-3 rounded-2xl ".concat(isMobile ? 'max-w-[85%]' : 'max-w-[80%]', " text-sm leading-6 shadow-sm ").concat(theme === 'dark'
912
+ : 'hover:bg-gray-100 text-gray-500 hover:text-gray-700'}`, children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-4 h-4" }) })] }))] }), (0, jsx_runtime_1.jsx)("div", { className: `flex-1 overflow-y-auto ${theme === 'dark' ? 'bg-gray-800' : 'bg-gray-50'}`, style: { padding: isMobile ? '12px 16px' : '16px 24px' }, children: (0, jsx_runtime_1.jsx)("div", { className: "flex justify-start", children: (0, jsx_runtime_1.jsx)("div", { className: `px-4 py-3 rounded-2xl ${isMobile ? 'max-w-[85%]' : 'max-w-[80%]'} text-sm leading-6 shadow-sm ${theme === 'dark'
891
913
  ? 'bg-gray-700 text-gray-100 border border-gray-600'
892
- : 'bg-white text-gray-800 border border-gray-200'), children: error }) }) })] }));
914
+ : 'bg-white text-gray-800 border border-gray-200'}`, children: error }) }) })] }));
893
915
  if (floating) {
894
- return (_jsxs(_Fragment, { children: [_jsxs("button", { onClick: handleOpenChat, className: "text-white rounded-full shadow-lg transition-all duration-200 flex items-center justify-center gap-2 ".concat(isMobile ? 'blumessage-mobile-button' : '', " ").concat(buttonText ? 'px-4 py-3 h-12' : 'w-14 h-14'), style: __assign(__assign(__assign({}, getButtonPositionStyles()), buttonStyle), { backgroundImage: primaryColor }), children: [React.createElement(getIconComponent(), { className: "w-6 h-6" }), buttonText && !isMobile && _jsx("span", { className: "text-sm font-medium whitespace-nowrap", children: buttonText })] }), _jsx("div", { style: getChatPositionStyles(), children: errorContent })] }));
916
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("button", { onClick: handleOpenChat, className: `text-white rounded-full shadow-lg transition-all duration-200 flex items-center justify-center gap-2 ${isMobile ? 'blumessage-mobile-button' : ''} ${buttonText ? 'px-4 py-3 h-12' : 'w-14 h-14'}`, style: { ...getButtonPositionStyles(), ...buttonStyle, backgroundImage: primaryColor }, children: [react_1.default.createElement(getIconComponent(), { className: "w-6 h-6" }), buttonText && !isMobile && (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium whitespace-nowrap", children: buttonText })] }), (0, jsx_runtime_1.jsx)("div", { style: getChatPositionStyles(), children: errorContent })] }));
895
917
  }
896
918
  return errorContent;
897
919
  }
898
920
  if (!isInitialized) {
899
- var isFullscreenMode = fullScreen || isMaximized || isMobile;
900
- var loadingContent = (_jsxs("div", { className: "shadow-2xl flex flex-col overflow-hidden border ".concat(isMobile ? 'blumessage-mobile-fullscreen' : '', " ").concat(theme === 'dark'
921
+ const isFullscreenMode = fullScreen || isMaximized || isMobile;
922
+ const loadingContent = ((0, jsx_runtime_1.jsxs)("div", { className: `shadow-2xl flex flex-col overflow-hidden border ${isMobile ? 'blumessage-mobile-fullscreen' : ''} ${theme === 'dark'
901
923
  ? 'bg-gray-900 border-gray-700'
902
- : 'bg-white border-black/10'), style: {
924
+ : 'bg-white border-black/10'}`, style: {
903
925
  width: isFullscreenMode ? '100%' : actualWidth,
904
926
  height: isFullscreenMode ? '100%' : actualHeight,
905
927
  fontFamily: 'system-ui, -apple-system, sans-serif',
906
928
  borderRadius: isMobile ? '0' : (isFullscreenMode ? '12px' : '24px')
907
- }, children: [_jsxs("div", { className: "flex items-center border-b ".concat(theme === 'dark'
929
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { className: `flex items-center border-b ${theme === 'dark'
908
930
  ? 'bg-gray-900 border-gray-700'
909
- : 'bg-white border-gray-100'), style: { padding: isMobile ? '12px 16px' : '16px 24px' }, children: [_jsx("div", { className: "rounded-full flex items-center justify-center", style: {
931
+ : 'bg-white border-gray-100'}`, style: { padding: isMobile ? '12px 16px' : '16px 24px' }, children: [(0, jsx_runtime_1.jsx)("div", { className: "rounded-full flex items-center justify-center", style: {
910
932
  backgroundImage: primaryColor,
911
933
  width: isMobile ? '40px' : '48px',
912
934
  height: isMobile ? '40px' : '48px',
913
935
  marginRight: isMobile ? '16px' : '24px'
914
- }, children: _jsx(Loader2, { className: isMobile ? "w-5 h-5 text-white animate-spin" : "w-6 h-6 text-white animate-spin" }) }), _jsxs("div", { className: "flex-1", children: [_jsx("div", { className: "".concat(isMobile ? 'text-base' : 'text-lg', " font-semibold m-0 leading-6 ").concat(theme === 'dark' ? 'text-gray-100' : 'text-gray-900'), children: name }), _jsx("div", { className: "text-sm m-0 leading-5 ".concat(theme === 'dark' ? 'text-gray-400' : 'text-gray-500'), children: subtitle })] }), floating && (_jsxs("div", { className: "flex items-center gap-1", children: [maximizeToggleButton && !isMobile && (_jsx("button", { onClick: handleToggleMaximize, className: "w-8 h-8 rounded-full flex items-center justify-center cursor-pointer transition-colors ".concat(theme === 'dark'
936
+ }, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: isMobile ? "w-5 h-5 text-white animate-spin" : "w-6 h-6 text-white animate-spin" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1", children: [(0, jsx_runtime_1.jsx)("div", { className: `${isMobile ? 'text-base' : 'text-lg'} font-semibold m-0 leading-6 ${theme === 'dark' ? 'text-gray-100' : 'text-gray-900'}`, children: name }), (0, jsx_runtime_1.jsx)("div", { className: `text-sm m-0 leading-5 ${theme === 'dark' ? 'text-gray-400' : 'text-gray-500'}`, children: subtitle })] }), floating && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1", children: [maximizeToggleButton && !isMobile && ((0, jsx_runtime_1.jsx)("button", { onClick: handleToggleMaximize, className: `w-8 h-8 rounded-full flex items-center justify-center cursor-pointer transition-colors ${theme === 'dark'
915
937
  ? 'hover:bg-gray-800 text-gray-400 hover:text-gray-200'
916
- : 'hover:bg-gray-100 text-gray-500 hover:text-gray-700'), children: isMaximized ? _jsx(Minimize2, { className: "w-4 h-4" }) : _jsx(Maximize, { className: "w-4 h-4" }) })), _jsx("button", { onClick: handleCloseChat, className: "w-8 h-8 rounded-full flex items-center justify-center cursor-pointer transition-colors ".concat(theme === 'dark'
938
+ : 'hover:bg-gray-100 text-gray-500 hover:text-gray-700'}`, children: isMaximized ? (0, jsx_runtime_1.jsx)(lucide_react_1.Minimize2, { className: "w-4 h-4" }) : (0, jsx_runtime_1.jsx)(lucide_react_1.Maximize, { className: "w-4 h-4" }) })), (0, jsx_runtime_1.jsx)("button", { onClick: handleCloseChat, className: `w-8 h-8 rounded-full flex items-center justify-center cursor-pointer transition-colors ${theme === 'dark'
917
939
  ? 'hover:bg-gray-800 text-gray-400 hover:text-gray-200'
918
- : 'hover:bg-gray-100 text-gray-500 hover:text-gray-700'), children: _jsx(X, { className: "w-4 h-4" }) })] }))] }), _jsx("div", { className: "flex-1 overflow-y-auto ".concat(theme === 'dark' ? 'bg-gray-800' : 'bg-gray-50'), style: { padding: isMobile ? '12px 16px' : '16px 24px' }, children: _jsx("div", { className: "text-center text-sm py-8 ".concat(theme === 'dark' ? 'text-gray-400' : 'text-gray-500'), children: "Ready to chat..." }) })] }));
940
+ : 'hover:bg-gray-100 text-gray-500 hover:text-gray-700'}`, children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-4 h-4" }) })] }))] }), (0, jsx_runtime_1.jsx)("div", { className: `flex-1 overflow-y-auto ${theme === 'dark' ? 'bg-gray-800' : 'bg-gray-50'}`, style: { padding: isMobile ? '12px 16px' : '16px 24px' }, children: (0, jsx_runtime_1.jsx)("div", { className: `text-center text-sm py-8 ${theme === 'dark' ? 'text-gray-400' : 'text-gray-500'}`, children: "Ready to chat..." }) })] }));
919
941
  if (floating) {
920
- return (_jsxs(_Fragment, { children: [_jsxs("button", { onClick: handleOpenChat, className: "text-white rounded-full shadow-lg transition-all duration-200 flex items-center justify-center gap-2 ".concat(isMobile ? 'blumessage-mobile-button' : '', " ").concat(buttonText ? 'px-4 py-3 h-12' : 'w-14 h-14'), style: __assign(__assign(__assign({}, getButtonPositionStyles()), buttonStyle), { backgroundImage: primaryColor }), children: [React.createElement(getIconComponent(), { className: "w-6 h-6" }), buttonText && !isMobile && _jsx("span", { className: "text-sm font-medium whitespace-nowrap", children: buttonText })] }), _jsx("div", { style: getChatPositionStyles(), children: loadingContent })] }));
942
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("button", { onClick: handleOpenChat, className: `text-white rounded-full shadow-lg transition-all duration-200 flex items-center justify-center gap-2 ${isMobile ? 'blumessage-mobile-button' : ''} ${buttonText ? 'px-4 py-3 h-12' : 'w-14 h-14'}`, style: { ...getButtonPositionStyles(), ...buttonStyle, backgroundImage: primaryColor }, children: [react_1.default.createElement(getIconComponent(), { className: "w-6 h-6" }), buttonText && !isMobile && (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium whitespace-nowrap", children: buttonText })] }), (0, jsx_runtime_1.jsx)("div", { style: getChatPositionStyles(), children: loadingContent })] }));
921
943
  }
922
944
  return loadingContent;
923
945
  }
924
946
  // Main render for initialized state
925
947
  if (floating) {
926
- return (_jsxs(_Fragment, { children: [_jsxs("button", { onClick: handleOpenChat, className: "text-white rounded-full shadow-lg transition-all duration-200 flex items-center justify-center gap-2 ".concat(isMobile ? 'blumessage-mobile-button' : '', " ").concat(buttonText ? 'px-4 py-3 h-12' : 'w-14 h-14'), style: __assign(__assign(__assign({}, getButtonPositionStyles()), buttonStyle), { backgroundImage: primaryColor }), children: [React.createElement(getIconComponent(), { className: "w-6 h-6" }), buttonText && !isMobile && _jsx("span", { className: "text-sm font-medium whitespace-nowrap", children: buttonText })] }), renderChatWindow()] }));
948
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("button", { onClick: handleOpenChat, className: `text-white rounded-full shadow-lg transition-all duration-200 flex items-center justify-center gap-2 ${isMobile ? 'blumessage-mobile-button' : ''} ${buttonText ? 'px-4 py-3 h-12' : 'w-14 h-14'}`, style: { ...getButtonPositionStyles(), ...buttonStyle, backgroundImage: primaryColor }, children: [react_1.default.createElement(getIconComponent(), { className: "w-6 h-6" }), buttonText && !isMobile && (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium whitespace-nowrap", children: buttonText })] }), renderChatWindow()] }));
927
949
  }
928
950
  return renderChatWindow();
929
951
  });