fix: dashboard layout, widget caching, and backend stability
Layout: - Remove Container maxWidth cap so widgets scale fluidly on wide screens - Fix ActivityFeed Card missing height:100% and overflow:hidden that caused the timeline connector pseudo-element to bleed outside the card boundary Performance (frontend): - Migrate VehicleDashboardCard, EquipmentDashboardCard, AtemschutzDashboardCard, UpcomingEventsWidget, and PersonalWarningsBanner from useEffect+useState to TanStack Query — cached for 5 min, so navigating back to the dashboard no longer re-fires all 9 API requests - Add gcTime:10min and refetchOnWindowFocus:false to QueryClient defaults to prevent spurious refetches on tab-switch Backend stability: - Raise default RATE_LIMIT_MAX from 100 to 300 req/15min — the previous limit was easily exceeded by a single active user during normal dashboard navigation - Increase DB connectionTimeoutMillis from 2s to 5s to handle burst-load scenarios where multiple requests compete for pool slots simultaneously Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React from 'react';
|
||||
import {
|
||||
Alert,
|
||||
AlertTitle,
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { Link as RouterLink } from 'react-router-dom';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { vehiclesApi } from '../../services/vehicles';
|
||||
import { equipmentApi } from '../../services/equipment';
|
||||
import type { VehicleStats, InspectionAlert } from '../../types/vehicle.types';
|
||||
@@ -22,39 +23,22 @@ interface VehicleDashboardCardProps {
|
||||
const VehicleDashboardCard: React.FC<VehicleDashboardCardProps> = ({
|
||||
hideWhenEmpty = false,
|
||||
}) => {
|
||||
const [stats, setStats] = useState<VehicleStats | null>(null);
|
||||
const [alerts, setAlerts] = useState<InspectionAlert[]>([]);
|
||||
const [equipmentWarnings, setEquipmentWarnings] = useState<VehicleEquipmentWarning[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const { data: stats, isLoading: statsLoading, isError: statsError } = useQuery<VehicleStats>({
|
||||
queryKey: ['vehicle-stats'],
|
||||
queryFn: () => vehiclesApi.getStats(),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
let mounted = true;
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
const [statsData, alertsData, warningsData] = await Promise.all([
|
||||
vehiclesApi.getStats(),
|
||||
vehiclesApi.getAlerts(30),
|
||||
equipmentApi.getVehicleWarnings(),
|
||||
]);
|
||||
if (mounted) {
|
||||
setStats(statsData);
|
||||
setAlerts(alertsData);
|
||||
setEquipmentWarnings(warningsData);
|
||||
}
|
||||
} catch {
|
||||
if (mounted) setError('Fahrzeugstatus konnte nicht geladen werden.');
|
||||
} finally {
|
||||
if (mounted) setLoading(false);
|
||||
}
|
||||
};
|
||||
fetchData();
|
||||
return () => {
|
||||
mounted = false;
|
||||
};
|
||||
}, []);
|
||||
const { data: alerts = [], isLoading: alertsLoading } = useQuery<InspectionAlert[]>({
|
||||
queryKey: ['vehicle-alerts'],
|
||||
queryFn: () => vehiclesApi.getAlerts(30),
|
||||
});
|
||||
|
||||
const { data: equipmentWarnings = [], isLoading: warningsLoading } = useQuery<VehicleEquipmentWarning[]>({
|
||||
queryKey: ['vehicle-equipment-warnings'],
|
||||
queryFn: () => equipmentApi.getVehicleWarnings(),
|
||||
});
|
||||
|
||||
const loading = statsLoading || alertsLoading || warningsLoading;
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
@@ -69,12 +53,12 @@ const VehicleDashboardCard: React.FC<VehicleDashboardCardProps> = ({
|
||||
);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
if (statsError) {
|
||||
return (
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Typography variant="body2" color="error">
|
||||
{error}
|
||||
Fahrzeugstatus konnte nicht geladen werden.
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -94,7 +78,6 @@ const VehicleDashboardCard: React.FC<VehicleDashboardCardProps> = ({
|
||||
|
||||
const allGood = stats.einsatzbereit === stats.total && !hasConcerns;
|
||||
|
||||
// If hideWhenEmpty and everything is fine, render nothing
|
||||
if (hideWhenEmpty && allGood) return null;
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user