'use client' import { useState, useEffect } from 'react' import { useAos } from '@/store/aos' import { SidebarNav } from './sidebar-nav' import { TopBar } from './top-bar' import { Footer } from './footer' import { CommandMenu } from './command-menu' import { CompanyDrawer } from './company-drawer' import { Sheet, SheetContent, SheetTitle } from '@/components/ui/sheet' import { DashboardView } from './views/dashboard' import { CalendarView } from './views/calendar' import { ReportingView } from './views/reporting' import { CrmView } from './views/crm' import { LeadsView } from './views/leads' import { EstimatesView } from './views/estimates' import { ProjectsView } from './views/projects' import { TimesheetView } from './views/timesheet' import { SupportView } from './views/support' import { LicensesView } from './views/licenses' import { ContractsView } from './views/contracts' import { ExpensesView } from './views/expenses' import { FinanceView } from './views/finance' import { RecurringView } from './views/recurring' import { AccountingView } from './views/accounting' import { FinanzamtView } from './views/finanzamt' import { AuditView } from './views/audit' import { DataView } from './views/data' import { KbView } from './views/kb' import { ApiView } from './views/api' import { SettingsView } from './views/settings' import { GlobalSettingsView } from './views/global-settings' import { SetupWizardView } from './views/setup-wizard' import { PortalShell } from './portal-shell' import { OnboardingOverlay } from './onboarding-overlay' import { MobileBottomNav } from './mobile-bottom-nav' export function AppShell() { const { view, sidebarOpen, setSidebarOpen, portalMode } = useAos() const [mounted, setMounted] = useState(false) // Hydration gate: wait for client mount before rendering interactive UI // This prevents Radix UI useId() mismatches between server and client useEffect(() => { // eslint-disable-next-line react-hooks/set-state-in-effect setMounted(true) }, []) // Portal mode renders a completely separate experience if (portalMode) return // Before mount: render a minimal skeleton to prevent hydration mismatch if (!mounted) { return (
) } return (
{/* Desktop sidebar */} {/* Mobile sidebar */} Navigation {/* Main */}
{view === 'dashboard' && } {view === 'calendar' && } {view === 'reporting' && } {view === 'crm' && } {view === 'leads' && } {view === 'estimates' && } {view === 'projects' && } {view === 'timesheet' && } {view === 'support' && } {view === 'licenses' && } {view === 'contracts' && } {view === 'expenses' && } {view === 'finance' && } {view === 'recurring' && } {view === 'accounting' && } {view === 'finanzamt' && } {view === 'audit' && } {view === 'data' && } {view === 'kb' && } {view === 'api' && } {view === 'settings' && } {view === 'settings_global' && } {view === 'setup' && }
) }