strapi-plugin-faqchatbot 1.0.1 → 1.0.3

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.
@@ -24975,7 +24975,7 @@ const ChatWindowWrapper = styled__default.default(designSystem.Box)`
24975
24975
  height: 500px;
24976
24976
  z-index: 1000;
24977
24977
  overflow: hidden;
24978
- box-shadow: 0 10px 40px rgba(0,0,0,0.2);
24978
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
24979
24979
  border: 1px solid ${({ theme }) => theme.colors.neutral150};
24980
24980
  transform-origin: bottom right;
24981
24981
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
@@ -25023,23 +25023,41 @@ const ChatbotPreview = () => {
25023
25023
  setMessages((prev) => [...prev, { text: userText, isUser: true }]);
25024
25024
  setChatInput("");
25025
25025
  try {
25026
- const res = await fetch("/api/faqchatbot/ask", {
25026
+ const res = await fetch("/api/faqchatbot-config/ask", {
25027
25027
  method: "POST",
25028
25028
  headers: { "Content-Type": "application/json" },
25029
- body: JSON.stringify({
25030
- question: userText
25031
- })
25029
+ body: JSON.stringify({ question: userText })
25032
25030
  });
25033
- const data = await res.json();
25034
- setMessages((prev) => [
25035
- ...prev,
25036
- { text: data.content || "No response", isUser: false }
25037
- ]);
25031
+ if (!res.ok) throw new Error("Request failed");
25032
+ const reader = res.body?.getReader();
25033
+ if (!reader) throw new Error("No stream");
25034
+ const decoder = new TextDecoder();
25035
+ let botMessage = "";
25036
+ setMessages((prev) => [...prev, { text: "", isUser: false }]);
25037
+ while (true) {
25038
+ const { done, value } = await reader.read();
25039
+ if (done) break;
25040
+ const chunk = decoder.decode(value, { stream: true });
25041
+ const lines = chunk.split("\n");
25042
+ for (let rawLine of lines) {
25043
+ const line = rawLine.replace(/\r/g, "");
25044
+ if (line.includes("[DONE]")) return;
25045
+ if (line.startsWith("data: ")) {
25046
+ const token = line.replace("data: ", "");
25047
+ botMessage += token;
25048
+ setMessages((prev) => {
25049
+ const updated = [...prev];
25050
+ updated[updated.length - 1] = {
25051
+ text: botMessage,
25052
+ isUser: false
25053
+ };
25054
+ return updated;
25055
+ });
25056
+ }
25057
+ }
25058
+ }
25038
25059
  } catch (err) {
25039
- setMessages((prev) => [
25040
- ...prev,
25041
- { text: "Error contacting chatbot", isUser: false }
25042
- ]);
25060
+ setMessages((prev) => [...prev, { text: "Error contacting chatbot", isUser: false }]);
25043
25061
  }
25044
25062
  };
25045
25063
  const handleClearHistory = () => {
@@ -25052,14 +25070,74 @@ const ChatbotPreview = () => {
25052
25070
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
25053
25071
  /* @__PURE__ */ jsxRuntime.jsx(icons.Message, { color: "neutral0", width: 18 }),
25054
25072
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral0", children: "Chatbot Preview" }),
25055
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { as: "button", onClick: handleClearHistory, style: { background: "none", border: "none", cursor: "pointer", display: "flex" }, title: "Clear History", children: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowClockwise, { color: "neutral0", width: 14 }) })
25073
+ /* @__PURE__ */ jsxRuntime.jsx(
25074
+ designSystem.Box,
25075
+ {
25076
+ as: "button",
25077
+ onClick: handleClearHistory,
25078
+ style: { background: "none", border: "none", cursor: "pointer", display: "flex" },
25079
+ title: "Clear History",
25080
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowClockwise, { color: "neutral0", width: 14 })
25081
+ }
25082
+ )
25056
25083
  ] }),
25057
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { as: "button", onClick: () => setIsOpen(false), style: { background: "none", border: "none", cursor: "pointer", display: "flex" }, title: "Close Chat", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, { color: "neutral0", width: 14 }) })
25084
+ /* @__PURE__ */ jsxRuntime.jsx(
25085
+ designSystem.Box,
25086
+ {
25087
+ as: "button",
25088
+ onClick: () => setIsOpen(false),
25089
+ style: { background: "none", border: "none", cursor: "pointer", display: "flex" },
25090
+ title: "Close Chat",
25091
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, { color: "neutral0", width: 14 })
25092
+ }
25093
+ )
25058
25094
  ] }) }),
25059
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { ref: scrollRef, padding: 4, background: "neutral100", style: { flex: 1, overflowY: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 3, children: messages.map((msg, idx) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 3, hasRadius: true, background: msg.isUser ? "primary600" : "neutral0", shadow: "filterShadow", style: { alignSelf: msg.isUser ? "flex-end" : "flex-start", maxWidth: "85%" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: msg.isUser ? "neutral0" : "neutral800", children: msg.text }) }, idx)) }) }),
25095
+ /* @__PURE__ */ jsxRuntime.jsx(
25096
+ designSystem.Box,
25097
+ {
25098
+ ref: scrollRef,
25099
+ padding: 4,
25100
+ background: "neutral100",
25101
+ style: { flex: 1, overflowY: "auto" },
25102
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 3, children: messages.map((msg, idx) => /* @__PURE__ */ jsxRuntime.jsx(
25103
+ designSystem.Box,
25104
+ {
25105
+ padding: 3,
25106
+ hasRadius: true,
25107
+ background: msg.isUser ? "primary600" : "neutral0",
25108
+ shadow: "filterShadow",
25109
+ style: {
25110
+ alignSelf: msg.isUser ? "flex-end" : "flex-start",
25111
+ maxWidth: "85%",
25112
+ wordBreak: "break-word",
25113
+ overflowWrap: "anywhere",
25114
+ whiteSpace: "pre-wrap"
25115
+ },
25116
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: msg.isUser ? "neutral0" : "neutral800", children: msg.text })
25117
+ },
25118
+ idx
25119
+ )) })
25120
+ }
25121
+ ),
25060
25122
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 3, background: "neutral0", style: { borderTop: "1px solid #f0f0f5" }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
25061
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { flexGrow: 1 }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.TextInput, { placeholder: "Type a message...", value: chatInput, onChange: (e2) => setChatInput(e2.target.value), onKeyDown: (e2) => e2.key === "Enter" && handleSendMessage() }) }),
25062
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleSendMessage, style: { height: "40px" }, startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.PaperPlane, {}), children: "Send" })
25123
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { flexGrow: 1 }, children: /* @__PURE__ */ jsxRuntime.jsx(
25124
+ designSystem.TextInput,
25125
+ {
25126
+ placeholder: "Type a message...",
25127
+ value: chatInput,
25128
+ onChange: (e2) => setChatInput(e2.target.value),
25129
+ onKeyDown: (e2) => e2.key === "Enter" && handleSendMessage()
25130
+ }
25131
+ ) }),
25132
+ /* @__PURE__ */ jsxRuntime.jsx(
25133
+ designSystem.Button,
25134
+ {
25135
+ onClick: handleSendMessage,
25136
+ style: { height: "40px" },
25137
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.PaperPlane, {}),
25138
+ children: "Send"
25139
+ }
25140
+ )
25063
25141
  ] }) })
25064
25142
  ] }) })
25065
25143
  ] });
@@ -24974,7 +24974,7 @@ const ChatWindowWrapper = styled$1(Box)`
24974
24974
  height: 500px;
24975
24975
  z-index: 1000;
24976
24976
  overflow: hidden;
24977
- box-shadow: 0 10px 40px rgba(0,0,0,0.2);
24977
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
24978
24978
  border: 1px solid ${({ theme }) => theme.colors.neutral150};
24979
24979
  transform-origin: bottom right;
24980
24980
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
@@ -25022,23 +25022,41 @@ const ChatbotPreview = () => {
25022
25022
  setMessages((prev) => [...prev, { text: userText, isUser: true }]);
25023
25023
  setChatInput("");
25024
25024
  try {
25025
- const res = await fetch("/api/faqchatbot/ask", {
25025
+ const res = await fetch("/api/faqchatbot-config/ask", {
25026
25026
  method: "POST",
25027
25027
  headers: { "Content-Type": "application/json" },
25028
- body: JSON.stringify({
25029
- question: userText
25030
- })
25028
+ body: JSON.stringify({ question: userText })
25031
25029
  });
25032
- const data = await res.json();
25033
- setMessages((prev) => [
25034
- ...prev,
25035
- { text: data.content || "No response", isUser: false }
25036
- ]);
25030
+ if (!res.ok) throw new Error("Request failed");
25031
+ const reader = res.body?.getReader();
25032
+ if (!reader) throw new Error("No stream");
25033
+ const decoder = new TextDecoder();
25034
+ let botMessage = "";
25035
+ setMessages((prev) => [...prev, { text: "", isUser: false }]);
25036
+ while (true) {
25037
+ const { done, value } = await reader.read();
25038
+ if (done) break;
25039
+ const chunk = decoder.decode(value, { stream: true });
25040
+ const lines = chunk.split("\n");
25041
+ for (let rawLine of lines) {
25042
+ const line = rawLine.replace(/\r/g, "");
25043
+ if (line.includes("[DONE]")) return;
25044
+ if (line.startsWith("data: ")) {
25045
+ const token = line.replace("data: ", "");
25046
+ botMessage += token;
25047
+ setMessages((prev) => {
25048
+ const updated = [...prev];
25049
+ updated[updated.length - 1] = {
25050
+ text: botMessage,
25051
+ isUser: false
25052
+ };
25053
+ return updated;
25054
+ });
25055
+ }
25056
+ }
25057
+ }
25037
25058
  } catch (err) {
25038
- setMessages((prev) => [
25039
- ...prev,
25040
- { text: "Error contacting chatbot", isUser: false }
25041
- ]);
25059
+ setMessages((prev) => [...prev, { text: "Error contacting chatbot", isUser: false }]);
25042
25060
  }
25043
25061
  };
25044
25062
  const handleClearHistory = () => {
@@ -25051,14 +25069,74 @@ const ChatbotPreview = () => {
25051
25069
  /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
25052
25070
  /* @__PURE__ */ jsx(Message, { color: "neutral0", width: 18 }),
25053
25071
  /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral0", children: "Chatbot Preview" }),
25054
- /* @__PURE__ */ jsx(Box, { as: "button", onClick: handleClearHistory, style: { background: "none", border: "none", cursor: "pointer", display: "flex" }, title: "Clear History", children: /* @__PURE__ */ jsx(ArrowClockwise, { color: "neutral0", width: 14 }) })
25072
+ /* @__PURE__ */ jsx(
25073
+ Box,
25074
+ {
25075
+ as: "button",
25076
+ onClick: handleClearHistory,
25077
+ style: { background: "none", border: "none", cursor: "pointer", display: "flex" },
25078
+ title: "Clear History",
25079
+ children: /* @__PURE__ */ jsx(ArrowClockwise, { color: "neutral0", width: 14 })
25080
+ }
25081
+ )
25055
25082
  ] }),
25056
- /* @__PURE__ */ jsx(Box, { as: "button", onClick: () => setIsOpen(false), style: { background: "none", border: "none", cursor: "pointer", display: "flex" }, title: "Close Chat", children: /* @__PURE__ */ jsx(Cross, { color: "neutral0", width: 14 }) })
25083
+ /* @__PURE__ */ jsx(
25084
+ Box,
25085
+ {
25086
+ as: "button",
25087
+ onClick: () => setIsOpen(false),
25088
+ style: { background: "none", border: "none", cursor: "pointer", display: "flex" },
25089
+ title: "Close Chat",
25090
+ children: /* @__PURE__ */ jsx(Cross, { color: "neutral0", width: 14 })
25091
+ }
25092
+ )
25057
25093
  ] }) }),
25058
- /* @__PURE__ */ jsx(Box, { ref: scrollRef, padding: 4, background: "neutral100", style: { flex: 1, overflowY: "auto" }, children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 3, children: messages.map((msg, idx) => /* @__PURE__ */ jsx(Box, { padding: 3, hasRadius: true, background: msg.isUser ? "primary600" : "neutral0", shadow: "filterShadow", style: { alignSelf: msg.isUser ? "flex-end" : "flex-start", maxWidth: "85%" }, children: /* @__PURE__ */ jsx(Typography, { textColor: msg.isUser ? "neutral0" : "neutral800", children: msg.text }) }, idx)) }) }),
25094
+ /* @__PURE__ */ jsx(
25095
+ Box,
25096
+ {
25097
+ ref: scrollRef,
25098
+ padding: 4,
25099
+ background: "neutral100",
25100
+ style: { flex: 1, overflowY: "auto" },
25101
+ children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 3, children: messages.map((msg, idx) => /* @__PURE__ */ jsx(
25102
+ Box,
25103
+ {
25104
+ padding: 3,
25105
+ hasRadius: true,
25106
+ background: msg.isUser ? "primary600" : "neutral0",
25107
+ shadow: "filterShadow",
25108
+ style: {
25109
+ alignSelf: msg.isUser ? "flex-end" : "flex-start",
25110
+ maxWidth: "85%",
25111
+ wordBreak: "break-word",
25112
+ overflowWrap: "anywhere",
25113
+ whiteSpace: "pre-wrap"
25114
+ },
25115
+ children: /* @__PURE__ */ jsx(Typography, { textColor: msg.isUser ? "neutral0" : "neutral800", children: msg.text })
25116
+ },
25117
+ idx
25118
+ )) })
25119
+ }
25120
+ ),
25059
25121
  /* @__PURE__ */ jsx(Box, { padding: 3, background: "neutral0", style: { borderTop: "1px solid #f0f0f5" }, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
25060
- /* @__PURE__ */ jsx(Box, { style: { flexGrow: 1 }, children: /* @__PURE__ */ jsx(TextInput, { placeholder: "Type a message...", value: chatInput, onChange: (e2) => setChatInput(e2.target.value), onKeyDown: (e2) => e2.key === "Enter" && handleSendMessage() }) }),
25061
- /* @__PURE__ */ jsx(Button, { onClick: handleSendMessage, style: { height: "40px" }, startIcon: /* @__PURE__ */ jsx(PaperPlane, {}), children: "Send" })
25122
+ /* @__PURE__ */ jsx(Box, { style: { flexGrow: 1 }, children: /* @__PURE__ */ jsx(
25123
+ TextInput,
25124
+ {
25125
+ placeholder: "Type a message...",
25126
+ value: chatInput,
25127
+ onChange: (e2) => setChatInput(e2.target.value),
25128
+ onKeyDown: (e2) => e2.key === "Enter" && handleSendMessage()
25129
+ }
25130
+ ) }),
25131
+ /* @__PURE__ */ jsx(
25132
+ Button,
25133
+ {
25134
+ onClick: handleSendMessage,
25135
+ style: { height: "40px" },
25136
+ startIcon: /* @__PURE__ */ jsx(PaperPlane, {}),
25137
+ children: "Send"
25138
+ }
25139
+ )
25062
25140
  ] }) })
25063
25141
  ] }) })
25064
25142
  ] });
@@ -26,7 +26,7 @@ const Initializer = ({ setPlugin }) => {
26
26
  }, []);
27
27
  return null;
28
28
  };
29
- const PluginIcon = () => /* @__PURE__ */ jsxRuntime.jsx(icons.PuzzlePiece, {});
29
+ const PluginIcon = () => /* @__PURE__ */ jsxRuntime.jsx(icons.Discuss, {});
30
30
  const index = {
31
31
  register(app) {
32
32
  app.addMenuLink({
@@ -37,7 +37,7 @@ const index = {
37
37
  defaultMessage: PLUGIN_ID
38
38
  },
39
39
  Component: async () => {
40
- const { App } = await Promise.resolve().then(() => require("../_chunks/App-Cn0wk9Bd.js"));
40
+ const { App } = await Promise.resolve().then(() => require("../_chunks/App-DXMGIi8p.js"));
41
41
  return App;
42
42
  }
43
43
  });
@@ -1,6 +1,6 @@
1
1
  import { useRef, useEffect } from "react";
2
2
  import { jsx } from "react/jsx-runtime";
3
- import { PuzzlePiece } from "@strapi/icons";
3
+ import { Discuss } from "@strapi/icons";
4
4
  const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
5
5
  const v = glob[path];
6
6
  if (v) {
@@ -25,7 +25,7 @@ const Initializer = ({ setPlugin }) => {
25
25
  }, []);
26
26
  return null;
27
27
  };
28
- const PluginIcon = () => /* @__PURE__ */ jsx(PuzzlePiece, {});
28
+ const PluginIcon = () => /* @__PURE__ */ jsx(Discuss, {});
29
29
  const index = {
30
30
  register(app) {
31
31
  app.addMenuLink({
@@ -36,7 +36,7 @@ const index = {
36
36
  defaultMessage: PLUGIN_ID
37
37
  },
38
38
  Component: async () => {
39
- const { App } = await import("../_chunks/App-B02Agl-6.mjs");
39
+ const { App } = await import("../_chunks/App-Dq5zlyVl.mjs");
40
40
  return App;
41
41
  }
42
42
  });
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.1",
2
+ "version": "1.0.3",
3
3
  "keywords": [],
4
4
  "type": "commonjs",
5
5
  "main": "dist/server/index.js",