Skip to content

Commit f211993

Browse files
committed
feat: ragbot ui integration
Signed-off-by: amaan-bhati <[email protected]>
1 parent 470f18c commit f211993

File tree

5 files changed

+298
-6
lines changed

5 files changed

+298
-6
lines changed

docs/components/RelatedReadList.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ export function Preview({
115115
style={{marginTop: "1rem", display: "block", fontSize: "0.75rem"}}
116116
>
117117
<a style={{color: "blue"}} href={metadata.permalink}>
118-
see full article >>
118+
see full article
119119
</a>
120120
</span>
121121
</div>

docusaurus.config.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -340,16 +340,23 @@ module.exports = {
340340
async: true,
341341
defer: true,
342342
},
343-
{
344-
src: "/docs/scripts/chat.js",
345-
async: true,
346-
defer: true,
347-
},
343+
344+
// {
345+
// src: "/docs/scripts/chatbot.js",
346+
// async: true,
347+
// defer: true,
348+
// },
349+
// {
350+
// src: "/docs/scripts/chat.js",
351+
// async: true,
352+
// defer: true,
353+
// },
348354
// {
349355
// src: "/scripts/fullstory.js",
350356
// async: true,
351357
// defer: true,
352358
// },
359+
353360
],
354361
};
355362

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@
3131
"prism-react-renderer": "^2.1.0",
3232
"react": "^18.2.0",
3333
"react-dom": "^18.2.0",
34+
"react-markdown": "^10.1.0",
3435
"react-player": "^2.6.0",
36+
"rehype-highlight": "^7.0.2",
37+
"remark-gfm": "^4.0.1",
3538
"remark-typescript-tools": "1.0.9",
3639
"typescript": "5",
3740
"uuid": "^8.3.2",

src/components/ChatBot.js

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
import React, { useState, useEffect, useRef } from "react";
2+
3+
export default function Chatbot() {
4+
const [isOpen, setIsOpen] = useState(false);
5+
const [messages, setMessages] = useState([]);
6+
const [inputValue, setInputValue] = useState("");
7+
const [isLoading, setIsLoading] = useState(false);
8+
const [botStatus, setBotStatus] = useState("");
9+
const [showGreetingMessage, setShowGreetingMessage] = useState(true);
10+
const messagesEndRef = useRef(null);
11+
12+
const CHAT_STORAGE_KEY = "chat_history";
13+
14+
const toggleChat = () => setIsOpen(!isOpen);
15+
16+
// Load saved messages
17+
useEffect(() => {
18+
const saved = localStorage.getItem(CHAT_STORAGE_KEY);
19+
if (saved) setMessages(JSON.parse(saved));
20+
}, []);
21+
22+
// Save chat history
23+
useEffect(() => {
24+
if (messages.length > 0) {
25+
localStorage.setItem(CHAT_STORAGE_KEY, JSON.stringify(messages));
26+
}
27+
}, [messages]);
28+
29+
// Auto-scroll
30+
useEffect(() => {
31+
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
32+
}, [messages]);
33+
34+
// Hide greeting after 7s
35+
useEffect(() => {
36+
if (!isOpen && showGreetingMessage) {
37+
const timer = setTimeout(() => setShowGreetingMessage(false), 7000);
38+
return () => clearTimeout(timer);
39+
}
40+
}, [isOpen, showGreetingMessage]);
41+
42+
const sendMessage = async () => {
43+
if (!inputValue.trim()) return;
44+
45+
const userMsg = {
46+
id: Date.now(),
47+
text: inputValue,
48+
sender: "user",
49+
timestamp: new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }),
50+
};
51+
52+
setMessages((prev) => [...prev, userMsg]);
53+
setInputValue("");
54+
setIsLoading(true);
55+
56+
const statuses = ["Reviewing your query...", "Searching knowledge base...", "Formulating response..."];
57+
let idx = 0;
58+
const interval = setInterval(() => {
59+
setBotStatus(statuses[idx]);
60+
idx = (idx + 1) % statuses.length;
61+
}, 2000);
62+
63+
try {
64+
const res = await fetch("https://docbot.keploy.io/chat", {
65+
method: "POST",
66+
headers: { "Content-Type": "application/json" },
67+
body: JSON.stringify({ question: userMsg.text }),
68+
});
69+
const data = await res.json();
70+
71+
const botMsg = {
72+
id: Date.now() + 1,
73+
text: data.answer || "I couldn't find an answer. Try rephrasing.",
74+
sender: "bot",
75+
timestamp: new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }),
76+
};
77+
78+
setMessages((prev) => [...prev, botMsg]);
79+
} catch (err) {
80+
setMessages((prev) => [
81+
...prev,
82+
{
83+
id: Date.now() + 2,
84+
text: "⚠️ Error: please try again later.",
85+
sender: "bot",
86+
timestamp: new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }),
87+
},
88+
]);
89+
} finally {
90+
clearInterval(interval);
91+
setBotStatus("");
92+
setIsLoading(false);
93+
}
94+
};
95+
96+
return (
97+
<div style={{ position: "fixed", bottom: "20px", right: "20px", zIndex: 1000, fontFamily: "sans-serif" }}>
98+
{/* Floating Button */}
99+
{!isOpen && (
100+
<div style={{ position: "relative" }}>
101+
{showGreetingMessage && (
102+
<div
103+
style={{
104+
position: "absolute",
105+
bottom: "75px",
106+
right: "0",
107+
background: "#fff",
108+
border: "1px solid #e5e7eb",
109+
borderRadius: "8px",
110+
padding: "10px 12px",
111+
width: "220px",
112+
fontSize: "14px",
113+
color: "#374151",
114+
boxShadow: "0 4px 10px rgba(0,0,0,0.15)",
115+
}}
116+
>
117+
<p style={{ fontWeight: "600", marginBottom: "4px" }}>Hey, I'm Keploy AI Assistant!</p>
118+
<p>May I help you?</p>
119+
</div>
120+
)}
121+
122+
<button
123+
onClick={toggleChat}
124+
style={{
125+
width: "60px",
126+
height: "60px",
127+
borderRadius: "50%",
128+
background: "#FF6B35",
129+
border: "none",
130+
cursor: "pointer",
131+
boxShadow: "0 6px 12px rgba(0,0,0,0.25)",
132+
display: "flex",
133+
alignItems: "center",
134+
justifyContent: "center",
135+
transition: "transform 0.2s ease",
136+
color: "#fff",
137+
fontSize: "24px",
138+
}}
139+
onMouseOver={(e) => (e.currentTarget.style.transform = "scale(1.05)")}
140+
onMouseOut={(e) => (e.currentTarget.style.transform = "scale(1)")}
141+
>
142+
💬
143+
</button>
144+
</div>
145+
)}
146+
147+
{/* Chat Window */}
148+
{isOpen && (
149+
<div
150+
style={{
151+
width: "360px",
152+
height: "520px",
153+
background: "#fff",
154+
border: "1px solid #e5e7eb",
155+
borderRadius: "12px",
156+
boxShadow: "0 8px 20px rgba(0,0,0,0.25)",
157+
display: "flex",
158+
flexDirection: "column",
159+
overflow: "hidden",
160+
}}
161+
>
162+
{/* Header */}
163+
<div
164+
style={{
165+
background: "#FF6B35",
166+
color: "#fff",
167+
padding: "12px",
168+
fontWeight: "600",
169+
display: "flex",
170+
justifyContent: "space-between",
171+
alignItems: "center",
172+
fontSize: "15px",
173+
}}
174+
>
175+
Keploy AI Assistant
176+
<button
177+
onClick={toggleChat}
178+
style={{
179+
background: "transparent",
180+
border: "none",
181+
color: "#fff",
182+
fontSize: "18px",
183+
cursor: "pointer",
184+
}}
185+
>
186+
187+
</button>
188+
</div>
189+
190+
{/* Messages */}
191+
<div
192+
style={{
193+
flex: 1,
194+
overflowY: "auto",
195+
padding: "12px",
196+
background: "#f9fafb",
197+
fontSize: "14px",
198+
}}
199+
>
200+
{messages.map((m) => (
201+
<div
202+
key={m.id}
203+
style={{
204+
margin: "8px 0",
205+
display: "flex",
206+
justifyContent: m.sender === "user" ? "flex-end" : "flex-start",
207+
}}
208+
>
209+
<div
210+
style={{
211+
padding: "8px 12px",
212+
borderRadius: "12px",
213+
background: m.sender === "user" ? "#ffedd5" : "#e5e7eb",
214+
color: "#1f2937",
215+
maxWidth: "75%",
216+
wordWrap: "break-word",
217+
}}
218+
>
219+
{m.text}
220+
<div style={{ fontSize: "11px", color: "#6b7280", marginTop: "4px", textAlign: "right" }}>
221+
{m.timestamp}
222+
</div>
223+
</div>
224+
</div>
225+
))}
226+
227+
{isLoading && (
228+
<div style={{ fontSize: "13px", color: "#6b7280", marginTop: "6px" }}>{botStatus}...</div>
229+
)}
230+
<div ref={messagesEndRef} />
231+
</div>
232+
233+
{/* Input */}
234+
<div style={{ borderTop: "1px solid #e5e7eb", padding: "8px", display: "flex" }}>
235+
<input
236+
type="text"
237+
value={inputValue}
238+
onChange={(e) => setInputValue(e.target.value)}
239+
onKeyDown={(e) => e.key === "Enter" && sendMessage()}
240+
placeholder="Type your message..."
241+
style={{
242+
flex: 1,
243+
border: "1px solid #d1d5db",
244+
borderRadius: "8px",
245+
padding: "8px 10px",
246+
fontSize: "14px",
247+
outline: "none",
248+
}}
249+
/>
250+
<button
251+
onClick={sendMessage}
252+
style={{
253+
marginLeft: "8px",
254+
background: "#FF6B35",
255+
border: "none",
256+
color: "#fff",
257+
padding: "8px 14px",
258+
borderRadius: "8px",
259+
cursor: "pointer",
260+
fontWeight: "500",
261+
}}
262+
>
263+
Send
264+
</button>
265+
</div>
266+
</div>
267+
)}
268+
</div>
269+
);
270+
}

src/theme/Root.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React from "react";
2+
import Chatbot from "../components/ChatBot";
3+
// import Chatbot from "../components/Chatbot";
4+
5+
export default function Root({ children }) {
6+
return (
7+
<>
8+
{children}
9+
<Chatbot/>
10+
</>
11+
);
12+
}

0 commit comments

Comments
 (0)