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.mjs CHANGED
@@ -4,6 +4,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import OpenAI from 'openai';
5
5
  import ReactMarkdown from 'react-markdown';
6
6
  import remarkGfm from 'remark-gfm';
7
+ import DOMPurify from 'dompurify';
7
8
 
8
9
  // src/utils/cx.ts
9
10
  function cx(...args) {
@@ -118,8 +119,6 @@ var useChatbot = (options = {}) => {
118
119
  const getHtmlUiInstructions = (config2) => {
119
120
  const headerColor = config2?.headerBackground || "#f5f5f5";
120
121
  const accentColor = config2?.buttonBackground || "#007bff";
121
- const companyName = config2?.companyName || "AI Assistant";
122
- const companyLogo = config2?.companyLogo || "\u{1F916}";
123
122
  return `
124
123
  You are a helpful assistant that creates UI using ONLY HTML tags.
125
124
 
@@ -128,27 +127,23 @@ Your task:
128
127
  - Render your response as a small HTML layout (card OR table OR mini-table).
129
128
  - Use inline CSS styles.
130
129
  - Use a clean, light (white-based) theme.
131
- - Use branding and colors from options.config.
130
+ - Use colors from options.config (headerBackground, buttonBackground).
132
131
  - Return ONLY raw HTML (no markdown, no backticks, no JSON, no explanations).
133
132
 
134
133
  ====================
135
- THEME & BRANDING (from options.config)
134
+ THEME (from options.config)
136
135
  ====================
137
136
  The chat widget configuration provides:
138
137
 
139
138
  - Header Background Color: ${headerColor}
140
139
  - Button / Accent Color: ${accentColor}
141
- - Company Name: ${companyName}
142
- - Company Logo: ${companyLogo}
143
140
 
144
141
  How to use these:
145
142
  - Use Header Background Color mainly for top headers, title strips, or main highlight areas.
146
- - Use Button / Accent Color for important accents: borders, highlights, small badges, table headers, key text highlights, links, etc.
143
+ - Use Button / Accent Color for important accents: borders, highlights, badges, table headers, key text highlights, links, etc.
147
144
  - Use a white or very light background for main surfaces.
148
145
  - Text color should generally be dark (#111\u2013#333) for readability.
149
146
 
150
- Do NOT create real interactive buttons. You can visually style elements using the accent color, but you must NOT use <button>.
151
-
152
147
  ====================
153
148
  ALLOWED / FORBIDDEN TAGS
154
149
  ====================
@@ -167,7 +162,10 @@ You may use ANY NON-INTERACTIVE HTML element, for example:
167
162
  - Links (non-interactive navigation style only):
168
163
  <a>
169
164
 
170
- FORBIDDEN (NEVER USE):
165
+ GENERAL RULE:
166
+ - In NORMAL responses, you MUST NOT use <button>.
167
+
168
+ FORBIDDEN (NORMAL MODE):
171
169
  - <button>, <input>, <textarea>, <select>, <option>, <form>, <label>
172
170
  - <details>, <summary>, <dialog>
173
171
  - <video> or <audio> with controls for user interaction
@@ -214,15 +212,11 @@ General style (CARD or container):
214
212
  border-radius: 8px;
215
213
  padding: 12px;
216
214
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
215
+
216
+ Header area (if you use one):
217
217
  - You may add a top header area using the header background color:
218
218
  background: ${headerColor};
219
219
 
220
- Use branding:
221
- - Include the company logo and name in a subtle way when appropriate
222
- (for example, in a small header bar):
223
- - Logo (emoji or image) on the left,
224
- - Company name text next to it.
225
-
226
220
  Typography:
227
221
  - Titles: 18\u201322px, bold.
228
222
  - Body text: 12\u201316px, regular.
@@ -244,6 +238,37 @@ Links:
244
238
  - Use the accent color for links:
245
239
  color: ${accentColor};
246
240
 
241
+ ====================
242
+ CONFIRMATION MODE (SPECIAL CASE)
243
+ ====================
244
+ Sometimes, during a workflow or tool usage, you may need the user to confirm an action
245
+ (e.g., deleting a workflow, sending a transaction, performing an irreversible change).
246
+
247
+ In such CONFIRMATION cases ONLY:
248
+ - You ARE allowed to use exactly TWO <button> elements.
249
+ - They MUST be rendered with these exact data attributes:
250
+
251
+ <button data-ai-action="approve">Onayla</button>
252
+ <button data-ai-action="cancel">Vazge\xE7</button>
253
+
254
+ Rules for confirmation buttons:
255
+ - Do NOT add onclick or any other JS event attributes.
256
+ - Do NOT add custom data attributes besides data-ai-action.
257
+ - The host application will detect these buttons by data-ai-action
258
+ and will send the following messages back to you:
259
+ "__APPROVE__" when the user clicks "Onayla"
260
+ "__CANCEL__" when the user clicks "Vazge\xE7"
261
+
262
+ Behavior after user choice:
263
+ - When you receive "__APPROVE__", behave as if the user confirmed YES.
264
+ - When you receive "__CANCEL__", behave as if the user declined or cancelled.
265
+ - After that, go back to NORMAL mode and return standard HTML output again
266
+ (card, table, or mini table, WITHOUT <button>).
267
+
268
+ IMPORTANT:
269
+ - In NORMAL responses (no confirmation needed), you MUST NOT use <button>.
270
+ - In CONFIRMATION MODE, you MUST use exactly these two buttons and NO others.
271
+
247
272
  ====================
248
273
  OUTPUT FORMAT
249
274
  ====================
@@ -255,16 +280,21 @@ Your final output MUST follow these rules:
255
280
  - Must use exactly ONE of: card, table, mini table.
256
281
  - Must respect allowed/forbidden tags.
257
282
  - Must use colors derived from:
258
- - header_background
259
- - button_background
283
+ - headerBackground
284
+ - buttonBackground
260
285
  and otherwise a light theme.
261
286
 
262
287
  ====================
263
288
  BEHAVIOR SUMMARY
264
289
  ====================
265
290
  1) Read the user message.
266
- 2) Decide whether CARD, TABLE, or MINI TABLE is most suitable.
267
- 3) Generate a single HTML layout using only allowed, non-interactive tags.
291
+ 2) If it is a normal response:
292
+ - Decide whether CARD, TABLE, or MINI TABLE is most suitable.
293
+ - Generate a single HTML layout using only allowed, non-interactive tags (no <button>).
294
+ 3) If you need explicit user confirmation:
295
+ - Enter CONFIRMATION MODE.
296
+ - Render a short explanation AND exactly two <button> elements with:
297
+ data-ai-action="approve" and data-ai-action="cancel".
268
298
  4) Style the layout with inline CSS using:
269
299
  - ${headerColor} for header areas,
270
300
  - ${accentColor} for accents,
@@ -300,7 +330,9 @@ BEHAVIOR SUMMARY
300
330
  if (resp && Array.isArray(resp)) {
301
331
  const messageItem = resp.find((item) => item.type === "message");
302
332
  if (messageItem && messageItem.content && Array.isArray(messageItem.content)) {
303
- const textContent = messageItem.content.find((content) => content.type === "output_text");
333
+ const textContent = messageItem.content.find(
334
+ (content) => content.type === "output_text"
335
+ );
304
336
  if (textContent && textContent.text) {
305
337
  responseText = textContent.text;
306
338
  }
@@ -319,7 +351,10 @@ BEHAVIOR SUMMARY
319
351
  setIsLoading(false);
320
352
  } catch (error) {
321
353
  console.error("Error sending message:", error);
322
- addMessage("\xDCzg\xFCn\xFCm, bir hata olu\u015Ftu. L\xFCtfen tekrar deneyin.", "assistant");
354
+ addMessage(
355
+ "\xDCzg\xFCn\xFCm, bir hata olu\u015Ftu. L\xFCtfen tekrar deneyin.",
356
+ "assistant"
357
+ );
323
358
  setIsLoading(false);
324
359
  }
325
360
  };
@@ -378,7 +413,8 @@ var mapApiSettingsToConfig = (apiSettings) => {
378
413
  };
379
414
 
380
415
  // src/styles/messageStyles.ts
381
- var getMessageBubbleStyles = (isUser) => ({
416
+ var getMessageBubbleStyles = (isUser, isTyping) => ({
417
+ display: !isTyping && !isUser ? "none" : "block",
382
418
  maxWidth: "80%",
383
419
  padding: "12px 16px",
384
420
  borderRadius: isUser ? "18px 18px 4px 18px" : "18px 18px 18px 4px",
@@ -854,7 +890,10 @@ var getAlertAnimationStyles = () => `
854
890
  }
855
891
  }
856
892
  `;
857
- var AizekChatBot = ({ clientId, headers }) => {
893
+ var AizekChatBot = ({
894
+ clientId,
895
+ headers
896
+ }) => {
858
897
  const defaultConfig = {
859
898
  welcomeMessage: "Merhaba! Size nas\u0131l yard\u0131mc\u0131 olabilirim?",
860
899
  buttonBackground: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
@@ -873,27 +912,47 @@ var AizekChatBot = ({ clientId, headers }) => {
873
912
  const [isConfigLoading, setIsConfigLoading] = useState(true);
874
913
  const [finalMcpUrl, setFinalMcpUrl] = useState("");
875
914
  const [apiKey, setApiKey] = useState("");
876
- const { welcomeMessage, buttonBackground, placeholder, buttonPosition, buttonSize, chatWidth, chatHeight, showTypingIndicator, initialOpen, headerBackground, companyLogo, companyName } = config;
915
+ const {
916
+ welcomeMessage,
917
+ buttonBackground,
918
+ placeholder,
919
+ buttonPosition,
920
+ buttonSize,
921
+ chatWidth,
922
+ chatHeight,
923
+ showTypingIndicator,
924
+ initialOpen,
925
+ headerBackground,
926
+ companyLogo,
927
+ companyName
928
+ } = config;
877
929
  const [isOpen, setIsOpen] = useState(false);
878
930
  const [headerValidation, setHeaderValidation] = useState(null);
879
931
  const [showAlert, setShowAlert] = useState(true);
932
+ console.log("Component rendered");
880
933
  useEffect(() => {
881
- console.log("render");
934
+ console.log("use");
882
935
  const loadConfig = async () => {
883
936
  try {
884
937
  setIsConfigLoading(true);
885
938
  const apiResponse = await fetchChatWidgetSettings(clientId);
886
939
  if (headers && apiResponse.data.auth_config) {
887
- const validationResult = validateHeaders(headers, apiResponse.data.auth_config, {
888
- allowExtra: false,
889
- caseSensitive: true
890
- });
940
+ const validationResult = validateHeaders(
941
+ headers,
942
+ apiResponse.data.auth_config,
943
+ {
944
+ allowExtra: false,
945
+ caseSensitive: true
946
+ }
947
+ );
891
948
  console.log(validationResult);
892
949
  setHeaderValidation(validationResult);
893
950
  }
894
951
  setFinalMcpUrl(apiResponse.data.mcp_url);
895
952
  setApiKey(apiResponse.data.openai_key || "");
896
- const apiConfig = mapApiSettingsToConfig(apiResponse.data.chat_widget_settings);
953
+ const apiConfig = mapApiSettingsToConfig(
954
+ apiResponse.data.chat_widget_settings
955
+ );
897
956
  if (apiConfig) {
898
957
  setConfig(apiConfig);
899
958
  }
@@ -906,7 +965,12 @@ var AizekChatBot = ({ clientId, headers }) => {
906
965
  };
907
966
  loadConfig();
908
967
  }, [clientId]);
909
- const internalChatbot = useChatbot({ mcpUrl: finalMcpUrl, apiKey, headers, config });
968
+ const internalChatbot = useChatbot({
969
+ mcpUrl: finalMcpUrl,
970
+ apiKey,
971
+ headers,
972
+ config
973
+ });
910
974
  const messages = internalChatbot.messages;
911
975
  const isLoading = internalChatbot.isLoading;
912
976
  const handleSendMessage = internalChatbot.sendMessage;
@@ -921,18 +985,39 @@ var AizekChatBot = ({ clientId, headers }) => {
921
985
  useEffect(() => {
922
986
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
923
987
  }, [messages]);
924
- const MessageBubble = ({ message }) => {
988
+ const MessageBubble = ({ message, onAction }) => {
925
989
  const isUser = message.role === "user";
990
+ const cleanContent = DOMPurify.sanitize(message.content);
991
+ const htmlRef = useRef(null);
992
+ useEffect(() => {
993
+ if (!htmlRef.current || isUser) return;
994
+ const root = htmlRef.current;
995
+ const approveBtn = root.querySelector(
996
+ 'button[data-ai-action="approve"]'
997
+ );
998
+ const cancelBtn = root.querySelector(
999
+ 'button[data-ai-action="cancel"]'
1000
+ );
1001
+ const handleApprove = () => onAction("__APPROVE__");
1002
+ const handleCancel = () => onAction("__CANCEL__");
1003
+ if (approveBtn) approveBtn.addEventListener("click", handleApprove);
1004
+ if (cancelBtn) cancelBtn.addEventListener("click", handleCancel);
1005
+ return () => {
1006
+ if (approveBtn) approveBtn.removeEventListener("click", handleApprove);
1007
+ if (cancelBtn) cancelBtn.removeEventListener("click", handleCancel);
1008
+ };
1009
+ }, [message.content, isUser, onAction]);
926
1010
  return /* @__PURE__ */ jsxs("div", { style: getMessageContainerStyles(isUser), children: [
927
1011
  /* @__PURE__ */ jsx("style", { children: getMarkdownElementStyles(isUser) }),
928
- /* @__PURE__ */ jsxs("div", { style: getMessageBubbleStyles(isUser), children: [
929
- isUser ? /* @__PURE__ */ jsx("div", { style: getMarkdownStyles(), className: "markdown-content", children: /* @__PURE__ */ jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], children: message.content }) }) : /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: message.content } }),
1012
+ /* @__PURE__ */ jsxs("div", { style: getMessageBubbleStyles(isUser, message.isTyping ?? false), children: [
1013
+ isUser && /* @__PURE__ */ jsx("div", { style: getMarkdownStyles(), className: "markdown-content", children: /* @__PURE__ */ jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], children: message.content }) }),
930
1014
  message.isTyping && /* @__PURE__ */ jsx("div", { style: {
931
1015
  display: "inline-flex",
932
1016
  alignItems: "center",
933
1017
  marginLeft: "8px"
934
1018
  }, children: /* @__PURE__ */ jsx(TypingDots, {}) })
935
1019
  ] }),
1020
+ !isUser && /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: cleanContent } }),
936
1021
  /* @__PURE__ */ jsx("div", { style: getTimeStyles(isUser), children: message.timestamp.toLocaleTimeString("tr-TR", {
937
1022
  hour: "2-digit",
938
1023
  minute: "2-digit"
@@ -977,60 +1062,102 @@ var AizekChatBot = ({ clientId, headers }) => {
977
1062
  missingKeys.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
978
1063
  /* @__PURE__ */ jsx("strong", { style: { fontSize: "13px" }, children: "Eksik Header'lar:" }),
979
1064
  /* @__PURE__ */ jsx("ul", { style: getAlertListStyles(), children: missingKeys.map((key, index) => /* @__PURE__ */ jsxs("li", { style: getAlertListItemStyles(), children: [
980
- /* @__PURE__ */ jsx("span", { style: {
981
- position: "absolute",
982
- left: "0",
983
- top: "2px",
984
- fontWeight: "bold"
985
- }, children: "\u2022" }),
986
- /* @__PURE__ */ jsx("code", { style: {
987
- background: "rgba(255, 255, 255, 0.2)",
988
- padding: "2px 6px",
989
- borderRadius: "4px",
990
- fontFamily: "monospace",
991
- fontSize: "12px"
992
- }, children: key })
1065
+ /* @__PURE__ */ jsx(
1066
+ "span",
1067
+ {
1068
+ style: {
1069
+ position: "absolute",
1070
+ left: "0",
1071
+ top: "2px",
1072
+ fontWeight: "bold"
1073
+ },
1074
+ children: "\u2022"
1075
+ }
1076
+ ),
1077
+ /* @__PURE__ */ jsx(
1078
+ "code",
1079
+ {
1080
+ style: {
1081
+ background: "rgba(255, 255, 255, 0.2)",
1082
+ padding: "2px 6px",
1083
+ borderRadius: "4px",
1084
+ fontFamily: "monospace",
1085
+ fontSize: "12px"
1086
+ },
1087
+ children: key
1088
+ }
1089
+ )
993
1090
  ] }, index)) })
994
1091
  ] }),
995
1092
  emptyValueKeys.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
996
1093
  /* @__PURE__ */ jsx("strong", { style: { fontSize: "13px" }, children: "Bo\u015F De\u011Ferli Header'lar:" }),
997
1094
  /* @__PURE__ */ jsx("ul", { style: getAlertListStyles(), children: emptyValueKeys.map((key, index) => /* @__PURE__ */ jsxs("li", { style: getAlertListItemStyles(), children: [
998
- /* @__PURE__ */ jsx("span", { style: {
999
- position: "absolute",
1000
- left: "0",
1001
- top: "2px",
1002
- fontWeight: "bold"
1003
- }, children: "\u2022" }),
1004
- /* @__PURE__ */ jsx("code", { style: {
1005
- background: "rgba(255, 255, 255, 0.2)",
1006
- padding: "2px 6px",
1007
- borderRadius: "4px",
1008
- fontFamily: "monospace",
1009
- fontSize: "12px"
1010
- }, children: key }),
1011
- /* @__PURE__ */ jsx("span", { style: {
1012
- marginLeft: "6px",
1013
- fontSize: "11px",
1014
- opacity: 0.9
1015
- }, children: "(de\u011Fer bo\u015F olamaz)" })
1095
+ /* @__PURE__ */ jsx(
1096
+ "span",
1097
+ {
1098
+ style: {
1099
+ position: "absolute",
1100
+ left: "0",
1101
+ top: "2px",
1102
+ fontWeight: "bold"
1103
+ },
1104
+ children: "\u2022"
1105
+ }
1106
+ ),
1107
+ /* @__PURE__ */ jsx(
1108
+ "code",
1109
+ {
1110
+ style: {
1111
+ background: "rgba(255, 255, 255, 0.2)",
1112
+ padding: "2px 6px",
1113
+ borderRadius: "4px",
1114
+ fontFamily: "monospace",
1115
+ fontSize: "12px"
1116
+ },
1117
+ children: key
1118
+ }
1119
+ ),
1120
+ /* @__PURE__ */ jsx(
1121
+ "span",
1122
+ {
1123
+ style: {
1124
+ marginLeft: "6px",
1125
+ fontSize: "11px",
1126
+ opacity: 0.9
1127
+ },
1128
+ children: "(de\u011Fer bo\u015F olamaz)"
1129
+ }
1130
+ )
1016
1131
  ] }, index)) })
1017
1132
  ] }),
1018
1133
  extraKeys.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
1019
1134
  /* @__PURE__ */ jsx("strong", { style: { fontSize: "13px" }, children: "Fazla Header'lar:" }),
1020
1135
  /* @__PURE__ */ jsx("ul", { style: getAlertListStyles(), children: extraKeys.map((key, index) => /* @__PURE__ */ jsxs("li", { style: getAlertListItemStyles(), children: [
1021
- /* @__PURE__ */ jsx("span", { style: {
1022
- position: "absolute",
1023
- left: "0",
1024
- top: "2px",
1025
- fontWeight: "bold"
1026
- }, children: "\u2022" }),
1027
- /* @__PURE__ */ jsx("code", { style: {
1028
- background: "rgba(255, 255, 255, 0.2)",
1029
- padding: "2px 6px",
1030
- borderRadius: "4px",
1031
- fontFamily: "monospace",
1032
- fontSize: "12px"
1033
- }, children: key })
1136
+ /* @__PURE__ */ jsx(
1137
+ "span",
1138
+ {
1139
+ style: {
1140
+ position: "absolute",
1141
+ left: "0",
1142
+ top: "2px",
1143
+ fontWeight: "bold"
1144
+ },
1145
+ children: "\u2022"
1146
+ }
1147
+ ),
1148
+ /* @__PURE__ */ jsx(
1149
+ "code",
1150
+ {
1151
+ style: {
1152
+ background: "rgba(255, 255, 255, 0.2)",
1153
+ padding: "2px 6px",
1154
+ borderRadius: "4px",
1155
+ fontFamily: "monospace",
1156
+ fontSize: "12px"
1157
+ },
1158
+ children: key
1159
+ }
1160
+ )
1034
1161
  ] }, index)) })
1035
1162
  ] })
1036
1163
  ] }),
@@ -1113,7 +1240,18 @@ var AizekChatBot = ({ clientId, headers }) => {
1113
1240
  return /* @__PURE__ */ jsx("div", { style: getLoadingSpinnerStyles() });
1114
1241
  };
1115
1242
  if (isConfigLoading) {
1116
- return /* @__PURE__ */ jsx("div", { style: getFloatingButtonStyles(buttonPosition, buttonSize, buttonBackground, false), children: /* @__PURE__ */ jsx("div", { style: getLoadingSpinnerStyles() }) });
1243
+ return /* @__PURE__ */ jsx(
1244
+ "div",
1245
+ {
1246
+ style: getFloatingButtonStyles(
1247
+ buttonPosition,
1248
+ buttonSize,
1249
+ buttonBackground,
1250
+ false
1251
+ ),
1252
+ children: /* @__PURE__ */ jsx("div", { style: getLoadingSpinnerStyles() })
1253
+ }
1254
+ );
1117
1255
  }
1118
1256
  return /* @__PURE__ */ jsxs(Fragment, { children: [
1119
1257
  isOpen && /* @__PURE__ */ jsx(
@@ -1124,49 +1262,74 @@ var AizekChatBot = ({ clientId, headers }) => {
1124
1262
  className: "floating-chat-overlay"
1125
1263
  }
1126
1264
  ),
1127
- /* @__PURE__ */ jsx("div", { style: getChatContainerStyles(buttonPosition, chatWidth, chatHeight, isOpen), className: "floating-chat-container", children: /* @__PURE__ */ jsxs("div", { style: getChatbotContainerStyles(), children: [
1128
- /* @__PURE__ */ jsxs("div", { style: getHeaderStyles(headerBackground), children: [
1129
- /* @__PURE__ */ jsx("div", { style: getLogoContainerStyles(), children: companyLogo ? companyLogo.startsWith("http") || companyLogo.startsWith("data:") ? /* @__PURE__ */ jsx(
1130
- "img",
1131
- {
1132
- src: companyLogo,
1133
- alt: "Company Logo",
1134
- style: getLogoImageStyles()
1135
- }
1136
- ) : /* @__PURE__ */ jsx("span", { style: getLogoTextStyles(), children: companyLogo }) : "\u{1F916}" }),
1137
- /* @__PURE__ */ jsxs("div", { children: [
1138
- /* @__PURE__ */ jsx("h3", { style: getCompanyNameStyles(), children: companyName }),
1139
- /* @__PURE__ */ jsx("p", { style: getStatusTextStyles(), children: isLoading ? "Yaz\u0131yor..." : "\xC7evrimi\xE7i" })
1140
- ] })
1141
- ] }),
1142
- /* @__PURE__ */ jsxs("div", { style: getMessagesContainerStyles(), children: [
1143
- /* @__PURE__ */ jsx(HeaderValidationAlert, {}),
1144
- messages.length === 0 ? /* @__PURE__ */ jsxs("div", { style: getEmptyStateStyles(), children: [
1145
- /* @__PURE__ */ jsx("div", { style: { fontSize: "48px", marginBottom: "16px" }, children: "\u{1F4AC}" }),
1146
- /* @__PURE__ */ jsx("h4", { style: { margin: "0 0 8px 0", fontSize: "18px" }, children: welcomeMessage }),
1147
- /* @__PURE__ */ jsx("p", { style: { margin: 0, fontSize: "14px", opacity: 0.8 }, children: "A\u015Fa\u011F\u0131daki alana mesaj\u0131n\u0131z\u0131 yazarak ba\u015Flayabilirsiniz." })
1148
- ] }) : messages.map((message) => /* @__PURE__ */ jsx(MessageBubble, { message }, message.id)),
1149
- showTypingIndicator && isLoading && messages.length > 0 && /* @__PURE__ */ jsx(
1150
- MessageBubble,
1151
- {
1152
- message: {
1153
- id: "typing",
1154
- content: "",
1155
- role: "assistant",
1156
- timestamp: /* @__PURE__ */ new Date(),
1157
- isTyping: true
1158
- }
1159
- }
1265
+ /* @__PURE__ */ jsx(
1266
+ "div",
1267
+ {
1268
+ style: getChatContainerStyles(
1269
+ buttonPosition,
1270
+ chatWidth,
1271
+ chatHeight,
1272
+ isOpen
1160
1273
  ),
1161
- /* @__PURE__ */ jsx("div", { ref: messagesEndRef })
1162
- ] }),
1163
- /* @__PURE__ */ jsx(ChatInput, {})
1164
- ] }) }),
1274
+ className: "floating-chat-container",
1275
+ children: /* @__PURE__ */ jsxs("div", { style: getChatbotContainerStyles(), children: [
1276
+ /* @__PURE__ */ jsxs("div", { style: getHeaderStyles(headerBackground), children: [
1277
+ /* @__PURE__ */ jsx("div", { style: getLogoContainerStyles(), children: companyLogo ? companyLogo.startsWith("http") || companyLogo.startsWith("data:") ? /* @__PURE__ */ jsx(
1278
+ "img",
1279
+ {
1280
+ src: companyLogo,
1281
+ alt: "Company Logo",
1282
+ style: getLogoImageStyles()
1283
+ }
1284
+ ) : /* @__PURE__ */ jsx("span", { style: getLogoTextStyles(), children: companyLogo }) : "\u{1F916}" }),
1285
+ /* @__PURE__ */ jsxs("div", { children: [
1286
+ /* @__PURE__ */ jsx("h3", { style: getCompanyNameStyles(), children: companyName }),
1287
+ /* @__PURE__ */ jsx("p", { style: getStatusTextStyles(), children: isLoading ? "Yaz\u0131yor..." : "\xC7evrimi\xE7i" })
1288
+ ] })
1289
+ ] }),
1290
+ /* @__PURE__ */ jsxs("div", { style: getMessagesContainerStyles(), children: [
1291
+ /* @__PURE__ */ jsx(HeaderValidationAlert, {}),
1292
+ messages.length === 0 ? /* @__PURE__ */ jsxs("div", { style: getEmptyStateStyles(), children: [
1293
+ /* @__PURE__ */ jsx("div", { style: { fontSize: "48px", marginBottom: "16px" }, children: "\u{1F4AC}" }),
1294
+ /* @__PURE__ */ jsx("h4", { style: { margin: "0 0 8px 0", fontSize: "18px" }, children: welcomeMessage }),
1295
+ /* @__PURE__ */ jsx("p", { style: { margin: 0, fontSize: "14px", opacity: 0.8 }, children: "A\u015Fa\u011F\u0131daki alana mesaj\u0131n\u0131z\u0131 yazarak ba\u015Flayabilirsiniz." })
1296
+ ] }) : messages.map((message) => /* @__PURE__ */ jsx(
1297
+ MessageBubble,
1298
+ {
1299
+ message,
1300
+ onAction: handleSendMessage
1301
+ },
1302
+ message.id
1303
+ )),
1304
+ showTypingIndicator && isLoading && messages.length > 0 && /* @__PURE__ */ jsx(
1305
+ MessageBubble,
1306
+ {
1307
+ message: {
1308
+ id: "typing",
1309
+ content: "",
1310
+ role: "assistant",
1311
+ timestamp: /* @__PURE__ */ new Date(),
1312
+ isTyping: true
1313
+ },
1314
+ onAction: handleSendMessage
1315
+ }
1316
+ ),
1317
+ /* @__PURE__ */ jsx("div", { ref: messagesEndRef })
1318
+ ] }),
1319
+ /* @__PURE__ */ jsx(ChatInput, {})
1320
+ ] })
1321
+ }
1322
+ ),
1165
1323
  /* @__PURE__ */ jsx(
1166
1324
  "button",
1167
1325
  {
1168
1326
  onClick: toggleChat,
1169
- style: getFloatingButtonStyles(buttonPosition, buttonSize, buttonBackground, isOpen),
1327
+ style: getFloatingButtonStyles(
1328
+ buttonPosition,
1329
+ buttonSize,
1330
+ buttonBackground,
1331
+ isOpen
1332
+ ),
1170
1333
  onMouseEnter: (e) => {
1171
1334
  e.currentTarget.style.transform = isOpen ? "scale(0.85)" : "scale(1.1)";
1172
1335
  e.currentTarget.style.boxShadow = "0 6px 20px rgba(0, 0, 0, 0.25)";