import { useState, useEffect, createContext, useContext } from "react"; import { Header } from "./Header"; import { Sidebar } from "./Sidebar"; import { Dashboard } from "@/components/dashboard/Dashboard"; import Repository from "../repositories/Repository"; import Providers from "./Providers"; import { ConfigTabs } from "../config/ConfigTabs"; import { ActivityLog } from "../activity/ActivityLog"; import { Organization } from "../organizations/Organization"; import { Toaster } from "@/components/ui/sonner"; import { useAuth } from "@/hooks/useAuth"; import { useRepoSync } from "@/hooks/useSyncRepo"; import { useConfigStatus } from "@/hooks/useConfigStatus"; // Navigation context to signal when navigation happens const NavigationContext = createContext<{ navigationKey: number }>({ navigationKey: 0 }); export const useNavigation = () => useContext(NavigationContext); interface AppProps { page: | "dashboard" | "repositories" | "organizations" | "configuration" | "activity-log"; "client:load"?: boolean; "client:idle"?: boolean; "client:visible"?: boolean; "client:media"?: string; "client:only"?: boolean | string; } export default function App({ page }: AppProps) { return ( ); } function AppWithProviders({ page: initialPage }: AppProps) { const { user, isLoading: authLoading } = useAuth(); const { isLoading: configLoading } = useConfigStatus(); const [currentPage, setCurrentPage] = useState(initialPage); const [navigationKey, setNavigationKey] = useState(0); const [sidebarOpen, setSidebarOpen] = useState(false); const [sidebarCollapsed, setSidebarCollapsed] = useState(() => { // Check if we're on medium screens (768px - 1280px) if (typeof window !== 'undefined') { return window.innerWidth >= 768 && window.innerWidth < 1280; } return false; }); useRepoSync({ userId: user?.id, enabled: false, // TODO: Get from config interval: 3600, // TODO: Get from config lastSync: null, nextSync: null, }); // Handle navigation from sidebar const handleNavigation = (pageName: string) => { setCurrentPage(pageName as AppProps['page']); // Increment navigation key to force components to refresh their loading state setNavigationKey(prev => prev + 1); }; // Handle browser back/forward navigation useEffect(() => { const handlePopState = () => { const path = window.location.pathname; const pageMap: Record = { '/': 'dashboard', '/repositories': 'repositories', '/organizations': 'organizations', '/config': 'configuration', '/activity': 'activity-log' }; const pageName = pageMap[path] || 'dashboard'; setCurrentPage(pageName); // Also increment navigation key for browser navigation to trigger loading states setNavigationKey(prev => prev + 1); }; window.addEventListener('popstate', handlePopState); return () => window.removeEventListener('popstate', handlePopState); }, []); // Handle window resize to auto-collapse sidebar on medium screens useEffect(() => { const handleResize = () => { const width = window.innerWidth; // Auto-collapse on medium screens (768px - 1280px) if (width >= 768 && width < 1280) { setSidebarCollapsed(true); } else if (width >= 1280) { // Expand on large screens setSidebarCollapsed(false); } }; window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); // Show loading state only during initial auth/config loading const isInitialLoading = authLoading || (configLoading && !user); if (isInitialLoading) { return (

Loading...

); } // Redirect to login if not authenticated if (!authLoading && !user) { // Use window.location for client-side redirect if (typeof window !== 'undefined') { window.location.href = '/login'; } return null; } return (
setSidebarOpen(!sidebarOpen)} onToggleCollapse={() => setSidebarCollapsed(!sidebarCollapsed)} isSidebarCollapsed={sidebarCollapsed} isSidebarOpen={sidebarOpen} />
setSidebarOpen(false)} onToggleCollapse={() => setSidebarCollapsed(!sidebarCollapsed)} />
{currentPage === "dashboard" && } {currentPage === "repositories" && } {currentPage === "organizations" && } {currentPage === "configuration" && } {currentPage === "activity-log" && }
); }