import { lazy, Suspense, useCallback, useEffect, useState } from 'react'
import { BrowserRouter, Routes, Route, Navigate, Link, useLocation } from 'react-router-dom'
import { AuthProvider, useAuth } from './context/AuthContext'
import Sidebar from './components/Navbar'
import Logo from './components/Logo'
import LoginPage from './pages/LoginPage'
import TicketsPage from './pages/TicketsPage'
import TicketPage from './pages/TicketPage'
import PlanboardPage from './pages/PlanboardPage'
import ProjectsPage from './pages/ProjectsPage'
import AdminPage from './pages/AdminPage'
import CustomersPage from './pages/CustomersPage'
import CustomerDetailPage from './pages/CustomerDetailPage'
import CustomerChatPage from './pages/CustomerChatPage'
import StorageTasksPage from './pages/StorageTasksPage'
import CreditsPage from './pages/CreditsPage'
import OffersPage from './pages/OffersPage'
import FinancePage from './pages/FinancePage'
import FinanceSettingsPage from './pages/FinanceSettingsPage'
import LegalPage from './pages/LegalPage'
import AssignProjectPage from './pages/AssignProjectPage'
import ServicesPage from './pages/ServicesPage'
import ServerpulsPage from './pages/ServerpulsPage'
import BankCallbackPage from './pages/BankCallbackPage'
import AdminRoute from './components/AdminRoute'
import RouteErrorBoundary from './components/RouteErrorBoundary'
import { safeReturnPath } from './lib/returnPath'
// Hochhaus der Hustler: erst beim Öffnen laden, damit Engine und Schrift nicht im Haupt-Bundle liegen
const WorkersPage = lazy(() => import('./pages/WorkersPage'))
function ProtectedRoute({ children }) {
const { user, loading } = useAuth()
const location = useLocation()
if (loading) {
return
Wird geladen …
}
if (!user) {
return
}
return children
}
// Alte Adressen /leads und /workers führen auf /hustler, die Query bleibt (/workers?tab=botleads&bot= wird /hustler?tab=botleads&bot=)
function HustlerRedirect() {
const { search } = useLocation()
return
}
function AppRoutes() {
const { user } = useAuth()
const location = useLocation()
return (
: } />
} />
} />
} />
} />
{/* Messenger (Kunden -> Chat); statische Pfade gehen in react-router vor /customers/:id */}
} />
} />
} />
} />
} />
Wird geladen …}>} />
} />
} />
{/* Finanzen: nur Admins, alle anderen gehen zu /tickets */}
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
{/* Alte Links (z. B. die entfernten Seiten Assets, Reports, Docs, Roadmaps) landen bei den Tickets */}
} />
)
}
function AppContent() {
const { user } = useAuth()
const location = useLocation()
// Schublade des Menues auf dem Handy; auf dem Desktop steht das Menue fest und menuOpen bleibt ohne Wirkung
const [menuOpen, setMenuOpen] = useState(false)
const open = useCallback(() => setMenuOpen(true), [])
const close = useCallback(() => setMenuOpen(false), [])
// Seitenwechsel (nur der Pfad, nicht ?woid= oder ?tab=): Schublade zu und wieder nach oben
useEffect(() => {
setMenuOpen(false)
window.scrollTo(0, 0)
}, [location.pathname])
// Esc schliesst die Schublade, nur solange sie offen ist und nur, wenn kein anderer Baustein die Taste schon behandelt hat
useEffect(() => {
if (!menuOpen) return undefined
const onKey = (e) => {
if (e.defaultPrevented) return
if (e.key === 'Escape') setMenuOpen(false)
}
document.addEventListener('keydown', onKey)
return () => document.removeEventListener('keydown', onKey)
}, [menuOpen])
if (!user) {
return
}
return (
WEBklar
{/* Fängt u. a. einen fehlenden lazy-Chunk ab (alter Tab nach einem Deploy): Menü bleibt, Knopf lädt neu */}