diff --git a/docs/components/RelatedReadList.js b/docs/components/RelatedReadList.js index 781ce8fa0..92d2b84d6 100644 --- a/docs/components/RelatedReadList.js +++ b/docs/components/RelatedReadList.js @@ -115,7 +115,7 @@ export function Preview({ style={{marginTop: "1rem", display: "block", fontSize: "0.75rem"}} > - see full article >> + see full article diff --git a/docusaurus.config.js b/docusaurus.config.js index 89ca483a1..1b3344ccd 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -162,8 +162,7 @@ module.exports = { dropdownActiveClassDisabled: true, }, { - href: - "https://join.slack.com/t/keploy/shared_invite/zt-357qqm9b5-PbZRVu3Yt2rJIa6ofrwWNg", + href: "https://join.slack.com/t/keploy/shared_invite/zt-357qqm9b5-PbZRVu3Yt2rJIa6ofrwWNg", position: "right", className: "header-slack-link", "aria-label": "Join our Slack community", @@ -340,11 +339,17 @@ module.exports = { async: true, defer: true, }, - { - src: "/docs/scripts/chat.js", - async: true, - defer: true, - }, + + // { + // src: "/docs/scripts/chatbot.js", + // async: true, + // defer: true, + // }, + // { + // src: "/docs/scripts/chat.js", + // async: true, + // defer: true, + // }, // { // src: "/scripts/fullstory.js", // async: true, diff --git a/package.json b/package.json index 2f50f0cbe..f4fccf853 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,10 @@ "prism-react-renderer": "^2.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-markdown": "^10.1.0", "react-player": "^2.6.0", + "rehype-highlight": "^7.0.2", + "remark-gfm": "^4.0.1", "remark-typescript-tools": "1.0.9", "typescript": "5", "uuid": "^8.3.2", diff --git a/src/components/ChatBot.js b/src/components/ChatBot.js new file mode 100644 index 000000000..730c766ec --- /dev/null +++ b/src/components/ChatBot.js @@ -0,0 +1,313 @@ +import React, {useState, useEffect, useRef} from "react"; + +export default function Chatbot() { + const [isOpen, setIsOpen] = useState(false); + const [messages, setMessages] = useState([]); + const [inputValue, setInputValue] = useState(""); + const [isLoading, setIsLoading] = useState(false); + const [botStatus, setBotStatus] = useState(""); + const [showGreetingMessage, setShowGreetingMessage] = useState(true); + const messagesEndRef = useRef(null); + + const CHAT_STORAGE_KEY = "chat_history"; + + const toggleChat = () => setIsOpen(!isOpen); + + // Load saved messages + useEffect(() => { + const saved = localStorage.getItem(CHAT_STORAGE_KEY); + if (saved) setMessages(JSON.parse(saved)); + }, []); + + // Save chat history + useEffect(() => { + if (messages.length > 0) { + localStorage.setItem(CHAT_STORAGE_KEY, JSON.stringify(messages)); + } + }, [messages]); + + // Auto-scroll + useEffect(() => { + messagesEndRef.current?.scrollIntoView({behavior: "smooth"}); + }, [messages]); + + // Hide greeting after 7s + useEffect(() => { + if (!isOpen && showGreetingMessage) { + const timer = setTimeout(() => setShowGreetingMessage(false), 7000); + return () => clearTimeout(timer); + } + }, [isOpen, showGreetingMessage]); + + const sendMessage = async () => { + if (!inputValue.trim()) return; + + const userMsg = { + id: Date.now(), + text: inputValue, + sender: "user", + timestamp: new Date().toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + }), + }; + + setMessages((prev) => [...prev, userMsg]); + setInputValue(""); + setIsLoading(true); + + const statuses = [ + "Reviewing your query...", + "Searching knowledge base...", + "Formulating response...", + ]; + let idx = 0; + const interval = setInterval(() => { + setBotStatus(statuses[idx]); + idx = (idx + 1) % statuses.length; + }, 2000); + + try { + const res = await fetch("https://docbot.keploy.io/chat", { + method: "POST", + headers: {"Content-Type": "application/json"}, + body: JSON.stringify({question: userMsg.text}), + }); + const data = await res.json(); + + const botMsg = { + id: Date.now() + 1, + text: data.answer || "I couldn't find an answer. Try rephrasing.", + sender: "bot", + timestamp: new Date().toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + }), + }; + + setMessages((prev) => [...prev, botMsg]); + } catch (err) { + setMessages((prev) => [ + ...prev, + { + id: Date.now() + 2, + text: "⚠️ Error: please try again later.", + sender: "bot", + timestamp: new Date().toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + }), + }, + ]); + } finally { + clearInterval(interval); + setBotStatus(""); + setIsLoading(false); + } + }; + + return ( +
+ Hey, I'm Keploy AI Assistant! +
+May I help you?
+