import React, { useState, useEffect } from 'react'; import ChatWindow from './components/ChatWindow'; import InfoPanel from './components/InfoPanel'; import Sidebar from './components/Sidebar'; import HomeView from './components/HomeView'; import { v4 as uuidv4 } from 'uuid'; import { getModelProps } from './api/orchestration'; /*** View Panels*** */ import AllChatsView from './components/AllChatsView'; import AllProjectsView from './components/AllProjectsView'; import SettingsView from './components/SettingsView'; import ProjectView from './components/ProjectView'; import MemoryView from './components/MemoryView'; import SummaryView from './components/SummaryView'; /**** useHooks **** */ import { useSession } from './hooks/useSession'; import { useChat } from './hooks/useChat'; import { useModels } from './hooks/useModels'; import { useProjects } from './hooks/useProjects'; // Views where back nav makes sense, and where they go back to const BACK_MAP = { 'chat': 'home', 'all-chats': 'home', 'all-projects': 'home', 'settings': 'home', 'project': 'all-projects', 'memory': 'settings', 'summaries': 'chat', }; export default function App() { const [leftOpen, setLeftOpen] = useState(false); // collapsed on home const [rightOpen, setRightOpen] = useState(false); const { models, selectedModel, setSelectedModel } = useModels(); const [view, setView] = useState('home'); const [viewHistory, setViewHistory] = useState([]); const [activeProject, setActiveProject] = useState(null); const { projects, refreshProjects } = useProjects(); // Lifted model props — available to header + SettingsView const [modelProps, setModelProps] = useState(null); useEffect(() => { getModelProps().then(setModelProps).catch(() => {}); }, []); const { sessions, setSessions, activeSession, messages, loadingHistory, selectSession, createSession, refreshSessions, appendMessage, updateLastMessage, } = useSession(); const { sendMessage, cancelStream, streaming, lastTokenCount, lastModel, useChat, } = useChat({ activeSession, appendMessage, updateLastMessage, refreshSessions }); function navigate(nextView) { setViewHistory(prev => [...prev, view]); setView(nextView); // Expand sidebar when leaving home if (view === 'home') setLeftOpen(true); } function goBack() { if (viewHistory.length > 0) { const prev = viewHistory[viewHistory.length - 1]; setViewHistory(h => h.slice(0, -1)); setView(prev); if (prev === 'home') setLeftOpen(false); } else { // Fallback to BACK_MAP const dest = BACK_MAP[view] ?? 'home'; setView(dest); if (dest === 'home') setLeftOpen(false); } } function handleSendMessage(text) { sendMessage(text, selectedModel, activeSession?.project_id ?? null); } function handleSessionsChange(deletedSession) { if (deletedSession?.external_id === activeSession?.external_id) { selectSession(null); } refreshSessions(); } // Home: create session, navigate to chat, then send after a tick function handleHomeSend(text) { const newSession = createSession(); // ← capture the returned session setViewHistory(prev => [...prev, 'home']); setView('chat'); setLeftOpen(true); sendMessage(text, selectedModel, null, newSession); // ← pass directly, no setTimeout needed } function handleNewProjectChat(text) { const newSession = { external_id: uuidv4(), metadata: null, isNew: true, project_id: activeProject?.id ?? null, }; setSessions(prev => [newSession, ...prev]); selectSession(newSession); setViewHistory(prev => [...prev, view]); setView('chat'); setLeftOpen(true); sendMessage(text, selectedModel, activeProject?.id ?? null, newSession); // ← direct, no timeout } const canGoBack = view !== 'home'; return (
{ selectSession(session); navigate('chat'); }} onNewChat={() => { createSession(); navigate('chat'); }} onNewProject={() => navigate('all-projects')} isOpen={leftOpen} onToggle={() => setLeftOpen(o => !o)} onSessionsChange={handleSessionsChange} onNavigate={navigate} projects={projects} onProjectsChange={refreshProjects} onSelectProject={setActiveProject} /> {view === 'home' && ( )} {view === 'chat' && ( setRightOpen(o => !o)} onBack={goBack} canGoBack={canGoBack} loadedModel={modelProps?.modelAlias ?? null} summarising={summarising} /> )} {view === 'all-chats' && ( { selectSession(session); navigate('chat'); }} projects={projects} /> )} {view === 'all-projects' && ( )} {view === 'settings' && ( )} {view === 'project' && activeProject && ( )} {view === 'memory' && ( )} {view === 'summaries' && ( )} setRightOpen(o => !o)} activeSession={activeSession} models={models} selectedModel={selectedModel} onModelChange={setSelectedModel} lastModel={lastModel} lastTokenCount={lastTokenCount} summarising={summarising} onViewSummary={() => navigate('summaries')} />
); }