118 lines
3.5 KiB
TypeScript
118 lines
3.5 KiB
TypeScript
import { useEffect } from 'react';
|
|
import { TopBar } from './components/Layout/TopBar';
|
|
import { CollapsibleSidebar } from './components/Layout/CollapsibleSidebar';
|
|
import { SettingsLayout } from './components/Settings/SettingsLayout';
|
|
import { AgentLayout } from './components/Agent/AgentLayout';
|
|
import { PluginLayout } from './components/Plugin/PluginLayout';
|
|
import { LeftPanel } from './components/Chat/LeftPanel';
|
|
import { ChatPanel } from './components/Chat/ChatPanel';
|
|
import { RightPanel } from './components/Chat/RightPanel';
|
|
import { WorkflowListView } from './components/Chat/WorkflowListView';
|
|
import { NewWorkflowDialog } from './components/Chat/NewWorkflowDialog';
|
|
import { AuthPage } from './components/Auth/AuthPage';
|
|
import { useAppStore } from './store/useAppStore';
|
|
import { useChatStore } from './store/useChatStore';
|
|
|
|
function App() {
|
|
const {
|
|
isAuthenticated,
|
|
setIsAuthenticated,
|
|
mode,
|
|
showSettings,
|
|
workTab,
|
|
agentTab,
|
|
applyTheme,
|
|
} = useAppStore();
|
|
|
|
const { loadSessions } = useChatStore();
|
|
|
|
// Initialize theme on mount
|
|
useEffect(() => {
|
|
applyTheme();
|
|
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
const handler = () => applyTheme();
|
|
mediaQuery.addEventListener('change', handler);
|
|
return () => mediaQuery.removeEventListener('change', handler);
|
|
}, [applyTheme]);
|
|
|
|
// Check auth and load sessions
|
|
useEffect(() => {
|
|
const token = localStorage.getItem('token');
|
|
if (token) {
|
|
setIsAuthenticated(true);
|
|
}
|
|
}, [setIsAuthenticated]);
|
|
|
|
useEffect(() => {
|
|
if (isAuthenticated) {
|
|
loadSessions();
|
|
}
|
|
}, [isAuthenticated, loadSessions]);
|
|
|
|
if (!isAuthenticated) {
|
|
return <AuthPage onLoginSuccess={() => setIsAuthenticated(true)} />;
|
|
}
|
|
|
|
return (
|
|
<div className="flex flex-col h-screen w-screen bg-bg-primary text-text-primary font-sans overflow-hidden">
|
|
<TopBar />
|
|
|
|
<div className="flex flex-1 overflow-hidden relative">
|
|
{showSettings ? (
|
|
<SettingsLayout />
|
|
) : (
|
|
<>
|
|
<CollapsibleSidebar />
|
|
|
|
<div className="flex-1 flex overflow-hidden">
|
|
{mode === 'work' && workTab === 'chat' && (
|
|
<div className="flex-1 p-4 flex overflow-hidden gap-4">
|
|
<div className="flex-1 flex bg-bg-card rounded-2xl shadow-sm border border-border-primary overflow-hidden relative">
|
|
<LeftPanel activeTab="chats" />
|
|
<ChatPanel />
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{mode === 'work' && workTab === 'workflow' && <WorkflowShell />}
|
|
|
|
{mode === 'agent' && agentTab === 'agents' && <AgentLayout />}
|
|
|
|
{mode === 'agent' && agentTab === 'plugin' && <PluginLayout />}
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function WorkflowShell() {
|
|
const { selectedWorkflow, setSelectedWorkflow } = useChatStore();
|
|
|
|
if (selectedWorkflow === 'new') {
|
|
return (
|
|
<>
|
|
<LeftPanel activeTab="workflows" />
|
|
<NewWorkflowDialog
|
|
onClose={() => setSelectedWorkflow(null)}
|
|
onSuccess={(traceId: string) => setSelectedWorkflow(traceId)}
|
|
/>
|
|
</>
|
|
);
|
|
}
|
|
|
|
if (selectedWorkflow) {
|
|
return (
|
|
<>
|
|
<LeftPanel activeTab="workflows" />
|
|
<RightPanel selectedWorkflow={selectedWorkflow} />
|
|
</>
|
|
);
|
|
}
|
|
|
|
return <WorkflowListView onSelectWorkflow={setSelectedWorkflow} />;
|
|
}
|
|
|
|
export default App;
|