UNPKG

chatbot-test-william

Version:

A flexible and customizable React chat component that supports context-aware conversations and document processing

1 lines 15.8 kB
{"version":3,"sources":["c:\\Users\\William\\code\\chatbot_llm\\frontend\\dist\\index.mjs"],"names":["useEffect","useRef","useState","AiFillRobot","IoPerson","jsx","jsxs","ChatMessageBubble","props","isUserMessage","message","role","bubbleClass","prefix","humanIcon","aiIcon","className","children","content","FaRobot","fetchChatbotResponse","endpoint","response","data","error","fetch","method","headers","body","JSON","stringify","ok","Error","json","console","MdDarkMode","MdLightMode","Fragment","jsx2","jsxs2","ChatWindow","messageContainerRef","isChatOpen","setIsChatOpen","theme","setTheme","messages","setMessages","input","setInput","chatEndpointIsLoading","setChatEndpointIsLoading","mediaQuery","window","matchMedia","themeChangeHandler","e","matches","addEventListener","removeEventListener","toggleTheme","currentTheme","isMobile","innerWidth","chatWindowStyles","flex","flexDirection","overflow","backgroundColor","color","position","bottom","right","borderRadius","width","placeholder","chatIcon","titleText","initialMessage","sourcesForMessages","setSourcesForMessages","length","push","id","createdAt","Date","now","sendMessage","newMessage","aiMessage","errorMessage","preventDefault","trim","crypto","randomUUID","prev","onClick","style","display","justifyContent","alignItems","gap","ref","map","m","i","onSubmit","value","onChange","target","lineHeight","parseInt","getComputedStyle","contentHeight","scrollHeight","newHeight","Math","min","height","onKeyDown","key","shiftKey","form","currentTarget","requestSubmit","rows","type","default"],"mappings":"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","sourcesContent":["// src/components/ChatWindow.tsx\nimport { useEffect, useRef, useState } from \"react\";\n\n// src/components/ChatMessageBubble.tsx\nimport { AiFillRobot } from \"react-icons/ai\";\nimport { IoPerson } from \"react-icons/io5\";\nimport { jsx, jsxs } from \"react/jsx-runtime\";\nfunction ChatMessageBubble(props) {\n const isUserMessage = props.message.role === \"user\";\n const bubbleClass = `message-bubble ${isUserMessage ? \"message-bubble-user\" : \"message-bubble-ai\"}`;\n const prefix = isUserMessage ? props.humanIcon ?? /* @__PURE__ */ jsx(IoPerson, {}) : props.aiIcon ?? /* @__PURE__ */ jsx(AiFillRobot, {});\n return /* @__PURE__ */ jsxs(\"div\", { className: bubbleClass, children: [\n /* @__PURE__ */ jsx(\"div\", { className: \"message-prefix\", children: prefix }),\n /* @__PURE__ */ jsx(\"div\", { className: \"message-content\", children: /* @__PURE__ */ jsx(\"span\", { children: props.message.content }) })\n ] });\n}\n\n// src/components/ChatWindow.tsx\nimport { FaRobot } from \"react-icons/fa6\";\n\n// src/components/utils/chatbot_api.tsx\nasync function fetchChatbotResponse(endpoint, message) {\n try {\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify({ message })\n });\n if (!response.ok) {\n throw new Error(\"Failed to fetch response from backend\");\n }\n const data = await response.json();\n return data.response;\n } catch (error) {\n console.error(\"Error fetching chatbot response:\", error);\n return \"I'm having trouble responding right now. Please try again later.\";\n }\n}\n\n// src/components/ChatWindow.tsx\nimport { MdDarkMode, MdLightMode } from \"react-icons/md\";\nimport { Fragment, jsx as jsx2, jsxs as jsxs2 } from \"react/jsx-runtime\";\nfunction ChatWindow(props) {\n const messageContainerRef = useRef(null);\n const [isChatOpen, setIsChatOpen] = useState(false);\n const [theme, setTheme] = useState(\"light\");\n const [messages, setMessages] = useState([]);\n const [input, setInput] = useState(\"\");\n const [chatEndpointIsLoading, setChatEndpointIsLoading] = useState(false);\n useEffect(() => {\n const mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const themeChangeHandler = (e) => setTheme(e.matches ? \"dark\" : \"light\");\n mediaQuery.addEventListener(\"change\", themeChangeHandler);\n setTheme(mediaQuery.matches ? \"dark\" : \"light\");\n return () => mediaQuery.removeEventListener(\"change\", themeChangeHandler);\n }, []);\n const toggleTheme = () => {\n setTheme((currentTheme) => currentTheme === \"light\" ? \"dark\" : \"light\");\n };\n const isMobile = window.innerWidth <= 768;\n const chatWindowStyles = {\n flex: 1,\n flexDirection: \"column\",\n overflow: \"hidden\",\n backgroundColor: theme === \"dark\" ? \"#333333\" : \"white\",\n color: theme === \"dark\" ? \"#fff\" : \"#000\",\n position: \"fixed\",\n bottom: isMobile ? \"160px\" : \"100px\",\n right: isMobile ? \"60px\" : \"40px\",\n borderRadius: \"10px\",\n width: isMobile ? \"90%\" : \"400px\"\n };\n const {\n endpoint,\n placeholder,\n aiIcon,\n humanIcon,\n chatIcon,\n titleText,\n initialMessage\n } = props;\n const [sourcesForMessages, setSourcesForMessages] = useState({});\n useEffect(() => {\n if (!messages.length) {\n messages.push({\n id: \"initial\",\n content: initialMessage || \"Hi, how may I help you?\",\n createdAt: new Date(Date.now()),\n role: \"assistant\"\n });\n }\n }, []);\n async function sendMessage(e) {\n e.preventDefault();\n if (input.trim() === \"\") return;\n const newMessage = {\n id: crypto.randomUUID(),\n content: input,\n createdAt: new Date(Date.now()),\n role: \"user\"\n };\n setMessages((prev) => [...prev, newMessage]);\n setInput(\"\");\n setChatEndpointIsLoading(true);\n try {\n const response = await fetchChatbotResponse(endpoint, newMessage.content);\n if (response) {\n const aiMessage = {\n id: \"bot\" + crypto.randomUUID(),\n content: response,\n createdAt: new Date(Date.now()),\n role: \"assistant\"\n };\n setMessages((prev) => [...prev, aiMessage]);\n }\n } catch (error) {\n console.error(\"Error fetching chatbot response:\", error);\n const errorMessage = {\n id: \"bot-error\" + crypto.randomUUID(),\n content: \"I'm having trouble responding right now. Please try again later.\",\n createdAt: new Date(Date.now()),\n role: \"assistant\"\n };\n setMessages((prev) => [...prev, errorMessage]);\n } finally {\n setChatEndpointIsLoading(false);\n }\n }\n ;\n return /* @__PURE__ */ jsxs2(Fragment, { children: [\n /* @__PURE__ */ jsx2(\n \"button\",\n {\n className: \"chat-button\",\n onClick: () => setIsChatOpen(!isChatOpen),\n children: chatIcon ?? /* @__PURE__ */ jsx2(FaRobot, {})\n }\n ),\n /* @__PURE__ */ jsxs2(\"div\", { style: chatWindowStyles, children: [\n isChatOpen && /* @__PURE__ */ jsxs2(Fragment, { children: [\n /* @__PURE__ */ jsxs2(\n \"div\",\n {\n className: \"chat-header\",\n style: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\"\n },\n children: [\n /* @__PURE__ */ jsx2(\"div\", { children: titleText }),\n /* @__PURE__ */ jsx2(\n \"div\",\n {\n style: { display: \"flex\", gap: \"8px\", alignItems: \"center\" },\n children: /* @__PURE__ */ jsx2(\"button\", { onClick: toggleTheme, className: \"theme-toggle-button\", children: /* @__PURE__ */ jsx2(\n \"div\",\n {\n className: theme === \"dark\" ? \"icon-wrapper\" : \"icon-wrapper dark-mode\",\n children: theme === \"dark\" ? /* @__PURE__ */ jsx2(MdLightMode, {}) : /* @__PURE__ */ jsx2(MdDarkMode, {})\n }\n ) })\n }\n )\n ]\n }\n ),\n /* @__PURE__ */ jsx2(\"div\", { className: \"chat-container\", children: /* @__PURE__ */ jsx2(\"div\", { ref: messageContainerRef, children: messages.length > 0 ? [...messages].map((m, i) => /* @__PURE__ */ jsx2(\n ChatMessageBubble,\n {\n message: m,\n aiIcon,\n humanIcon\n },\n m.id\n )) : \"\" }) })\n ] }),\n isChatOpen && /* @__PURE__ */ jsx2(\"form\", { onSubmit: sendMessage, className: \"form-container\", children: /* @__PURE__ */ jsxs2(\"div\", { className: \"chat-input\", children: [\n /* @__PURE__ */ jsx2(\n \"textarea\",\n {\n className: \"input-field\",\n value: input,\n placeholder: placeholder ?? \"Type your message here...\",\n onChange: (e) => {\n setInput(e.target.value);\n const lineHeight = parseInt(\n window.getComputedStyle(e.target).lineHeight\n );\n const contentHeight = e.target.scrollHeight;\n if (contentHeight > lineHeight && contentHeight > 32) {\n const newHeight = Math.min(contentHeight, 96);\n e.target.style.height = `${newHeight}px`;\n } else {\n e.target.style.height = \"32px\";\n }\n },\n onKeyDown: (e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n const form = e.currentTarget.form;\n if (form) form.requestSubmit();\n }\n },\n rows: 1,\n style: { height: \"32px\" }\n }\n ),\n /* @__PURE__ */ jsx2(\"button\", { type: \"submit\", className: \"submit-button\", children: chatEndpointIsLoading ? /* @__PURE__ */ jsx2(\"div\", { role: \"status\", className: \"flex justify-center\", children: /* @__PURE__ */ jsx2(\"span\", { children: \"Loading...\" }) }) : \"Send\" })\n ] }) })\n ] })\n ] });\n}\nexport {\n ChatWindow as default\n};\n"]}