bug fix for atemschutz
This commit is contained in:
@@ -78,6 +78,8 @@ import incidentRoutes from './routes/incident.routes';
|
|||||||
import equipmentRoutes from './routes/equipment.routes';
|
import equipmentRoutes from './routes/equipment.routes';
|
||||||
import nextcloudRoutes from './routes/nextcloud.routes';
|
import nextcloudRoutes from './routes/nextcloud.routes';
|
||||||
import atemschutzRoutes from './routes/atemschutz.routes';
|
import atemschutzRoutes from './routes/atemschutz.routes';
|
||||||
|
import eventsRoutes from './routes/events.routes';
|
||||||
|
import bookingRoutes from './routes/booking.routes';
|
||||||
|
|
||||||
app.use('/api/auth', authRoutes);
|
app.use('/api/auth', authRoutes);
|
||||||
app.use('/api/user', userRoutes);
|
app.use('/api/user', userRoutes);
|
||||||
@@ -89,6 +91,8 @@ app.use('/api/incidents', incidentRoutes);
|
|||||||
app.use('/api/equipment', equipmentRoutes);
|
app.use('/api/equipment', equipmentRoutes);
|
||||||
app.use('/api/atemschutz', atemschutzRoutes);
|
app.use('/api/atemschutz', atemschutzRoutes);
|
||||||
app.use('/api/nextcloud/talk', nextcloudRoutes);
|
app.use('/api/nextcloud/talk', nextcloudRoutes);
|
||||||
|
app.use('/api/events', eventsRoutes);
|
||||||
|
app.use('/api/bookings', bookingRoutes);
|
||||||
|
|
||||||
// 404 handler
|
// 404 handler
|
||||||
app.use(notFoundHandler);
|
app.use(notFoundHandler);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { authenticate } from '../middleware/auth.middleware';
|
|||||||
import { requireGroups } from '../middleware/rbac.middleware';
|
import { requireGroups } from '../middleware/rbac.middleware';
|
||||||
|
|
||||||
const ADMIN_GROUPS = ['dashboard_admin'];
|
const ADMIN_GROUPS = ['dashboard_admin'];
|
||||||
const WRITE_GROUPS = ['dashboard_admin', 'dashboard_kommandant'];
|
const WRITE_GROUPS = ['dashboard_admin', 'dashboard_atemschutz'];
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import EinsatzDetail from './pages/EinsatzDetail';
|
|||||||
import Fahrzeuge from './pages/Fahrzeuge';
|
import Fahrzeuge from './pages/Fahrzeuge';
|
||||||
import FahrzeugDetail from './pages/FahrzeugDetail';
|
import FahrzeugDetail from './pages/FahrzeugDetail';
|
||||||
import FahrzeugForm from './pages/FahrzeugForm';
|
import FahrzeugForm from './pages/FahrzeugForm';
|
||||||
|
import FahrzeugBuchungen from './pages/FahrzeugBuchungen';
|
||||||
import Ausruestung from './pages/Ausruestung';
|
import Ausruestung from './pages/Ausruestung';
|
||||||
import AusruestungForm from './pages/AusruestungForm';
|
import AusruestungForm from './pages/AusruestungForm';
|
||||||
import AusruestungDetail from './pages/AusruestungDetail';
|
import AusruestungDetail from './pages/AusruestungDetail';
|
||||||
@@ -21,6 +22,8 @@ import Mitglieder from './pages/Mitglieder';
|
|||||||
import MitgliedDetail from './pages/MitgliedDetail';
|
import MitgliedDetail from './pages/MitgliedDetail';
|
||||||
import Kalender from './pages/Kalender';
|
import Kalender from './pages/Kalender';
|
||||||
import UebungDetail from './pages/UebungDetail';
|
import UebungDetail from './pages/UebungDetail';
|
||||||
|
import Veranstaltungen from './pages/Veranstaltungen';
|
||||||
|
import VeranstaltungKategorien from './pages/VeranstaltungKategorien';
|
||||||
import NotFound from './pages/NotFound';
|
import NotFound from './pages/NotFound';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
@@ -176,6 +179,30 @@ function App() {
|
|||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
path="/veranstaltungen"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Veranstaltungen />
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/veranstaltungen/kategorien"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<VeranstaltungKategorien />
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/fahrzeugbuchungen"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<FahrzeugBuchungen />
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
<Route path="*" element={<NotFound />} />
|
<Route path="*" element={<NotFound />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</AuthProvider>
|
</AuthProvider>
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ import {
|
|||||||
Build,
|
Build,
|
||||||
People,
|
People,
|
||||||
Air,
|
Air,
|
||||||
|
Event,
|
||||||
|
BookOnline,
|
||||||
|
CalendarMonth,
|
||||||
} from '@mui/icons-material';
|
} from '@mui/icons-material';
|
||||||
import { useNavigate, useLocation } from 'react-router-dom';
|
import { useNavigate, useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
@@ -31,11 +34,26 @@ const navigationItems: NavigationItem[] = [
|
|||||||
icon: <DashboardIcon />,
|
icon: <DashboardIcon />,
|
||||||
path: '/dashboard',
|
path: '/dashboard',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: 'Kalender',
|
||||||
|
icon: <CalendarMonth />,
|
||||||
|
path: '/kalender',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Veranstaltungen',
|
||||||
|
icon: <Event />,
|
||||||
|
path: '/veranstaltungen',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: 'Fahrzeuge',
|
text: 'Fahrzeuge',
|
||||||
icon: <DirectionsCar />,
|
icon: <DirectionsCar />,
|
||||||
path: '/fahrzeuge',
|
path: '/fahrzeuge',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: 'Fahrzeugbuchungen',
|
||||||
|
icon: <BookOnline />,
|
||||||
|
path: '/fahrzeugbuchungen',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: 'Ausrüstung',
|
text: 'Ausrüstung',
|
||||||
icon: <Build />,
|
icon: <Build />,
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import DashboardLayout from '../components/dashboard/DashboardLayout';
|
|||||||
import { atemschutzApi } from '../services/atemschutz';
|
import { atemschutzApi } from '../services/atemschutz';
|
||||||
import { membersService } from '../services/members';
|
import { membersService } from '../services/members';
|
||||||
import { useNotification } from '../contexts/NotificationContext';
|
import { useNotification } from '../contexts/NotificationContext';
|
||||||
|
import { useAuth } from '../contexts/AuthContext';
|
||||||
import type {
|
import type {
|
||||||
AtemschutzUebersicht,
|
AtemschutzUebersicht,
|
||||||
AtemschutzStats,
|
AtemschutzStats,
|
||||||
@@ -150,6 +151,8 @@ const StatCard: React.FC<StatCardProps> = ({ label, value, color, bgcolor }) =>
|
|||||||
|
|
||||||
function Atemschutz() {
|
function Atemschutz() {
|
||||||
const notification = useNotification();
|
const notification = useNotification();
|
||||||
|
const { user } = useAuth();
|
||||||
|
const canWrite = user?.groups?.some(g => ['dashboard_admin', 'dashboard_atemschutz'].includes(g)) ?? false;
|
||||||
|
|
||||||
// Data state
|
// Data state
|
||||||
const [traeger, setTraeger] = useState<AtemschutzUebersicht[]>([]);
|
const [traeger, setTraeger] = useState<AtemschutzUebersicht[]>([]);
|
||||||
@@ -543,6 +546,7 @@ function Atemschutz() {
|
|||||||
/>
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="right">
|
<TableCell align="right">
|
||||||
|
{canWrite && (
|
||||||
<Tooltip title="Bearbeiten">
|
<Tooltip title="Bearbeiten">
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
@@ -552,6 +556,8 @@ function Atemschutz() {
|
|||||||
<Edit fontSize="small" />
|
<Edit fontSize="small" />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
{canWrite && (
|
||||||
<Tooltip title="Löschen">
|
<Tooltip title="Löschen">
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
@@ -562,6 +568,7 @@ function Atemschutz() {
|
|||||||
<Delete fontSize="small" />
|
<Delete fontSize="small" />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
);
|
);
|
||||||
@@ -572,6 +579,7 @@ function Atemschutz() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* FAB to create */}
|
{/* FAB to create */}
|
||||||
|
{canWrite && (
|
||||||
<Fab
|
<Fab
|
||||||
color="primary"
|
color="primary"
|
||||||
aria-label="Atemschutzträger hinzufügen"
|
aria-label="Atemschutzträger hinzufügen"
|
||||||
@@ -580,6 +588,7 @@ function Atemschutz() {
|
|||||||
>
|
>
|
||||||
<Add />
|
<Add />
|
||||||
</Fab>
|
</Fab>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* ── Add / Edit Dialog ───────────────────────────────────────────── */}
|
{/* ── Add / Edit Dialog ───────────────────────────────────────────── */}
|
||||||
<Dialog
|
<Dialog
|
||||||
|
|||||||
Reference in New Issue
Block a user