import { useEffect, useRef, useState } from "react"; import { io, Socket } from "socket.io-client"; import ChatMessage from "./components/ChatMessage"; interface Message { role: "user" | "assistant"; content: string; } const SOCKET_URL = `${window.location.protocol}//${window.location.hostname}:8000`; export default function App() { const [messages, setMessages] = useState([]); const [input, setInput] = useState(""); const [loading, setLoading] = useState(false); const [connected, setConnected] = useState(false); const socketRef = useRef(null); const bottomRef = useRef(null); useEffect(() => { const socket = io(SOCKET_URL); socketRef.current = socket; socket.on("connect", () => setConnected(true)); socket.on("disconnect", () => setConnected(false)); socket.on("answer", (data: { answer?: string; error?: string }) => { const content = data.answer ?? `Lỗi: ${data.error}`; setMessages((prev) => [...prev, { role: "assistant", content }]); setLoading(false); }); return () => { socket.disconnect(); }; }, []); useEffect(() => { bottomRef.current?.scrollIntoView({ behavior: "smooth" }); }, [messages, loading]); const handleSend = () => { const question = input.trim(); if (!question || loading || !connected) return; setMessages((prev) => [...prev, { role: "user", content: question }]); setInput(""); setLoading(true); socketRef.current?.emit("ask", { question }); }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); handleSend(); } }; return (
{/* Header */}

Hỏi đáp Pháp luật Việt Nam

RAG Agent - Tra cứu văn bản pháp luật

{/* Messages */}
{messages.length === 0 && !loading && (

Chào mừng bạn!

Hãy đặt câu hỏi về pháp luật Việt Nam.

)} {messages.map((msg, i) => ( ))} {loading && (

Trợ lý Pháp luật

)}
{/* Input */}
); }