import { useEffect, useRef, useState } from "react"; const API_BASE = import.meta.env.VITE_API_BASE_URL || ""; interface Message { role: "user" | "assistant"; content: string; } export default function ChatPanel() { const [messages, setMessages] = useState([]); const [input, setInput] = useState(""); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const bottomRef = useRef(null); useEffect(() => { bottomRef.current?.scrollIntoView({ behavior: "smooth" }); }, [messages, loading]); async function submitMessage() { const trimmed = input.trim(); if (!trimmed || loading) return; setError(null); setMessages((prev) => [...prev, { role: "user", content: trimmed }]); setInput(""); setLoading(true); try { const res = await fetch(`${API_BASE}/api/generate`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ message: trimmed }), }); if (res.status === 429) { setError("Rate limit exceeded. Please wait a moment and try again."); return; } if (!res.ok) { const detail = await res.json().catch(() => null); setError(detail?.detail ?? `Error: ${res.status}`); return; } const data = await res.json(); setMessages((prev) => [ ...prev, { role: "assistant", content: data.generated_code ?? "No code generated." }, ]); } catch { setError("Failed to connect to the server."); } finally { setLoading(false); } } function handleSubmit(e: React.FormEvent) { e.preventDefault(); submitMessage(); } function handleKeyDown(e: React.KeyboardEvent) { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); submitMessage(); } } return (

AVP RAG Chat

{messages.map((msg, i) => { const isUser = msg.role === "user"; return (
{isUser ? (

{msg.content}

) : (
{msg.content}
)}
); })} {loading && (
Generating...
)} {error && (
{error}
)}