// TODO: P2-F1 — Replace hardcoded plugin routes with dynamic PluginRouteRenderer import React, { Suspense } from 'react'; import { createBrowserRouter, RouterProvider, Navigate } from 'react-router-dom'; import { AppShell } from '@/components/layout/AppShell'; import { StartLayout } from '@/components/layout/StartLayout'; import { ProtectedRoute } from './ProtectedRoute'; import { ProtectedRoute as PermissionRoute } from '@/components/common/ProtectedRoute'; import { LoginPage } from '@/pages/Login'; import { GuestLoginPage } from '@/pages/GuestLogin'; import { GuestContactsPage } from '@/pages/GuestContacts'; import { PasswordResetRequestPage } from '@/pages/PasswordResetRequest'; import { PasswordResetConfirmPage } from '@/pages/PasswordResetConfirm'; import { Loader2 } from 'lucide-react'; import { PluginRouteRenderer } from '@/components/plugins/PluginRouteRenderer'; import { ErrorBoundary } from '@/components/common/ErrorBoundary'; // Lazy-loaded pages (code-splitting) const DashboardPage = React.lazy(() => import('@/pages/Dashboard').then(m => ({ default: m.DashboardPage }))); const AuditLogPage = React.lazy(() => import('@/pages/AuditLog').then(m => ({ default: m.AuditLogPage }))); const GlobalSearchResultsPage = React.lazy(() => import('@/pages/GlobalSearchResults').then(m => ({ default: m.GlobalSearchResultsPage }))); const SettingsPage = React.lazy(() => import('@/pages/Settings').then(m => ({ default: m.SettingsPage }))); const SettingsProfilePage = React.lazy(() => import('@/pages/SettingsProfile').then(m => ({ default: m.SettingsProfilePage }))); const SettingsRolesPage = React.lazy(() => import('@/pages/SettingsRoles').then(m => ({ default: m.SettingsRolesPage }))); const SettingsUsersPage = React.lazy(() => import('@/pages/SettingsUsers').then(m => ({ default: m.SettingsUsersPage }))); const SettingsGroupsPage = React.lazy(() => import('@/pages/SettingsGroups').then(m => ({ default: m.SettingsGroupsPage }))); const SettingsPluginsPage = React.lazy(() => import('@/pages/SettingsPlugins').then(m => ({ default: m.SettingsPluginsPage }))); const SettingsSystemPage = React.lazy(() => import('@/pages/SettingsSystem').then(m => ({ default: m.SettingsSystemPage }))); const SettingsCurrenciesPage = React.lazy(() => import('@/pages/SettingsCurrencies').then(m => ({ default: m.SettingsCurrenciesPage }))); const SettingsTaxesPage = React.lazy(() => import('@/pages/SettingsTaxes').then(m => ({ default: m.SettingsTaxesPage }))); const SettingsSequencesPage = React.lazy(() => import('@/pages/SettingsSequences').then(m => ({ default: m.SettingsSequencesPage }))); const CalendarPage = React.lazy(() => import('@/pages/Calendar').then(m => ({ default: m.CalendarPage }))); const CalendarKanbanPage = React.lazy(() => import('@/pages/CalendarKanban').then(m => ({ default: m.CalendarKanbanPage }))); const DmsPage = React.lazy(() => import('@/pages/Dms').then(m => ({ default: m.DmsPage }))); const DmsTrashPage = React.lazy(() => import('@/pages/DmsTrash').then(m => ({ default: m.DmsTrashPage }))); const TrashPage = React.lazy(() => import('@/pages/Trash').then(m => ({ default: m.TrashPage }))); const MailPage = React.lazy(() => import('@/pages/Mail').then(m => ({ default: m.MailPage }))); const MailSettingsPage = React.lazy(() => import('@/pages/MailSettings').then(m => ({ default: m.MailSettingsPage }))); const SettingsNotificationsPage = React.lazy(() => import('@/pages/SettingsNotifications').then(m => ({ default: m.SettingsNotificationsPage }))); const AISettingsPage = React.lazy(() => import('@/pages/AISettings').then(m => ({ default: m.AISettingsPage }))); const ProactiveAISettings = React.lazy(() => import('@/pages/ProactiveAISettings').then(m => ({ default: m.ProactiveAISettings }))); const SettingsThemePage = React.lazy(() => import('@/pages/SettingsTheme').then(m => ({ default: m.SettingsThemePage }))); const SettingsMcpPage = React.lazy(() => import('@/pages/SettingsMcp').then(m => ({ default: m.SettingsMcpPage }))); const DmsStandalonePage = React.lazy(() => import('@/pages/DmsStandalone').then(m => ({ default: m.DmsStandalonePage }))); const CalendarStandalonePage = React.lazy(() => import('@/pages/CalendarStandalone').then(m => ({ default: m.CalendarStandalonePage }))); const MailStandalonePage = React.lazy(() => import('@/pages/MailStandalone').then(m => ({ default: m.MailStandalonePage }))); const ContactsStandalonePage = React.lazy(() => import('@/pages/ContactsStandalone').then(m => ({ default: m.ContactsStandalonePage }))); const SettingsAIPage = React.lazy(() => import('@/pages/SettingsAI').then(m => ({ default: m.SettingsAIPage }))); const SettingsMenuOrderPage = React.lazy(() => import('@/pages/SettingsMenuOrder').then(m => ({ default: m.SettingsMenuOrderPage }))); const SettingsStammdatenPage = React.lazy(() => import('@/pages/SettingsStammdaten').then(m => ({ default: m.SettingsStammdatenPage }))); const SettingsUserManagementPage = React.lazy(() => import('@/pages/SettingsUserManagement').then(m => ({ default: m.SettingsUserManagementPage }))); const AutomationDashboardPage = React.lazy(() => import('@/pages/AutomationDashboard').then(m => ({ default: m.AutomationDashboardPage }))); const AgentDashboardPage = React.lazy(() => import('@/pages/AgentDashboard').then(m => ({ default: m.AgentDashboardPage }))); const AutomationSettingsPage = React.lazy(() => import('@/pages/AutomationSettings').then(m => ({ default: m.AutomationSettingsPage }))); const ReportsPage = React.lazy(() => import('@/pages/Reports').then(m => ({ default: m.ReportsPage }))); const DocumentSettingsPage = React.lazy(() => import('@/pages/DocumentSettings').then(m => ({ default: m.DocumentSettingsPage }))); const TasksPage = React.lazy(() => import('@/pages/Tasks').then(m => ({ default: m.TasksPage }))); const CommunicationPage = React.lazy(() => import('@/pages/Communication').then(m => ({ default: m.CommunicationPage }))); const WorkflowsPage = React.lazy(() => import('@/pages/Workflows').then(m => ({ default: m.WorkflowsPage }))); const ImportExportPage = React.lazy(() => import('@/pages/ImportExport').then(m => ({ default: m.ImportExportPage }))); const TagsPage = React.lazy(() => import('@/pages/Tags').then(m => ({ default: m.TagsPage }))); const CustomFieldsPage = React.lazy(() => import('@/pages/CustomFields').then(m => ({ default: m.CustomFieldsPage }))); const ActivityTimelinePage = React.lazy(() => import('@/pages/ActivityTimeline').then(m => ({ default: m.ActivityTimelinePage }))); const SettingsWebhooksPage = React.lazy(() => import('@/pages/SettingsWebhooks').then(m => ({ default: m.SettingsWebhooksPage }))); const SettingsBackupPage = React.lazy(() => import('@/pages/SettingsBackup').then(m => ({ default: m.SettingsBackupPage }))); const WorkspaceManagerPage = React.lazy(() => import('@/pages/SettingsWorkspaces').then(m => ({ default: m.WorkspaceManagerPage }))); const SettingsRechtePage = React.lazy(() => import('@/pages/SettingsRechte').then(m => ({ default: m.SettingsRechtePage }))); const NoAccessPage = React.lazy(() => import('@/pages/NoAccessPage').then(m => ({ default: m.NoAccessPage }))); const StartPage = React.lazy(() => import('@/pages/StartPage').then(m => ({ default: m.StartPage }))); const HelpPage = React.lazy(() => import('@/pages/Help').then(m => ({ default: m.HelpPage }))); const HelpWelcomePage = React.lazy(() => import('@/pages/help/HelpWelcome').then(m => ({ default: m.HelpWelcomePage }))); const HelpLoginPage = React.lazy(() => import('@/pages/help/HelpLogin').then(m => ({ default: m.HelpLoginPage }))); const HelpNavigationPage = React.lazy(() => import('@/pages/help/HelpNavigation').then(m => ({ default: m.HelpNavigationPage }))); const HelpContactsPage = React.lazy(() => import('@/pages/help/HelpContacts').then(m => ({ default: m.HelpContactsPage }))); const HelpMailSetupPage = React.lazy(() => import('@/pages/help/HelpMailSetup').then(m => ({ default: m.HelpMailSetupPage }))); const HelpPlaceholderPage = React.lazy(() => import('@/pages/help/HelpPlaceholder').then(m => ({ default: m.HelpPlaceholderPage }))); const AgentsPage = React.lazy(() => import('@/pages/Agents').then(m => ({ default: m.AgentsPage }))); const AgentsOverviewPage = React.lazy(() => import('@/pages/agents/AgentsOverview').then(m => ({ default: m.AgentsOverviewPage }))); const AgentsPlaceholderPage = React.lazy(() => import('@/pages/agents/AgentsPlaceholder').then(m => ({ default: m.AgentsPlaceholderPage }))); const AutomationPage = React.lazy(() => import('@/pages/Automation').then(m => ({ default: m.AutomationPage }))); const AutomationOverviewPage = React.lazy(() => import('@/pages/automation/AutomationOverview').then(m => ({ default: m.AutomationOverviewPage }))); const AutomationPlaceholderPage = React.lazy(() => import('@/pages/automation/AutomationPlaceholder').then(m => ({ default: m.AutomationPlaceholderPage }))); const LogsPage = React.lazy(() => import('@/pages/Logs').then(m => ({ default: m.LogsPage }))); const LogsOverviewPage = React.lazy(() => import('@/pages/logs/LogsOverview').then(m => ({ default: m.LogsOverviewPage }))); const LogsPlaceholderPage = React.lazy(() => import('@/pages/logs/LogsPlaceholder').then(m => ({ default: m.LogsPlaceholderPage }))); const HelpApiDocsPage = React.lazy(() => import('@/pages/help/HelpApiDocs').then(m => ({ default: m.HelpApiDocsPage }))); const ApiDocsPage = React.lazy(() => import('@/pages/ApiDocs').then(m => ({ default: m.ApiDocsPage }))); const WikiPage = React.lazy(() => import('@/pages/Wiki').then(m => ({ default: m.WikiPage }))); const SystemDashboardPage = React.lazy(() => import('@/pages/SystemDashboard').then(m => ({ default: m.SystemDashboardPage }))); /** Centered spinner fallback for lazy-loaded routes */ function PageLoader() { return (
); } /** Wrap a lazy element in Suspense with PageLoader fallback */ function withSuspense(element: React.ReactElement) { return }>{element}; } const router = createBrowserRouter([ { path: '/login', element: , }, { }, { path: '/dms-standalone', element: {withSuspense()}, }, { path: '/calendar-standalone', element: {withSuspense()}, }, { path: '/mail-standalone', element: {withSuspense()}, }, { path: '/contacts-standalone', element: {withSuspense()}, }, { path: '/password-reset', element: , }, { path: '/password-reset/confirm', element: , }, { path: '/guest/login', element: , }, { path: '/guest/contacts', element: , }, { path: '/kein-zugriff', element: {withSuspense()}, }, { element: ( ), children: [ { path: '/start', element: withSuspense() }, { path: '/help', element: withSuspense(), children: [ { path: 'welcome', element: withSuspense() }, { path: 'login', element: withSuspense() }, { path: 'navigation', element: withSuspense() }, { path: 'contacts', element: withSuspense() }, { path: 'mail-setup', element: withSuspense() }, { path: 'api-docs', element: withSuspense() }, { path: '*', element: withSuspense() }, ], }, { path: '/agents', element: withSuspense(), children: [ { path: 'overview', element: withSuspense() }, { path: 'automation', element: withSuspense() }, { path: 'automation-settings', element: withSuspense() }, { path: 'ai-settings', element: withSuspense() }, { path: 'ai-proactive', element: withSuspense() }, { path: '*', element: withSuspense() }, ], }, { path: '/automation', element: withSuspense(), children: [ { path: 'overview', element: withSuspense() }, { path: 'runs', element: withSuspense() }, { path: 'versions', element: withSuspense() }, { path: 'triggers', element: withSuspense() }, { path: 'actions', element: withSuspense() }, { path: 'conditions', element: withSuspense() }, { path: '*', element: withSuspense() }, ], }, { path: '/logs', element: withSuspense(), children: [ { path: 'overview', element: withSuspense() }, { path: '*', element: withSuspense() }, ], }, { path: '/settings', element: {withSuspense()}, children: [ { path: 'stammdaten', element: withSuspense() }, { path: 'user-management', element: withSuspense() }, { path: 'roles', element: withSuspense() }, { path: 'users', element: withSuspense() }, { path: 'groups', element: withSuspense() }, { path: 'plugins', element: withSuspense() }, { path: 'system', element: withSuspense() }, { path: 'currencies', element: withSuspense() }, { path: 'taxes', element: withSuspense() }, { path: 'sequences', element: withSuspense() }, { path: 'mail', element: withSuspense() }, { path: 'notifications', element: withSuspense() }, { path: 'ai', element: withSuspense() }, { path: 'ai-proactive', element: withSuspense() }, { path: 'theme', element: withSuspense() }, { path: 'automation', element: withSuspense() }, { path: 'mcp', element: withSuspense() }, { path: 'ai-settings', element: withSuspense() }, { path: 'menu', element: withSuspense() }, { path: 'custom-fields', element: withSuspense() }, { path: 'webhooks', element: withSuspense() }, { path: 'workspaces', element: withSuspense() }, { path: 'documents', element: withSuspense() }, { path: 'backup', element: withSuspense() }, { path: 'rechte', element: {withSuspense()} }, { path: '*', element: {} }, ], }, ], }, { element: ( ), children: [ { path: '/', element: }, { path: '/dashboard', element: withSuspense() }, { path: '/audit-log', element: {withSuspense()} }, { path: '/search', element: withSuspense() }, { path: '/calendar', element: {withSuspense()} }, { path: '/calendar/kanban', element: {withSuspense()} }, { path: '/dms', element: {withSuspense()} }, { path: '/dms/trash', element: {withSuspense()} }, { path: '/trash', element: {withSuspense()} }, { path: '/mail', element: {withSuspense()} }, { path: '/mail/settings', element: {withSuspense()} }, { path: '/reports', element: {withSuspense()} }, { path: '/tasks', element: {withSuspense()} }, { path: '/communication', element: {withSuspense()} }, { path: '/workflows', element: {withSuspense()} }, { path: '/import-export', element: {withSuspense()} }, { path: 'tags', element: {withSuspense()} }, { path: '/api-docs', element: {withSuspense()} }, { path: '/activity', element: {withSuspense()} }, { path: '/wiki', element: {withSuspense()} }, { path: '/system-dashboard', element: withSuspense() }, { path: '/profile', element: withSuspense() }, { path: '*', element: {} }, ], }, ]); export function AppRouter() { return ; }