import { useRef, useEffect, useState } from "react"; import { AnimatePresence, motion } from "framer-motion"; import { Menu, PanelLeftClose, Cpu, FileText, Settings, ChevronLeft, ChevronRight } from "lucide-react"; import { Button } from "@/components/ui/button"; import { ScrollArea } from "@/components/ui/scroll-area"; import { ChatMessage } from "@/components/ChatMessage"; import { ChatInput } from "@/components/ChatInput"; import { WelcomeScreen } from "@/components/WelcomeScreen"; import { ConversationSidebar } from "@/components/ConversationSidebar"; import { ModelStore } from "@/components/ModelStore"; import { PDFViewer } from "@/components/PDFViewer"; import { SettingsPanel } from "@/components/SettingsPanel"; import { ProviderBadge } from "@/components/ProviderBadge"; import { useChat } from "@/hooks/useChat"; import { useVoice } from "@/hooks/useVoice"; import { usePDF } from "@/hooks/usePDF"; import { useSettings } from "@/hooks/useSettings"; import { cn } from "@/lib/utils"; type RightPanelView = "models" | "documents" | "settings" | null; export function ChatInterface() { const [sidebarOpen, setSidebarOpen] = useState(true); const [rightPanel, setRightPanel] = useState(null); const scrollRef = useRef(null); const { settings, updateSettings } = useSettings(); const { documents, activeDocument, isLoading: pdfLoading, uploadPDF, removeDocument, setActiveDocument, getContextForRAG, } = usePDF(); const { conversations, activeConversation, activeConversationId, messages, isLoading, createConversation, setActiveConversationId, deleteConversation, sendMessage, } = useChat({ settings, pdfContext: activeDocument ? getContextForRAG("") : undefined, }); const { isListening, transcript, startListening, stopListening, } = useVoice(); // Auto-scroll to bottom when new messages arrive useEffect(() => { if (scrollRef.current) { scrollRef.current.scrollTop = scrollRef.current.scrollHeight; } }, [messages]); const handleSendMessage = async (content: string) => { const context = activeDocument ? getContextForRAG(content) : undefined; sendMessage(content); }; const handleFileUpload = async (file: File) => { if (file.type === "application/pdf") { await uploadPDF(file); setRightPanel("documents"); } }; const toggleRightPanel = (view: RightPanelView) => { setRightPanel((prev) => (prev === view ? null : view)); }; return (
{/* Sidebar */} {sidebarOpen && ( )} {/* Main Chat Area */}
{/* Header */}

{activeConversation?.title || "AI Assistant"}

{activeConversation && ( )}
{/* Right Panel Toggles */}
{/* Messages Area */}
{messages.length === 0 ? ( 0} /> ) : (
{messages.map((message) => ( ))}
)}
{/* Input Area */}
{/* Right Panel */} {rightPanel && ( {rightPanel === "models" && ( updateSettings({ ollamaModel: model, provider: "ollama" })} /> )} {rightPanel === "documents" && ( )} {rightPanel === "settings" && ( )} )}
); }