aizek-chatbot 1.0.9 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -5,6 +5,7 @@ var jsxRuntime = require('react/jsx-runtime');
5
5
  var OpenAI = require('openai');
6
6
  var ReactMarkdown = require('react-markdown');
7
7
  var remarkGfm = require('remark-gfm');
8
+ var DOMPurify = require('dompurify');
8
9
 
9
10
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
11
 
@@ -30,6 +31,7 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
30
31
  var OpenAI__default = /*#__PURE__*/_interopDefault(OpenAI);
31
32
  var ReactMarkdown__default = /*#__PURE__*/_interopDefault(ReactMarkdown);
32
33
  var remarkGfm__default = /*#__PURE__*/_interopDefault(remarkGfm);
34
+ var DOMPurify__default = /*#__PURE__*/_interopDefault(DOMPurify);
33
35
 
34
36
  // src/utils/cx.ts
35
37
  function cx(...args) {
@@ -144,8 +146,6 @@ var useChatbot = (options = {}) => {
144
146
  const getHtmlUiInstructions = (config2) => {
145
147
  const headerColor = config2?.headerBackground || "#f5f5f5";
146
148
  const accentColor = config2?.buttonBackground || "#007bff";
147
- const companyName = config2?.companyName || "AI Assistant";
148
- const companyLogo = config2?.companyLogo || "\u{1F916}";
149
149
  return `
150
150
  You are a helpful assistant that creates UI using ONLY HTML tags.
151
151
 
@@ -154,27 +154,23 @@ Your task:
154
154
  - Render your response as a small HTML layout (card OR table OR mini-table).
155
155
  - Use inline CSS styles.
156
156
  - Use a clean, light (white-based) theme.
157
- - Use branding and colors from options.config.
157
+ - Use colors from options.config (headerBackground, buttonBackground).
158
158
  - Return ONLY raw HTML (no markdown, no backticks, no JSON, no explanations).
159
159
 
160
160
  ====================
161
- THEME & BRANDING (from options.config)
161
+ THEME (from options.config)
162
162
  ====================
163
163
  The chat widget configuration provides:
164
164
 
165
165
  - Header Background Color: ${headerColor}
166
166
  - Button / Accent Color: ${accentColor}
167
- - Company Name: ${companyName}
168
- - Company Logo: ${companyLogo}
169
167
 
170
168
  How to use these:
171
169
  - Use Header Background Color mainly for top headers, title strips, or main highlight areas.
172
- - Use Button / Accent Color for important accents: borders, highlights, small badges, table headers, key text highlights, links, etc.
170
+ - Use Button / Accent Color for important accents: borders, highlights, badges, table headers, key text highlights, links, etc.
173
171
  - Use a white or very light background for main surfaces.
174
172
  - Text color should generally be dark (#111\u2013#333) for readability.
175
173
 
176
- Do NOT create real interactive buttons. You can visually style elements using the accent color, but you must NOT use <button>.
177
-
178
174
  ====================
179
175
  ALLOWED / FORBIDDEN TAGS
180
176
  ====================
@@ -193,7 +189,10 @@ You may use ANY NON-INTERACTIVE HTML element, for example:
193
189
  - Links (non-interactive navigation style only):
194
190
  <a>
195
191
 
196
- FORBIDDEN (NEVER USE):
192
+ GENERAL RULE:
193
+ - In NORMAL responses, you MUST NOT use <button>.
194
+
195
+ FORBIDDEN (NORMAL MODE):
197
196
  - <button>, <input>, <textarea>, <select>, <option>, <form>, <label>
198
197
  - <details>, <summary>, <dialog>
199
198
  - <video> or <audio> with controls for user interaction
@@ -240,15 +239,11 @@ General style (CARD or container):
240
239
  border-radius: 8px;
241
240
  padding: 12px;
242
241
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
242
+
243
+ Header area (if you use one):
243
244
  - You may add a top header area using the header background color:
244
245
  background: ${headerColor};
245
246
 
246
- Use branding:
247
- - Include the company logo and name in a subtle way when appropriate
248
- (for example, in a small header bar):
249
- - Logo (emoji or image) on the left,
250
- - Company name text next to it.
251
-
252
247
  Typography:
253
248
  - Titles: 18\u201322px, bold.
254
249
  - Body text: 12\u201316px, regular.
@@ -270,6 +265,37 @@ Links:
270
265
  - Use the accent color for links:
271
266
  color: ${accentColor};
272
267
 
268
+ ====================
269
+ CONFIRMATION MODE (SPECIAL CASE)
270
+ ====================
271
+ Sometimes, during a workflow or tool usage, you may need the user to confirm an action
272
+ (e.g., deleting a workflow, sending a transaction, performing an irreversible change).
273
+
274
+ In such CONFIRMATION cases ONLY:
275
+ - You ARE allowed to use exactly TWO <button> elements.
276
+ - They MUST be rendered with these exact data attributes:
277
+
278
+ <button data-ai-action="approve">Onayla</button>
279
+ <button data-ai-action="cancel">Vazge\xE7</button>
280
+
281
+ Rules for confirmation buttons:
282
+ - Do NOT add onclick or any other JS event attributes.
283
+ - Do NOT add custom data attributes besides data-ai-action.
284
+ - The host application will detect these buttons by data-ai-action
285
+ and will send the following messages back to you:
286
+ "__APPROVE__" when the user clicks "Onayla"
287
+ "__CANCEL__" when the user clicks "Vazge\xE7"
288
+
289
+ Behavior after user choice:
290
+ - When you receive "__APPROVE__", behave as if the user confirmed YES.
291
+ - When you receive "__CANCEL__", behave as if the user declined or cancelled.
292
+ - After that, go back to NORMAL mode and return standard HTML output again
293
+ (card, table, or mini table, WITHOUT <button>).
294
+
295
+ IMPORTANT:
296
+ - In NORMAL responses (no confirmation needed), you MUST NOT use <button>.
297
+ - In CONFIRMATION MODE, you MUST use exactly these two buttons and NO others.
298
+
273
299
  ====================
274
300
  OUTPUT FORMAT
275
301
  ====================
@@ -281,16 +307,21 @@ Your final output MUST follow these rules:
281
307
  - Must use exactly ONE of: card, table, mini table.
282
308
  - Must respect allowed/forbidden tags.
283
309
  - Must use colors derived from:
284
- - header_background
285
- - button_background
310
+ - headerBackground
311
+ - buttonBackground
286
312
  and otherwise a light theme.
287
313
 
288
314
  ====================
289
315
  BEHAVIOR SUMMARY
290
316
  ====================
291
317
  1) Read the user message.
292
- 2) Decide whether CARD, TABLE, or MINI TABLE is most suitable.
293
- 3) Generate a single HTML layout using only allowed, non-interactive tags.
318
+ 2) If it is a normal response:
319
+ - Decide whether CARD, TABLE, or MINI TABLE is most suitable.
320
+ - Generate a single HTML layout using only allowed, non-interactive tags (no <button>).
321
+ 3) If you need explicit user confirmation:
322
+ - Enter CONFIRMATION MODE.
323
+ - Render a short explanation AND exactly two <button> elements with:
324
+ data-ai-action="approve" and data-ai-action="cancel".
294
325
  4) Style the layout with inline CSS using:
295
326
  - ${headerColor} for header areas,
296
327
  - ${accentColor} for accents,
@@ -326,7 +357,9 @@ BEHAVIOR SUMMARY
326
357
  if (resp && Array.isArray(resp)) {
327
358
  const messageItem = resp.find((item) => item.type === "message");
328
359
  if (messageItem && messageItem.content && Array.isArray(messageItem.content)) {
329
- const textContent = messageItem.content.find((content) => content.type === "output_text");
360
+ const textContent = messageItem.content.find(
361
+ (content) => content.type === "output_text"
362
+ );
330
363
  if (textContent && textContent.text) {
331
364
  responseText = textContent.text;
332
365
  }
@@ -345,7 +378,10 @@ BEHAVIOR SUMMARY
345
378
  setIsLoading(false);
346
379
  } catch (error) {
347
380
  console.error("Error sending message:", error);
348
- addMessage("\xDCzg\xFCn\xFCm, bir hata olu\u015Ftu. L\xFCtfen tekrar deneyin.", "assistant");
381
+ addMessage(
382
+ "\xDCzg\xFCn\xFCm, bir hata olu\u015Ftu. L\xFCtfen tekrar deneyin.",
383
+ "assistant"
384
+ );
349
385
  setIsLoading(false);
350
386
  }
351
387
  };
@@ -404,7 +440,8 @@ var mapApiSettingsToConfig = (apiSettings) => {
404
440
  };
405
441
 
406
442
  // src/styles/messageStyles.ts
407
- var getMessageBubbleStyles = (isUser) => ({
443
+ var getMessageBubbleStyles = (isUser, isTyping) => ({
444
+ display: !isTyping && !isUser ? "none" : "block",
408
445
  maxWidth: "80%",
409
446
  padding: "12px 16px",
410
447
  borderRadius: isUser ? "18px 18px 4px 18px" : "18px 18px 18px 4px",
@@ -880,7 +917,10 @@ var getAlertAnimationStyles = () => `
880
917
  }
881
918
  }
882
919
  `;
883
- var AizekChatBot = ({ clientId, headers }) => {
920
+ var AizekChatBot = ({
921
+ clientId,
922
+ headers
923
+ }) => {
884
924
  const defaultConfig = {
885
925
  welcomeMessage: "Merhaba! Size nas\u0131l yard\u0131mc\u0131 olabilirim?",
886
926
  buttonBackground: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
@@ -899,27 +939,47 @@ var AizekChatBot = ({ clientId, headers }) => {
899
939
  const [isConfigLoading, setIsConfigLoading] = React.useState(true);
900
940
  const [finalMcpUrl, setFinalMcpUrl] = React.useState("");
901
941
  const [apiKey, setApiKey] = React.useState("");
902
- const { welcomeMessage, buttonBackground, placeholder, buttonPosition, buttonSize, chatWidth, chatHeight, showTypingIndicator, initialOpen, headerBackground, companyLogo, companyName } = config;
942
+ const {
943
+ welcomeMessage,
944
+ buttonBackground,
945
+ placeholder,
946
+ buttonPosition,
947
+ buttonSize,
948
+ chatWidth,
949
+ chatHeight,
950
+ showTypingIndicator,
951
+ initialOpen,
952
+ headerBackground,
953
+ companyLogo,
954
+ companyName
955
+ } = config;
903
956
  const [isOpen, setIsOpen] = React.useState(false);
904
957
  const [headerValidation, setHeaderValidation] = React.useState(null);
905
958
  const [showAlert, setShowAlert] = React.useState(true);
959
+ console.log("Component rendered");
906
960
  React.useEffect(() => {
907
- console.log("render");
961
+ console.log("use");
908
962
  const loadConfig = async () => {
909
963
  try {
910
964
  setIsConfigLoading(true);
911
965
  const apiResponse = await fetchChatWidgetSettings(clientId);
912
966
  if (headers && apiResponse.data.auth_config) {
913
- const validationResult = validateHeaders(headers, apiResponse.data.auth_config, {
914
- allowExtra: false,
915
- caseSensitive: true
916
- });
967
+ const validationResult = validateHeaders(
968
+ headers,
969
+ apiResponse.data.auth_config,
970
+ {
971
+ allowExtra: false,
972
+ caseSensitive: true
973
+ }
974
+ );
917
975
  console.log(validationResult);
918
976
  setHeaderValidation(validationResult);
919
977
  }
920
978
  setFinalMcpUrl(apiResponse.data.mcp_url);
921
979
  setApiKey(apiResponse.data.openai_key || "");
922
- const apiConfig = mapApiSettingsToConfig(apiResponse.data.chat_widget_settings);
980
+ const apiConfig = mapApiSettingsToConfig(
981
+ apiResponse.data.chat_widget_settings
982
+ );
923
983
  if (apiConfig) {
924
984
  setConfig(apiConfig);
925
985
  }
@@ -932,7 +992,12 @@ var AizekChatBot = ({ clientId, headers }) => {
932
992
  };
933
993
  loadConfig();
934
994
  }, [clientId]);
935
- const internalChatbot = useChatbot({ mcpUrl: finalMcpUrl, apiKey, headers, config });
995
+ const internalChatbot = useChatbot({
996
+ mcpUrl: finalMcpUrl,
997
+ apiKey,
998
+ headers,
999
+ config
1000
+ });
936
1001
  const messages = internalChatbot.messages;
937
1002
  const isLoading = internalChatbot.isLoading;
938
1003
  const handleSendMessage = internalChatbot.sendMessage;
@@ -947,18 +1012,39 @@ var AizekChatBot = ({ clientId, headers }) => {
947
1012
  React.useEffect(() => {
948
1013
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
949
1014
  }, [messages]);
950
- const MessageBubble = ({ message }) => {
1015
+ const MessageBubble = ({ message, onAction }) => {
951
1016
  const isUser = message.role === "user";
1017
+ const cleanContent = DOMPurify__default.default.sanitize(message.content);
1018
+ const htmlRef = React.useRef(null);
1019
+ React.useEffect(() => {
1020
+ if (!htmlRef.current || isUser) return;
1021
+ const root = htmlRef.current;
1022
+ const approveBtn = root.querySelector(
1023
+ 'button[data-ai-action="approve"]'
1024
+ );
1025
+ const cancelBtn = root.querySelector(
1026
+ 'button[data-ai-action="cancel"]'
1027
+ );
1028
+ const handleApprove = () => onAction("__APPROVE__");
1029
+ const handleCancel = () => onAction("__CANCEL__");
1030
+ if (approveBtn) approveBtn.addEventListener("click", handleApprove);
1031
+ if (cancelBtn) cancelBtn.addEventListener("click", handleCancel);
1032
+ return () => {
1033
+ if (approveBtn) approveBtn.removeEventListener("click", handleApprove);
1034
+ if (cancelBtn) cancelBtn.removeEventListener("click", handleCancel);
1035
+ };
1036
+ }, [message.content, isUser, onAction]);
952
1037
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getMessageContainerStyles(isUser), children: [
953
1038
  /* @__PURE__ */ jsxRuntime.jsx("style", { children: getMarkdownElementStyles(isUser) }),
954
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getMessageBubbleStyles(isUser), children: [
955
- isUser ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: getMarkdownStyles(), className: "markdown-content", children: /* @__PURE__ */ jsxRuntime.jsx(ReactMarkdown__default.default, { remarkPlugins: [remarkGfm__default.default], children: message.content }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: message.content } }),
1039
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getMessageBubbleStyles(isUser, message.isTyping ?? false), children: [
1040
+ isUser && /* @__PURE__ */ jsxRuntime.jsx("div", { style: getMarkdownStyles(), className: "markdown-content", children: /* @__PURE__ */ jsxRuntime.jsx(ReactMarkdown__default.default, { remarkPlugins: [remarkGfm__default.default], children: message.content }) }),
956
1041
  message.isTyping && /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
957
1042
  display: "inline-flex",
958
1043
  alignItems: "center",
959
1044
  marginLeft: "8px"
960
1045
  }, children: /* @__PURE__ */ jsxRuntime.jsx(TypingDots, {}) })
961
1046
  ] }),
1047
+ !isUser && /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: cleanContent } }),
962
1048
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: getTimeStyles(isUser), children: message.timestamp.toLocaleTimeString("tr-TR", {
963
1049
  hour: "2-digit",
964
1050
  minute: "2-digit"
@@ -1003,60 +1089,102 @@ var AizekChatBot = ({ clientId, headers }) => {
1003
1089
  missingKeys.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1004
1090
  /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { fontSize: "13px" }, children: "Eksik Header'lar:" }),
1005
1091
  /* @__PURE__ */ jsxRuntime.jsx("ul", { style: getAlertListStyles(), children: missingKeys.map((key, index) => /* @__PURE__ */ jsxRuntime.jsxs("li", { style: getAlertListItemStyles(), children: [
1006
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: {
1007
- position: "absolute",
1008
- left: "0",
1009
- top: "2px",
1010
- fontWeight: "bold"
1011
- }, children: "\u2022" }),
1012
- /* @__PURE__ */ jsxRuntime.jsx("code", { style: {
1013
- background: "rgba(255, 255, 255, 0.2)",
1014
- padding: "2px 6px",
1015
- borderRadius: "4px",
1016
- fontFamily: "monospace",
1017
- fontSize: "12px"
1018
- }, children: key })
1092
+ /* @__PURE__ */ jsxRuntime.jsx(
1093
+ "span",
1094
+ {
1095
+ style: {
1096
+ position: "absolute",
1097
+ left: "0",
1098
+ top: "2px",
1099
+ fontWeight: "bold"
1100
+ },
1101
+ children: "\u2022"
1102
+ }
1103
+ ),
1104
+ /* @__PURE__ */ jsxRuntime.jsx(
1105
+ "code",
1106
+ {
1107
+ style: {
1108
+ background: "rgba(255, 255, 255, 0.2)",
1109
+ padding: "2px 6px",
1110
+ borderRadius: "4px",
1111
+ fontFamily: "monospace",
1112
+ fontSize: "12px"
1113
+ },
1114
+ children: key
1115
+ }
1116
+ )
1019
1117
  ] }, index)) })
1020
1118
  ] }),
1021
1119
  emptyValueKeys.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1022
1120
  /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { fontSize: "13px" }, children: "Bo\u015F De\u011Ferli Header'lar:" }),
1023
1121
  /* @__PURE__ */ jsxRuntime.jsx("ul", { style: getAlertListStyles(), children: emptyValueKeys.map((key, index) => /* @__PURE__ */ jsxRuntime.jsxs("li", { style: getAlertListItemStyles(), children: [
1024
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: {
1025
- position: "absolute",
1026
- left: "0",
1027
- top: "2px",
1028
- fontWeight: "bold"
1029
- }, children: "\u2022" }),
1030
- /* @__PURE__ */ jsxRuntime.jsx("code", { style: {
1031
- background: "rgba(255, 255, 255, 0.2)",
1032
- padding: "2px 6px",
1033
- borderRadius: "4px",
1034
- fontFamily: "monospace",
1035
- fontSize: "12px"
1036
- }, children: key }),
1037
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: {
1038
- marginLeft: "6px",
1039
- fontSize: "11px",
1040
- opacity: 0.9
1041
- }, children: "(de\u011Fer bo\u015F olamaz)" })
1122
+ /* @__PURE__ */ jsxRuntime.jsx(
1123
+ "span",
1124
+ {
1125
+ style: {
1126
+ position: "absolute",
1127
+ left: "0",
1128
+ top: "2px",
1129
+ fontWeight: "bold"
1130
+ },
1131
+ children: "\u2022"
1132
+ }
1133
+ ),
1134
+ /* @__PURE__ */ jsxRuntime.jsx(
1135
+ "code",
1136
+ {
1137
+ style: {
1138
+ background: "rgba(255, 255, 255, 0.2)",
1139
+ padding: "2px 6px",
1140
+ borderRadius: "4px",
1141
+ fontFamily: "monospace",
1142
+ fontSize: "12px"
1143
+ },
1144
+ children: key
1145
+ }
1146
+ ),
1147
+ /* @__PURE__ */ jsxRuntime.jsx(
1148
+ "span",
1149
+ {
1150
+ style: {
1151
+ marginLeft: "6px",
1152
+ fontSize: "11px",
1153
+ opacity: 0.9
1154
+ },
1155
+ children: "(de\u011Fer bo\u015F olamaz)"
1156
+ }
1157
+ )
1042
1158
  ] }, index)) })
1043
1159
  ] }),
1044
1160
  extraKeys.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1045
1161
  /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { fontSize: "13px" }, children: "Fazla Header'lar:" }),
1046
1162
  /* @__PURE__ */ jsxRuntime.jsx("ul", { style: getAlertListStyles(), children: extraKeys.map((key, index) => /* @__PURE__ */ jsxRuntime.jsxs("li", { style: getAlertListItemStyles(), children: [
1047
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: {
1048
- position: "absolute",
1049
- left: "0",
1050
- top: "2px",
1051
- fontWeight: "bold"
1052
- }, children: "\u2022" }),
1053
- /* @__PURE__ */ jsxRuntime.jsx("code", { style: {
1054
- background: "rgba(255, 255, 255, 0.2)",
1055
- padding: "2px 6px",
1056
- borderRadius: "4px",
1057
- fontFamily: "monospace",
1058
- fontSize: "12px"
1059
- }, children: key })
1163
+ /* @__PURE__ */ jsxRuntime.jsx(
1164
+ "span",
1165
+ {
1166
+ style: {
1167
+ position: "absolute",
1168
+ left: "0",
1169
+ top: "2px",
1170
+ fontWeight: "bold"
1171
+ },
1172
+ children: "\u2022"
1173
+ }
1174
+ ),
1175
+ /* @__PURE__ */ jsxRuntime.jsx(
1176
+ "code",
1177
+ {
1178
+ style: {
1179
+ background: "rgba(255, 255, 255, 0.2)",
1180
+ padding: "2px 6px",
1181
+ borderRadius: "4px",
1182
+ fontFamily: "monospace",
1183
+ fontSize: "12px"
1184
+ },
1185
+ children: key
1186
+ }
1187
+ )
1060
1188
  ] }, index)) })
1061
1189
  ] })
1062
1190
  ] }),
@@ -1139,7 +1267,18 @@ var AizekChatBot = ({ clientId, headers }) => {
1139
1267
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: getLoadingSpinnerStyles() });
1140
1268
  };
1141
1269
  if (isConfigLoading) {
1142
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: getFloatingButtonStyles(buttonPosition, buttonSize, buttonBackground, false), children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: getLoadingSpinnerStyles() }) });
1270
+ return /* @__PURE__ */ jsxRuntime.jsx(
1271
+ "div",
1272
+ {
1273
+ style: getFloatingButtonStyles(
1274
+ buttonPosition,
1275
+ buttonSize,
1276
+ buttonBackground,
1277
+ false
1278
+ ),
1279
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: getLoadingSpinnerStyles() })
1280
+ }
1281
+ );
1143
1282
  }
1144
1283
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1145
1284
  isOpen && /* @__PURE__ */ jsxRuntime.jsx(
@@ -1150,49 +1289,74 @@ var AizekChatBot = ({ clientId, headers }) => {
1150
1289
  className: "floating-chat-overlay"
1151
1290
  }
1152
1291
  ),
1153
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: getChatContainerStyles(buttonPosition, chatWidth, chatHeight, isOpen), className: "floating-chat-container", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getChatbotContainerStyles(), children: [
1154
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getHeaderStyles(headerBackground), children: [
1155
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: getLogoContainerStyles(), children: companyLogo ? companyLogo.startsWith("http") || companyLogo.startsWith("data:") ? /* @__PURE__ */ jsxRuntime.jsx(
1156
- "img",
1157
- {
1158
- src: companyLogo,
1159
- alt: "Company Logo",
1160
- style: getLogoImageStyles()
1161
- }
1162
- ) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: getLogoTextStyles(), children: companyLogo }) : "\u{1F916}" }),
1163
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1164
- /* @__PURE__ */ jsxRuntime.jsx("h3", { style: getCompanyNameStyles(), children: companyName }),
1165
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: getStatusTextStyles(), children: isLoading ? "Yaz\u0131yor..." : "\xC7evrimi\xE7i" })
1166
- ] })
1167
- ] }),
1168
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getMessagesContainerStyles(), children: [
1169
- /* @__PURE__ */ jsxRuntime.jsx(HeaderValidationAlert, {}),
1170
- messages.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getEmptyStateStyles(), children: [
1171
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "48px", marginBottom: "16px" }, children: "\u{1F4AC}" }),
1172
- /* @__PURE__ */ jsxRuntime.jsx("h4", { style: { margin: "0 0 8px 0", fontSize: "18px" }, children: welcomeMessage }),
1173
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "14px", opacity: 0.8 }, children: "A\u015Fa\u011F\u0131daki alana mesaj\u0131n\u0131z\u0131 yazarak ba\u015Flayabilirsiniz." })
1174
- ] }) : messages.map((message) => /* @__PURE__ */ jsxRuntime.jsx(MessageBubble, { message }, message.id)),
1175
- showTypingIndicator && isLoading && messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1176
- MessageBubble,
1177
- {
1178
- message: {
1179
- id: "typing",
1180
- content: "",
1181
- role: "assistant",
1182
- timestamp: /* @__PURE__ */ new Date(),
1183
- isTyping: true
1184
- }
1185
- }
1292
+ /* @__PURE__ */ jsxRuntime.jsx(
1293
+ "div",
1294
+ {
1295
+ style: getChatContainerStyles(
1296
+ buttonPosition,
1297
+ chatWidth,
1298
+ chatHeight,
1299
+ isOpen
1186
1300
  ),
1187
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: messagesEndRef })
1188
- ] }),
1189
- /* @__PURE__ */ jsxRuntime.jsx(ChatInput, {})
1190
- ] }) }),
1301
+ className: "floating-chat-container",
1302
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getChatbotContainerStyles(), children: [
1303
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getHeaderStyles(headerBackground), children: [
1304
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: getLogoContainerStyles(), children: companyLogo ? companyLogo.startsWith("http") || companyLogo.startsWith("data:") ? /* @__PURE__ */ jsxRuntime.jsx(
1305
+ "img",
1306
+ {
1307
+ src: companyLogo,
1308
+ alt: "Company Logo",
1309
+ style: getLogoImageStyles()
1310
+ }
1311
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: getLogoTextStyles(), children: companyLogo }) : "\u{1F916}" }),
1312
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1313
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { style: getCompanyNameStyles(), children: companyName }),
1314
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: getStatusTextStyles(), children: isLoading ? "Yaz\u0131yor..." : "\xC7evrimi\xE7i" })
1315
+ ] })
1316
+ ] }),
1317
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getMessagesContainerStyles(), children: [
1318
+ /* @__PURE__ */ jsxRuntime.jsx(HeaderValidationAlert, {}),
1319
+ messages.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getEmptyStateStyles(), children: [
1320
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "48px", marginBottom: "16px" }, children: "\u{1F4AC}" }),
1321
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { style: { margin: "0 0 8px 0", fontSize: "18px" }, children: welcomeMessage }),
1322
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "14px", opacity: 0.8 }, children: "A\u015Fa\u011F\u0131daki alana mesaj\u0131n\u0131z\u0131 yazarak ba\u015Flayabilirsiniz." })
1323
+ ] }) : messages.map((message) => /* @__PURE__ */ jsxRuntime.jsx(
1324
+ MessageBubble,
1325
+ {
1326
+ message,
1327
+ onAction: handleSendMessage
1328
+ },
1329
+ message.id
1330
+ )),
1331
+ showTypingIndicator && isLoading && messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1332
+ MessageBubble,
1333
+ {
1334
+ message: {
1335
+ id: "typing",
1336
+ content: "",
1337
+ role: "assistant",
1338
+ timestamp: /* @__PURE__ */ new Date(),
1339
+ isTyping: true
1340
+ },
1341
+ onAction: handleSendMessage
1342
+ }
1343
+ ),
1344
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: messagesEndRef })
1345
+ ] }),
1346
+ /* @__PURE__ */ jsxRuntime.jsx(ChatInput, {})
1347
+ ] })
1348
+ }
1349
+ ),
1191
1350
  /* @__PURE__ */ jsxRuntime.jsx(
1192
1351
  "button",
1193
1352
  {
1194
1353
  onClick: toggleChat,
1195
- style: getFloatingButtonStyles(buttonPosition, buttonSize, buttonBackground, isOpen),
1354
+ style: getFloatingButtonStyles(
1355
+ buttonPosition,
1356
+ buttonSize,
1357
+ buttonBackground,
1358
+ isOpen
1359
+ ),
1196
1360
  onMouseEnter: (e) => {
1197
1361
  e.currentTarget.style.transform = isOpen ? "scale(0.85)" : "scale(1.1)";
1198
1362
  e.currentTarget.style.boxShadow = "0 6px 20px rgba(0, 0, 0, 0.25)";