Files
MABEA/frontend/src/App.tsx
T
patrickandClaude Sonnet 5 eb20affd5d
CI / backend-tests (push) Failing after 1m37s
CI / frontend-build (push) Successful in 18s
feat(mangel): Mangel-Ticket-System (Roadmap Phase 2)
Eigener Workflow für Schäden/Defekte, getrennt von Fehlbestand (Mengen-
Abweichung Soll/Ist). Status: neu → in_bearbeitung → ersatzteil_bestellt/
reparatur_geplant → erledigt. entitaet_typ/entitaet_id optional (Objektposition
oder Geräteinstanz), analog zum bestehenden historie.entitaet_typ-Muster,
objekt_id immer gesetzt für Dashboard-Abfragen.

Ein offener Mangel mit prioritaet=hoch macht das Objekt "nicht einsatzbereit"
(neuer Grund mangel_kritisch_offen in dashboard.einsatzbereitschaft) -
niedrige/normale Mängel blockieren nicht.

Melden/Lesen: alle Mitarbeiter+. Status ändern: Materialverantwortliche+.
Neue Seite /maengel für alle eingeloggten Nutzer (Nav-Link "Mängel").

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
2026-09-05 13:23:38 +02:00

94 lines
2.6 KiB
TypeScript

import type { ReactNode } from "react";
import { Navigate, Route, Routes } from "react-router-dom";
import { AuthProvider, useAuth } from "./auth/AuthContext";
import { AppShell } from "./components/AppShell";
import { AdminPage } from "./pages/AdminPage";
import { DashboardPage } from "./pages/DashboardPage";
import { FehlbestandListePage } from "./pages/FehlbestandListePage";
import { KontrollPage } from "./pages/KontrollPage";
import { LoginPage } from "./pages/LoginPage";
import { MangelListePage } from "./pages/MangelListePage";
import { ObjektListPage } from "./pages/ObjektListPage";
function GeschuetzteRoute({ children }: { children: ReactNode }) {
const { eingeloggt } = useAuth();
if (!eingeloggt) {
return <Navigate to="/login" replace />;
}
return <AppShell>{children}</AppShell>;
}
function AdminRoute({ children }: { children: ReactNode }) {
const { eingeloggt, istVerantwortlich } = useAuth();
if (!eingeloggt) {
return <Navigate to="/login" replace />;
}
// Nicht mehr admin-exklusiv: Materialverantwortliche/Leitungsverantwortliche
// dürfen rein, sehen dort aber nur die für sie freigeschalteten Tabs
// (AdminPage filtert selbst nach Rolle, Backend erzwingt es ohnehin je Endpunkt).
if (!istVerantwortlich) {
return <Navigate to="/objekte" replace />;
}
return <AppShell>{children}</AppShell>;
}
export default function App() {
return (
<AuthProvider>
<Routes>
<Route path="/login" element={<LoginPage />} />
<Route
path="/objekte"
element={
<GeschuetzteRoute>
<ObjektListPage />
</GeschuetzteRoute>
}
/>
<Route
path="/objekte/:objektId/kontrolle"
element={
<GeschuetzteRoute>
<KontrollPage />
</GeschuetzteRoute>
}
/>
<Route
path="/admin"
element={
<AdminRoute>
<AdminPage />
</AdminRoute>
}
/>
<Route
path="/maengel"
element={
<GeschuetzteRoute>
<MangelListePage />
</GeschuetzteRoute>
}
/>
<Route
path="/fehlbestaende"
element={
<AdminRoute>
<FehlbestandListePage />
</AdminRoute>
}
/>
<Route
path="/dashboard"
element={
<AdminRoute>
<DashboardPage />
</AdminRoute>
}
/>
<Route path="*" element={<Navigate to="/objekte" replace />} />
</Routes>
</AuthProvider>
);
}