aizek-chatbot 1.0.8 → 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) {
@@ -123,7 +125,7 @@ var Button = React__namespace.forwardRef(
123
125
  );
124
126
  Button.displayName = "Button";
125
127
  var useChatbot = (options = {}) => {
126
- const { mcpUrl, apiKey } = options;
128
+ const { mcpUrl, apiKey, config } = options;
127
129
  const client = new OpenAI__default.default({ apiKey, dangerouslyAllowBrowser: true });
128
130
  const [responseId, setResponseId] = React.useState(null);
129
131
  const [messages, setMessages] = React.useState([]);
@@ -141,10 +143,197 @@ var useChatbot = (options = {}) => {
141
143
  setMessages((prev) => [...prev, newMessage]);
142
144
  return newMessage;
143
145
  };
146
+ const getHtmlUiInstructions = (config2) => {
147
+ const headerColor = config2?.headerBackground || "#f5f5f5";
148
+ const accentColor = config2?.buttonBackground || "#007bff";
149
+ return `
150
+ You are a helpful assistant that creates UI using ONLY HTML tags.
151
+
152
+ Your task:
153
+ - Read the user message and respond.
154
+ - Render your response as a small HTML layout (card OR table OR mini-table).
155
+ - Use inline CSS styles.
156
+ - Use a clean, light (white-based) theme.
157
+ - Use colors from options.config (headerBackground, buttonBackground).
158
+ - Return ONLY raw HTML (no markdown, no backticks, no JSON, no explanations).
159
+
160
+ ====================
161
+ THEME (from options.config)
162
+ ====================
163
+ The chat widget configuration provides:
164
+
165
+ - Header Background Color: ${headerColor}
166
+ - Button / Accent Color: ${accentColor}
167
+
168
+ How to use these:
169
+ - Use Header Background Color mainly for top headers, title strips, or main highlight areas.
170
+ - Use Button / Accent Color for important accents: borders, highlights, badges, table headers, key text highlights, links, etc.
171
+ - Use a white or very light background for main surfaces.
172
+ - Text color should generally be dark (#111\u2013#333) for readability.
173
+
174
+ ====================
175
+ ALLOWED / FORBIDDEN TAGS
176
+ ====================
177
+ You may use ANY NON-INTERACTIVE HTML element, for example:
178
+ - Text and headings:
179
+ <h1>, <h2>, <h3>, <h4>, <h5>, <h6>,
180
+ <p>, <span>, <strong>, <em>, <small>, <blockquote>, <code>, <pre>
181
+ - Layout:
182
+ <div>, <section>, <article>, <header>, <footer>
183
+ - Lists:
184
+ <ul>, <ol>, <li>
185
+ - Tables:
186
+ <table>, <thead>, <tbody>, <tr>, <th>, <td>
187
+ - Media:
188
+ <img>, <figure>, <figcaption>
189
+ - Links (non-interactive navigation style only):
190
+ <a>
191
+
192
+ GENERAL RULE:
193
+ - In NORMAL responses, you MUST NOT use <button>.
194
+
195
+ FORBIDDEN (NORMAL MODE):
196
+ - <button>, <input>, <textarea>, <select>, <option>, <form>, <label>
197
+ - <details>, <summary>, <dialog>
198
+ - <video> or <audio> with controls for user interaction
199
+ - Any inline event handlers like onclick, onmouseover, etc.
200
+ - <script> or any JavaScript code.
201
+
202
+ ====================
203
+ LAYOUT TYPE RULES
204
+ ====================
205
+ You have exactly THREE layout types you can use:
206
+
207
+ 1) CARD
208
+ 2) TABLE
209
+ 3) MINI TABLE
210
+
211
+ For EACH response:
212
+ - You MUST choose exactly ONE of these layout types.
213
+ - You MUST NOT mix layout types in the same response.
214
+ (Do NOT render card + table together, or table + mini-table together.)
215
+
216
+ Which layout to choose:
217
+ - CARD (DEFAULT):
218
+ - Use this for normal answers, explanations, descriptions, welcome messages,
219
+ and any content that is mostly free text.
220
+ - TABLE:
221
+ - Use this ONLY when the content is clearly structured with multiple columns
222
+ (for example: comparisons, lists of items with several attributes).
223
+ - MINI TABLE:
224
+ - Use this for small, compact key-value style data
225
+ (for example: a few fields like "Token", "Price", "Network"),
226
+ or when a full table would be visually too heavy.
227
+
228
+ If the user does NOT explicitly ask for a table or very structured data,
229
+ you MUST use the CARD layout.
230
+
231
+ ====================
232
+ STYLE RULES
233
+ ====================
234
+ General style (CARD or container):
235
+ - Use a main wrapper <div> with styles similar to:
236
+ background: #ffffff;
237
+ color: #111111;
238
+ border: 1px solid #e5e5e5;
239
+ border-radius: 8px;
240
+ padding: 12px;
241
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
242
+
243
+ Header area (if you use one):
244
+ - You may add a top header area using the header background color:
245
+ background: ${headerColor};
246
+
247
+ Typography:
248
+ - Titles: 18\u201322px, bold.
249
+ - Body text: 12\u201316px, regular.
250
+ - Line-height should be comfortable (around 1.4\u20131.6).
251
+
252
+ Tables:
253
+ - Use <table> with <thead> and <tbody> where appropriate.
254
+ - Header row background: ${accentColor};
255
+ - Header row text color: #ffffff;
256
+ - Body rows background: #ffffff;
257
+ - Row borders: 1px solid #e5e5e5 (or a faint version of the border color).
258
+
259
+ Mini table:
260
+ - Can be a simple two-column table or stacked key-value pairs.
261
+ - Keep it compact (less padding, fewer rows).
262
+
263
+ Links:
264
+ - You can use <a> for styling or static URLs.
265
+ - Use the accent color for links:
266
+ color: ${accentColor};
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
+
299
+ ====================
300
+ OUTPUT FORMAT
301
+ ====================
302
+ Your final output MUST follow these rules:
303
+ - Output ONLY a single HTML snippet.
304
+ - Do NOT wrap it in backticks or markdown.
305
+ - Do NOT include any explanation text.
306
+ - Do NOT include JSON.
307
+ - Must use exactly ONE of: card, table, mini table.
308
+ - Must respect allowed/forbidden tags.
309
+ - Must use colors derived from:
310
+ - headerBackground
311
+ - buttonBackground
312
+ and otherwise a light theme.
313
+
314
+ ====================
315
+ BEHAVIOR SUMMARY
316
+ ====================
317
+ 1) Read the user message.
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".
325
+ 4) Style the layout with inline CSS using:
326
+ - ${headerColor} for header areas,
327
+ - ${accentColor} for accents,
328
+ - white/light backgrounds and dark text.
329
+ 5) Return ONLY the HTML snippet.
330
+ `;
331
+ };
144
332
  const sendMessage = async (message) => {
145
333
  if (!message.trim() || isLoading) return;
146
334
  addMessage(message, "user");
147
335
  setIsLoading(true);
336
+ console.log(options.config);
148
337
  try {
149
338
  let resp;
150
339
  console.log(options.headers);
@@ -160,14 +349,17 @@ var useChatbot = (options = {}) => {
160
349
  }
161
350
  ],
162
351
  input: message,
163
- previous_response_id: responseId || void 0
352
+ previous_response_id: responseId || void 0,
353
+ instructions: getHtmlUiInstructions(options.config)
164
354
  });
165
355
  setResponseId(resp.id);
166
356
  let responseText = "";
167
357
  if (resp && Array.isArray(resp)) {
168
358
  const messageItem = resp.find((item) => item.type === "message");
169
359
  if (messageItem && messageItem.content && Array.isArray(messageItem.content)) {
170
- const textContent = messageItem.content.find((content) => content.type === "output_text");
360
+ const textContent = messageItem.content.find(
361
+ (content) => content.type === "output_text"
362
+ );
171
363
  if (textContent && textContent.text) {
172
364
  responseText = textContent.text;
173
365
  }
@@ -186,7 +378,10 @@ var useChatbot = (options = {}) => {
186
378
  setIsLoading(false);
187
379
  } catch (error) {
188
380
  console.error("Error sending message:", error);
189
- 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
+ );
190
385
  setIsLoading(false);
191
386
  }
192
387
  };
@@ -245,7 +440,8 @@ var mapApiSettingsToConfig = (apiSettings) => {
245
440
  };
246
441
 
247
442
  // src/styles/messageStyles.ts
248
- var getMessageBubbleStyles = (isUser) => ({
443
+ var getMessageBubbleStyles = (isUser, isTyping) => ({
444
+ display: !isTyping && !isUser ? "none" : "block",
249
445
  maxWidth: "80%",
250
446
  padding: "12px 16px",
251
447
  borderRadius: isUser ? "18px 18px 4px 18px" : "18px 18px 18px 4px",
@@ -721,7 +917,10 @@ var getAlertAnimationStyles = () => `
721
917
  }
722
918
  }
723
919
  `;
724
- var AizekChatBot = ({ clientId, headers }) => {
920
+ var AizekChatBot = ({
921
+ clientId,
922
+ headers
923
+ }) => {
725
924
  const defaultConfig = {
726
925
  welcomeMessage: "Merhaba! Size nas\u0131l yard\u0131mc\u0131 olabilirim?",
727
926
  buttonBackground: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
@@ -740,27 +939,47 @@ var AizekChatBot = ({ clientId, headers }) => {
740
939
  const [isConfigLoading, setIsConfigLoading] = React.useState(true);
741
940
  const [finalMcpUrl, setFinalMcpUrl] = React.useState("");
742
941
  const [apiKey, setApiKey] = React.useState("");
743
- const [validConfig, setValidConfig] = React.useState(false);
744
- 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;
745
956
  const [isOpen, setIsOpen] = React.useState(false);
746
957
  const [headerValidation, setHeaderValidation] = React.useState(null);
747
958
  const [showAlert, setShowAlert] = React.useState(true);
959
+ console.log("Component rendered");
748
960
  React.useEffect(() => {
961
+ console.log("use");
749
962
  const loadConfig = async () => {
750
963
  try {
751
964
  setIsConfigLoading(true);
752
965
  const apiResponse = await fetchChatWidgetSettings(clientId);
753
966
  if (headers && apiResponse.data.auth_config) {
754
- const validationResult = validateHeaders(headers, apiResponse.data.auth_config, {
755
- allowExtra: false,
756
- caseSensitive: true
757
- });
967
+ const validationResult = validateHeaders(
968
+ headers,
969
+ apiResponse.data.auth_config,
970
+ {
971
+ allowExtra: false,
972
+ caseSensitive: true
973
+ }
974
+ );
758
975
  console.log(validationResult);
759
976
  setHeaderValidation(validationResult);
760
977
  }
761
978
  setFinalMcpUrl(apiResponse.data.mcp_url);
762
979
  setApiKey(apiResponse.data.openai_key || "");
763
- const apiConfig = mapApiSettingsToConfig(apiResponse.data.chat_widget_settings);
980
+ const apiConfig = mapApiSettingsToConfig(
981
+ apiResponse.data.chat_widget_settings
982
+ );
764
983
  if (apiConfig) {
765
984
  setConfig(apiConfig);
766
985
  }
@@ -773,7 +992,12 @@ var AizekChatBot = ({ clientId, headers }) => {
773
992
  };
774
993
  loadConfig();
775
994
  }, [clientId]);
776
- const internalChatbot = useChatbot({ mcpUrl: finalMcpUrl, apiKey, headers });
995
+ const internalChatbot = useChatbot({
996
+ mcpUrl: finalMcpUrl,
997
+ apiKey,
998
+ headers,
999
+ config
1000
+ });
777
1001
  const messages = internalChatbot.messages;
778
1002
  const isLoading = internalChatbot.isLoading;
779
1003
  const handleSendMessage = internalChatbot.sendMessage;
@@ -788,18 +1012,39 @@ var AizekChatBot = ({ clientId, headers }) => {
788
1012
  React.useEffect(() => {
789
1013
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
790
1014
  }, [messages]);
791
- const MessageBubble = ({ message }) => {
1015
+ const MessageBubble = ({ message, onAction }) => {
792
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]);
793
1037
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getMessageContainerStyles(isUser), children: [
794
1038
  /* @__PURE__ */ jsxRuntime.jsx("style", { children: getMarkdownElementStyles(isUser) }),
795
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getMessageBubbleStyles(isUser), children: [
796
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: getMarkdownStyles(), className: "markdown-content", children: /* @__PURE__ */ jsxRuntime.jsx(ReactMarkdown__default.default, { remarkPlugins: [remarkGfm__default.default], children: 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 }) }),
797
1041
  message.isTyping && /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
798
1042
  display: "inline-flex",
799
1043
  alignItems: "center",
800
1044
  marginLeft: "8px"
801
1045
  }, children: /* @__PURE__ */ jsxRuntime.jsx(TypingDots, {}) })
802
1046
  ] }),
1047
+ !isUser && /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: cleanContent } }),
803
1048
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: getTimeStyles(isUser), children: message.timestamp.toLocaleTimeString("tr-TR", {
804
1049
  hour: "2-digit",
805
1050
  minute: "2-digit"
@@ -844,60 +1089,102 @@ var AizekChatBot = ({ clientId, headers }) => {
844
1089
  missingKeys.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
845
1090
  /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { fontSize: "13px" }, children: "Eksik Header'lar:" }),
846
1091
  /* @__PURE__ */ jsxRuntime.jsx("ul", { style: getAlertListStyles(), children: missingKeys.map((key, index) => /* @__PURE__ */ jsxRuntime.jsxs("li", { style: getAlertListItemStyles(), children: [
847
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: {
848
- position: "absolute",
849
- left: "0",
850
- top: "2px",
851
- fontWeight: "bold"
852
- }, children: "\u2022" }),
853
- /* @__PURE__ */ jsxRuntime.jsx("code", { style: {
854
- background: "rgba(255, 255, 255, 0.2)",
855
- padding: "2px 6px",
856
- borderRadius: "4px",
857
- fontFamily: "monospace",
858
- fontSize: "12px"
859
- }, 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
+ )
860
1117
  ] }, index)) })
861
1118
  ] }),
862
1119
  emptyValueKeys.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
863
1120
  /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { fontSize: "13px" }, children: "Bo\u015F De\u011Ferli Header'lar:" }),
864
1121
  /* @__PURE__ */ jsxRuntime.jsx("ul", { style: getAlertListStyles(), children: emptyValueKeys.map((key, index) => /* @__PURE__ */ jsxRuntime.jsxs("li", { style: getAlertListItemStyles(), children: [
865
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: {
866
- position: "absolute",
867
- left: "0",
868
- top: "2px",
869
- fontWeight: "bold"
870
- }, children: "\u2022" }),
871
- /* @__PURE__ */ jsxRuntime.jsx("code", { style: {
872
- background: "rgba(255, 255, 255, 0.2)",
873
- padding: "2px 6px",
874
- borderRadius: "4px",
875
- fontFamily: "monospace",
876
- fontSize: "12px"
877
- }, children: key }),
878
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: {
879
- marginLeft: "6px",
880
- fontSize: "11px",
881
- opacity: 0.9
882
- }, 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
+ )
883
1158
  ] }, index)) })
884
1159
  ] }),
885
1160
  extraKeys.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
886
1161
  /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { fontSize: "13px" }, children: "Fazla Header'lar:" }),
887
1162
  /* @__PURE__ */ jsxRuntime.jsx("ul", { style: getAlertListStyles(), children: extraKeys.map((key, index) => /* @__PURE__ */ jsxRuntime.jsxs("li", { style: getAlertListItemStyles(), children: [
888
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: {
889
- position: "absolute",
890
- left: "0",
891
- top: "2px",
892
- fontWeight: "bold"
893
- }, children: "\u2022" }),
894
- /* @__PURE__ */ jsxRuntime.jsx("code", { style: {
895
- background: "rgba(255, 255, 255, 0.2)",
896
- padding: "2px 6px",
897
- borderRadius: "4px",
898
- fontFamily: "monospace",
899
- fontSize: "12px"
900
- }, 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
+ )
901
1188
  ] }, index)) })
902
1189
  ] })
903
1190
  ] }),
@@ -980,7 +1267,18 @@ var AizekChatBot = ({ clientId, headers }) => {
980
1267
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: getLoadingSpinnerStyles() });
981
1268
  };
982
1269
  if (isConfigLoading) {
983
- 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
+ );
984
1282
  }
985
1283
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
986
1284
  isOpen && /* @__PURE__ */ jsxRuntime.jsx(
@@ -991,49 +1289,74 @@ var AizekChatBot = ({ clientId, headers }) => {
991
1289
  className: "floating-chat-overlay"
992
1290
  }
993
1291
  ),
994
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: getChatContainerStyles(buttonPosition, chatWidth, chatHeight, isOpen), className: "floating-chat-container", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getChatbotContainerStyles(), children: [
995
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getHeaderStyles(headerBackground), children: [
996
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: getLogoContainerStyles(), children: companyLogo ? companyLogo.startsWith("http") || companyLogo.startsWith("data:") ? /* @__PURE__ */ jsxRuntime.jsx(
997
- "img",
998
- {
999
- src: companyLogo,
1000
- alt: "Company Logo",
1001
- style: getLogoImageStyles()
1002
- }
1003
- ) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: getLogoTextStyles(), children: companyLogo }) : "\u{1F916}" }),
1004
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1005
- /* @__PURE__ */ jsxRuntime.jsx("h3", { style: getCompanyNameStyles(), children: companyName }),
1006
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: getStatusTextStyles(), children: isLoading ? "Yaz\u0131yor..." : "\xC7evrimi\xE7i" })
1007
- ] })
1008
- ] }),
1009
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getMessagesContainerStyles(), children: [
1010
- /* @__PURE__ */ jsxRuntime.jsx(HeaderValidationAlert, {}),
1011
- messages.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getEmptyStateStyles(), children: [
1012
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "48px", marginBottom: "16px" }, children: "\u{1F4AC}" }),
1013
- /* @__PURE__ */ jsxRuntime.jsx("h4", { style: { margin: "0 0 8px 0", fontSize: "18px" }, children: welcomeMessage }),
1014
- /* @__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." })
1015
- ] }) : messages.map((message) => /* @__PURE__ */ jsxRuntime.jsx(MessageBubble, { message }, message.id)),
1016
- showTypingIndicator && isLoading && messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1017
- MessageBubble,
1018
- {
1019
- message: {
1020
- id: "typing",
1021
- content: "",
1022
- role: "assistant",
1023
- timestamp: /* @__PURE__ */ new Date(),
1024
- isTyping: true
1025
- }
1026
- }
1292
+ /* @__PURE__ */ jsxRuntime.jsx(
1293
+ "div",
1294
+ {
1295
+ style: getChatContainerStyles(
1296
+ buttonPosition,
1297
+ chatWidth,
1298
+ chatHeight,
1299
+ isOpen
1027
1300
  ),
1028
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: messagesEndRef })
1029
- ] }),
1030
- /* @__PURE__ */ jsxRuntime.jsx(ChatInput, {})
1031
- ] }) }),
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
+ ),
1032
1350
  /* @__PURE__ */ jsxRuntime.jsx(
1033
1351
  "button",
1034
1352
  {
1035
1353
  onClick: toggleChat,
1036
- style: getFloatingButtonStyles(buttonPosition, buttonSize, buttonBackground, isOpen),
1354
+ style: getFloatingButtonStyles(
1355
+ buttonPosition,
1356
+ buttonSize,
1357
+ buttonBackground,
1358
+ isOpen
1359
+ ),
1037
1360
  onMouseEnter: (e) => {
1038
1361
  e.currentTarget.style.transform = isOpen ? "scale(0.85)" : "scale(1.1)";
1039
1362
  e.currentTarget.style.boxShadow = "0 6px 20px rgba(0, 0, 0, 0.25)";