repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
public Clawd ADK gateway launch mirror
stars
latest
clone command
git clone gitlawb://did:key:z6Mkq5mY...iFZ5/my-project-publ...git clone gitlawb://did:key:z6Mkq5mY.../my-project-publ...2fa351d6docs: add automaton and perps launch sources16d ago| #1 | import { useRouter } from "next/router"; |
| #2 | import React, { useState, useEffect } from "react"; |
| #3 | import BotWrapper from "@/components/chat/BotWrapper"; |
| #4 | import HumanWrapper from "@/components/chat/HumanWrapper"; |
| #5 | import SetSources from "@/containers/SetSources"; |
| #6 | |
| #7 | export default function ChatWindow({ embedding_model, app_type, setBotTitle }) { |
| #8 | const [bot, setBot] = useState(null); |
| #9 | const [chats, setChats] = useState([]); |
| #10 | const [isLoading, setIsLoading] = useState(false); |
| #11 | const [selectChat, setSelectChat] = useState(true); |
| #12 | |
| #13 | const router = useRouter(); |
| #14 | const { bot_slug } = router.query; |
| #15 | |
| #16 | useEffect(() => { |
| #17 | if (bot_slug) { |
| #18 | const fetchBots = async () => { |
| #19 | const response = await fetch("/api/get_bots"); |
| #20 | const data = await response.json(); |
| #21 | const matchingBot = data.find((item) => item.slug === bot_slug); |
| #22 | setBot(matchingBot); |
| #23 | setBotTitle(matchingBot.name); |
| #24 | }; |
| #25 | fetchBots(); |
| #26 | } |
| #27 | }, [bot_slug]); |
| #28 | |
| #29 | useEffect(() => { |
| #30 | const storedChats = localStorage.getItem(`chat_${bot_slug}_${app_type}`); |
| #31 | if (storedChats) { |
| #32 | const parsedChats = JSON.parse(storedChats); |
| #33 | setChats(parsedChats.chats); |
| #34 | } |
| #35 | }, [app_type, bot_slug]); |
| #36 | |
| #37 | const handleChatResponse = async (e) => { |
| #38 | e.preventDefault(); |
| #39 | setIsLoading(true); |
| #40 | const queryInput = e.target.query.value; |
| #41 | e.target.query.value = ""; |
| #42 | const chatEntry = { |
| #43 | sender: "H", |
| #44 | message: queryInput, |
| #45 | }; |
| #46 | setChats((prevChats) => [...prevChats, chatEntry]); |
| #47 | |
| #48 | const response = await fetch("/api/get_answer", { |
| #49 | method: "POST", |
| #50 | body: JSON.stringify({ |
| #51 | query: queryInput, |
| #52 | embedding_model, |
| #53 | app_type, |
| #54 | }), |
| #55 | headers: { |
| #56 | "Content-Type": "application/json", |
| #57 | }, |
| #58 | }); |
| #59 | |
| #60 | const data = await response.json(); |
| #61 | if (response.ok) { |
| #62 | const botResponse = data.response; |
| #63 | const botEntry = { |
| #64 | sender: "B", |
| #65 | message: botResponse, |
| #66 | }; |
| #67 | setIsLoading(false); |
| #68 | setChats((prevChats) => [...prevChats, botEntry]); |
| #69 | const savedChats = { |
| #70 | chats: [...chats, chatEntry, botEntry], |
| #71 | }; |
| #72 | localStorage.setItem( |
| #73 | `chat_${bot_slug}_${app_type}`, |
| #74 | JSON.stringify(savedChats) |
| #75 | ); |
| #76 | } else { |
| #77 | router.reload(); |
| #78 | } |
| #79 | }; |
| #80 | |
| #81 | return ( |
| #82 | <> |
| #83 | <div className="flex flex-col justify-between h-full"> |
| #84 | <div className="space-y-4 overflow-x-auto h-full pb-8"> |
| #85 | {/* Greeting Message */} |
| #86 | <BotWrapper> |
| #87 | Hi, I am {bot?.name}. How can I help you today? |
| #88 | </BotWrapper> |
| #89 | |
| #90 | {/* Chat Messages */} |
| #91 | {chats.map((chat, index) => ( |
| #92 | <React.Fragment key={index}> |
| #93 | {chat.sender === "B" ? ( |
| #94 | <BotWrapper>{chat.message}</BotWrapper> |
| #95 | ) : ( |
| #96 | <HumanWrapper>{chat.message}</HumanWrapper> |
| #97 | )} |
| #98 | </React.Fragment> |
| #99 | ))} |
| #100 | |
| #101 | {/* Loader */} |
| #102 | {isLoading && ( |
| #103 | <BotWrapper> |
| #104 | <div className="flex items-center justify-center space-x-2 animate-pulse"> |
| #105 | <div className="w-2 h-2 bg-black rounded-full"></div> |
| #106 | <div className="w-2 h-2 bg-black rounded-full"></div> |
| #107 | <div className="w-2 h-2 bg-black rounded-full"></div> |
| #108 | </div> |
| #109 | </BotWrapper> |
| #110 | )} |
| #111 | </div> |
| #112 | |
| #113 | <div className="bg-white fixed bottom-0 left-0 right-0 h-28 sm:h-16"></div> |
| #114 | |
| #115 | {/* Query Form */} |
| #116 | <div className="flex flex-row gap-x-2 sticky bottom-3"> |
| #117 | <SetSources |
| #118 | setChats={setChats} |
| #119 | embedding_model={embedding_model} |
| #120 | setSelectChat={setSelectChat} |
| #121 | /> |
| #122 | {selectChat && ( |
| #123 | <form |
| #124 | onSubmit={handleChatResponse} |
| #125 | className="w-full flex flex-col sm:flex-row gap-y-2 gap-x-2" |
| #126 | > |
| #127 | <div className="w-full"> |
| #128 | <input |
| #129 | id="query" |
| #130 | name="query" |
| #131 | type="text" |
| #132 | placeholder="Enter your query..." |
| #133 | className="text-sm w-full border-2 border-black rounded-xl focus:outline-none focus:border-blue-800 sm:pl-4 h-11" |
| #134 | required |
| #135 | /> |
| #136 | </div> |
| #137 | |
| #138 | <div className="w-full sm:w-fit"> |
| #139 | <button |
| #140 | type="submit" |
| #141 | id="sender" |
| #142 | disabled={isLoading} |
| #143 | className={`${ |
| #144 | isLoading ? "opacity-60" : "" |
| #145 | } w-full bg-black hover:bg-blue-800 rounded-xl text-lg text-white px-6 h-11`} |
| #146 | > |
| #147 | Send |
| #148 | </button> |
| #149 | </div> |
| #150 | </form> |
| #151 | )} |
| #152 | </div> |
| #153 | </div> |
| #154 | </> |
| #155 | ); |
| #156 | } |
| #157 |