Spaces:
No application file
No application file
| import { useRouter } from "next/router"; | |
| import React, { useState, useEffect } from "react"; | |
| import BotWrapper from "@/components/chat/BotWrapper"; | |
| import HumanWrapper from "@/components/chat/HumanWrapper"; | |
| import SetSources from "@/containers/SetSources"; | |
| export default function ChatWindow({ embedding_model, app_type, setBotTitle }) { | |
| const [bot, setBot] = useState(null); | |
| const [chats, setChats] = useState([]); | |
| const [isLoading, setIsLoading] = useState(false); | |
| const [selectChat, setSelectChat] = useState(true); | |
| const router = useRouter(); | |
| const { bot_slug } = router.query; | |
| useEffect(() => { | |
| if (bot_slug) { | |
| const fetchBots = async () => { | |
| const response = await fetch("/api/get_bots"); | |
| const data = await response.json(); | |
| const matchingBot = data.find((item) => item.slug === bot_slug); | |
| setBot(matchingBot); | |
| setBotTitle(matchingBot.name); | |
| }; | |
| fetchBots(); | |
| } | |
| }, [bot_slug]); | |
| useEffect(() => { | |
| const storedChats = localStorage.getItem(`chat_${bot_slug}_${app_type}`); | |
| if (storedChats) { | |
| const parsedChats = JSON.parse(storedChats); | |
| setChats(parsedChats.chats); | |
| } | |
| }, [app_type, bot_slug]); | |
| const handleChatResponse = async (e) => { | |
| e.preventDefault(); | |
| setIsLoading(true); | |
| const queryInput = e.target.query.value; | |
| e.target.query.value = ""; | |
| const chatEntry = { | |
| sender: "H", | |
| message: queryInput, | |
| }; | |
| setChats((prevChats) => [...prevChats, chatEntry]); | |
| const response = await fetch("/api/get_answer", { | |
| method: "POST", | |
| body: JSON.stringify({ | |
| query: queryInput, | |
| embedding_model, | |
| app_type, | |
| }), | |
| headers: { | |
| "Content-Type": "application/json", | |
| }, | |
| }); | |
| const data = await response.json(); | |
| if (response.ok) { | |
| const botResponse = data.response; | |
| const botEntry = { | |
| sender: "B", | |
| message: botResponse, | |
| }; | |
| setIsLoading(false); | |
| setChats((prevChats) => [...prevChats, botEntry]); | |
| const savedChats = { | |
| chats: [...chats, chatEntry, botEntry], | |
| }; | |
| localStorage.setItem( | |
| `chat_${bot_slug}_${app_type}`, | |
| JSON.stringify(savedChats) | |
| ); | |
| } else { | |
| router.reload(); | |
| } | |
| }; | |
| return ( | |
| <> | |
| <div className="flex flex-col justify-between h-full"> | |
| <div className="space-y-4 overflow-x-auto h-full pb-8"> | |
| {/* Greeting Message */} | |
| <BotWrapper> | |
| Hi, I am {bot?.name}. How can I help you today? | |
| </BotWrapper> | |
| {/* Chat Messages */} | |
| {chats.map((chat, index) => ( | |
| <React.Fragment key={index}> | |
| {chat.sender === "B" ? ( | |
| <BotWrapper>{chat.message}</BotWrapper> | |
| ) : ( | |
| <HumanWrapper>{chat.message}</HumanWrapper> | |
| )} | |
| </React.Fragment> | |
| ))} | |
| {/* Loader */} | |
| {isLoading && ( | |
| <BotWrapper> | |
| <div className="flex items-center justify-center space-x-2 animate-pulse"> | |
| <div className="w-2 h-2 bg-black rounded-full"></div> | |
| <div className="w-2 h-2 bg-black rounded-full"></div> | |
| <div className="w-2 h-2 bg-black rounded-full"></div> | |
| </div> | |
| </BotWrapper> | |
| )} | |
| </div> | |
| <div className="bg-white fixed bottom-0 left-0 right-0 h-28 sm:h-16"></div> | |
| {/* Query Form */} | |
| <div className="flex flex-row gap-x-2 sticky bottom-3"> | |
| <SetSources | |
| setChats={setChats} | |
| embedding_model={embedding_model} | |
| setSelectChat={setSelectChat} | |
| /> | |
| {selectChat && ( | |
| <form | |
| onSubmit={handleChatResponse} | |
| className="w-full flex flex-col sm:flex-row gap-y-2 gap-x-2" | |
| > | |
| <div className="w-full"> | |
| <input | |
| id="query" | |
| name="query" | |
| type="text" | |
| placeholder="Enter your query..." | |
| className="text-sm w-full border-2 border-black rounded-xl focus:outline-none focus:border-blue-800 sm:pl-4 h-11" | |
| required | |
| /> | |
| </div> | |
| <div className="w-full sm:w-fit"> | |
| <button | |
| type="submit" | |
| id="sender" | |
| disabled={isLoading} | |
| className={`${ | |
| isLoading ? "opacity-60" : "" | |
| } w-full bg-black hover:bg-blue-800 rounded-xl text-lg text-white px-6 h-11`} | |
| > | |
| Send | |
| </button> | |
| </div> | |
| </form> | |
| )} | |
| </div> | |
| </div> | |
| </> | |
| ); | |
| } | |