Decoder2704/python-chatbot-jay
0
1import { useState, useCallback, useRef, useEffect } from "react";2import { sendChatMessage, ChatApiError } from "../services/api.js";3 4function createId() {5 return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;6}7 8/**9 * Shared chat state + API calls (same behavior as legacy ChatWindow).10 */11export function useChatSession() {12 const [messages, setMessages] = useState([]);13 const [input, setInput] = useState("");14 const [loading, setLoading] = useState(false);15 const [error, setError] = useState(null);16 const bottomRef = useRef(null);17 18 const scrollToBottom = useCallback(() => {19 bottomRef.current?.scrollIntoView({ behavior: "smooth" });20 }, []);21 22 useEffect(() => {23 scrollToBottom();24 }, [messages, loading, scrollToBottom]);25 26 const appendUser = useCallback((text) => {27 setMessages((prev) => [28 ...prev,29 { id: createId(), role: "user", text, at: Date.now() },30 ]);31 }, []);32 33 const appendBot = useCallback((text, meta) => {34 setMessages((prev) => [35 ...prev,36 { id: createId(), role: "bot", text, meta, at: Date.now() },37 ]);38 }, []);39 40 const runSend = useCallback(41 async (rawText) => {42 const text = rawText.trim();43 if (!text || loading) return;44 45 setError(null);46 appendUser(text);47 setInput("");48 setLoading(true);49 50 try {51 const data = await sendChatMessage(text);52 appendBot(data.answer, {53 qid: data.qid,54 aid: data.aid,55 alternate: data.alternate,56 });57 } catch (e) {58 const msg =59 e instanceof ChatApiError60 ? e.message61 : e instanceof Error62 ? e.message63 : "Something went wrong";64 setError(msg);65 } finally {66 setLoading(false);67 }68 },69 [loading, appendUser, appendBot]70 );71 72 const handleSubmit = useCallback(73 (e) => {74 e.preventDefault();75 runSend(input);76 },77 [input, runSend]78 );79 80 const handleClear = useCallback(() => {81 setMessages([]);82 setError(null);83 setInput("");84 }, []);85 86 return {87 messages,88 input,89 setInput,90 loading,91 error,92 runSend,93 handleSubmit,94 handleClear,95 bottomRef,96 };97}98 