108 lines
4.1 KiB
TypeScript
108 lines
4.1 KiB
TypeScript
import { Routes, Route, Navigate } from 'react-router'
|
||
import { Component, Suspense, lazy, type ReactNode } from 'react'
|
||
import { StoreProvider, useStore } from './store/store'
|
||
import AppLayout from './components/AppLayout'
|
||
import LadeSkeleton from './components/LadeSkeleton'
|
||
import Login from './pages/Login'
|
||
|
||
// Seiten werden beim ersten Aufruf nachgeladen (Code-Splitting) –
|
||
// Verwaltungsmodule landen nicht im Bundle der Mieter.
|
||
const Dashboard = lazy(() => import('./pages/Dashboard'))
|
||
const Payments = lazy(() => import('./pages/Payments'))
|
||
const Tickets = lazy(() => import('./pages/Tickets'))
|
||
const Documents = lazy(() => import('./pages/Documents'))
|
||
const Messages = lazy(() => import('./pages/Messages'))
|
||
const Zaehler = lazy(() => import('./pages/Zaehler'))
|
||
const Kosten = lazy(() => import('./pages/Kosten'))
|
||
const Bestand = lazy(() => import('./pages/Bestand'))
|
||
const Mietvertraege = lazy(() => import('./pages/Mietvertraege'))
|
||
const MieterVerwaltung = lazy(() => import('./pages/MieterVerwaltung'))
|
||
const Assistent = lazy(() => import('./pages/Assistent'))
|
||
const BenutzerVerwaltung = lazy(() => import('./pages/BenutzerVerwaltung'))
|
||
const Profil = lazy(() => import('./pages/Profil'))
|
||
const Anleitung = lazy(() => import('./pages/Anleitung'))
|
||
|
||
/** Fängt Render-Fehler ab – statt schwarzem Bildschirm: Hinweis + Reload. */
|
||
class FehlerGrenze extends Component<{ children: ReactNode }, { fehler: boolean }> {
|
||
state = { fehler: false }
|
||
static getDerivedStateFromError() {
|
||
return { fehler: true }
|
||
}
|
||
render() {
|
||
if (this.state.fehler) {
|
||
return (
|
||
<div className="flex min-h-screen items-center justify-center bg-[#22333b] p-6">
|
||
<div className="max-w-md rounded-2xl bg-white p-8 text-center shadow-2xl dark:bg-slate-900">
|
||
<h1 className="text-xl font-bold">Da ist etwas schiefgelaufen</h1>
|
||
<p className="mt-2 text-sm text-slate-500">
|
||
Die Seite konnte nicht korrekt dargestellt werden. Ein Neuladen hilft in der Regel weiter.
|
||
</p>
|
||
<button
|
||
onClick={() => window.location.reload()}
|
||
className="mt-5 rounded-xl bg-amber-500 px-6 py-2.5 font-semibold text-slate-900 hover:bg-amber-400"
|
||
>
|
||
Seite neu laden
|
||
</button>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
return this.props.children
|
||
}
|
||
}
|
||
|
||
function Ladebildschirm() {
|
||
return <LadeSkeleton />
|
||
}
|
||
|
||
function RequireAuth({ children }: { children: React.ReactElement }) {
|
||
const { me, bereit } = useStore()
|
||
if (!bereit) return <Ladebildschirm />
|
||
if (!me) return <Navigate to="/login" replace />
|
||
return children
|
||
}
|
||
|
||
function LoginGate() {
|
||
const { me, bereit } = useStore()
|
||
if (!bereit) return <Ladebildschirm />
|
||
if (me) return <Navigate to="/" replace />
|
||
return <Login />
|
||
}
|
||
|
||
export default function App() {
|
||
return (
|
||
<FehlerGrenze>
|
||
<StoreProvider>
|
||
<Suspense fallback={<Ladebildschirm />}>
|
||
<Routes>
|
||
<Route path="/login" element={<LoginGate />} />
|
||
<Route
|
||
element={
|
||
<RequireAuth>
|
||
<AppLayout />
|
||
</RequireAuth>
|
||
}
|
||
>
|
||
<Route path="/" element={<Dashboard />} />
|
||
<Route path="/mietkonto" element={<Payments />} />
|
||
<Route path="/schadensmeldungen" element={<Tickets />} />
|
||
<Route path="/zaehler" element={<Zaehler />} />
|
||
<Route path="/kosten" element={<Kosten />} />
|
||
<Route path="/bestand" element={<Bestand />} />
|
||
<Route path="/mietvertraege" element={<Mietvertraege />} />
|
||
<Route path="/mieter" element={<MieterVerwaltung />} />
|
||
<Route path="/assistent" element={<Assistent />} />
|
||
<Route path="/dokumente" element={<Documents />} />
|
||
<Route path="/nachrichten" element={<Messages />} />
|
||
<Route path="/anleitung" element={<Anleitung />} />
|
||
<Route path="/profil" element={<Profil />} />
|
||
<Route path="/benutzer" element={<BenutzerVerwaltung />} />
|
||
</Route>
|
||
<Route path="*" element={<Navigate to="/" replace />} />
|
||
</Routes>
|
||
</Suspense>
|
||
</StoreProvider>
|
||
</FehlerGrenze>
|
||
)
|
||
}
|