Files
archon/archon-ui-main/src/App.tsx
2025-09-22 02:52:45 -04:00

130 lines
4.6 KiB
TypeScript

import { useState, useEffect } from 'react';
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import { QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { queryClient } from './features/shared/queryClient';
import { KnowledgeBasePage } from './pages/KnowledgeBasePage';
import { SettingsPage } from './pages/SettingsPage';
import { MCPPage } from './pages/MCPPage';
import { OnboardingPage } from './pages/OnboardingPage';
import { MainLayout } from './components/layout/MainLayout';
import { ThemeProvider } from './contexts/ThemeContext';
import { ToastProvider } from './features/ui/components/ToastProvider';
import { SettingsProvider, useSettings } from './contexts/SettingsContext';
import { TooltipProvider } from './features/ui/primitives/tooltip';
import { ProjectPage } from './pages/ProjectPage';
import StyleGuidePage from './pages/StyleGuidePage';
import { DisconnectScreenOverlay } from './components/DisconnectScreenOverlay';
import { ErrorBoundaryWithBugReport } from './components/bug-report/ErrorBoundaryWithBugReport';
import { MigrationBanner } from './components/ui/MigrationBanner';
import { serverHealthService } from './services/serverHealthService';
import { useMigrationStatus } from './hooks/useMigrationStatus';
const AppRoutes = () => {
const { projectsEnabled } = useSettings();
return (
<Routes>
<Route path="/" element={<KnowledgeBasePage />} />
<Route path="/onboarding" element={<OnboardingPage />} />
<Route path="/settings" element={<SettingsPage />} />
<Route path="/mcp" element={<MCPPage />} />
<Route path="/style-guide" element={<StyleGuidePage />} />
{projectsEnabled ? (
<>
<Route path="/projects" element={<ProjectPage />} />
<Route path="/projects/:projectId" element={<ProjectPage />} />
</>
) : (
<Route path="/projects" element={<Navigate to="/" replace />} />
)}
</Routes>
);
};
const AppContent = () => {
const [disconnectScreenActive, setDisconnectScreenActive] = useState(false);
const [disconnectScreenDismissed, setDisconnectScreenDismissed] = useState(false);
const [disconnectScreenSettings, setDisconnectScreenSettings] = useState({
enabled: true,
delay: 10000
});
const [migrationBannerDismissed, setMigrationBannerDismissed] = useState(false);
const migrationStatus = useMigrationStatus();
useEffect(() => {
// Load initial settings
const settings = serverHealthService.getSettings();
setDisconnectScreenSettings(settings);
// Stop any existing monitoring before starting new one to prevent multiple intervals
serverHealthService.stopMonitoring();
// Start health monitoring
serverHealthService.startMonitoring({
onDisconnected: () => {
if (!disconnectScreenDismissed) {
setDisconnectScreenActive(true);
}
},
onReconnected: () => {
setDisconnectScreenActive(false);
setDisconnectScreenDismissed(false);
// Refresh the page to ensure all data is fresh
window.location.reload();
}
});
return () => {
serverHealthService.stopMonitoring();
};
}, [disconnectScreenDismissed]);
const handleDismissDisconnectScreen = () => {
setDisconnectScreenActive(false);
setDisconnectScreenDismissed(true);
};
return (
<>
<Router>
<ErrorBoundaryWithBugReport>
<MainLayout>
{/* Migration Banner - shows when backend is up but DB schema needs work */}
{migrationStatus.migrationRequired && !migrationBannerDismissed && (
<MigrationBanner
message={migrationStatus.message || "Database migration required"}
onDismiss={() => setMigrationBannerDismissed(true)}
/>
)}
<AppRoutes />
</MainLayout>
</ErrorBoundaryWithBugReport>
</Router>
<DisconnectScreenOverlay
isActive={disconnectScreenActive && disconnectScreenSettings.enabled}
onDismiss={handleDismissDisconnectScreen}
/>
</>
);
};
export function App() {
return (
<QueryClientProvider client={queryClient}>
<ThemeProvider>
<ToastProvider>
<TooltipProvider>
<SettingsProvider>
<AppContent />
</SettingsProvider>
</TooltipProvider>
</ToastProvider>
</ThemeProvider>
{import.meta.env.VITE_SHOW_DEVTOOLS === 'true' && (
<ReactQueryDevtools initialIsOpen={false} />
)}
</QueryClientProvider>
);
}