update
This commit is contained in:
@@ -41,6 +41,7 @@ import {
|
||||
CheckCircle,
|
||||
Warning,
|
||||
Block,
|
||||
Build,
|
||||
} from '@mui/icons-material';
|
||||
import DashboardLayout from '../components/dashboard/DashboardLayout';
|
||||
import ChatAwareFab from '../components/shared/ChatAwareFab';
|
||||
@@ -52,6 +53,7 @@ import type {
|
||||
Fahrzeug,
|
||||
CreateBuchungInput,
|
||||
BuchungsArt,
|
||||
MaintenanceWindow,
|
||||
} from '../types/booking.types';
|
||||
import { BUCHUNGS_ART_LABELS, BUCHUNGS_ART_COLORS } from '../types/booking.types';
|
||||
import {
|
||||
@@ -116,6 +118,7 @@ function FahrzeugBuchungen() {
|
||||
// ── Data ──────────────────────────────────────────────────────────────────
|
||||
const [vehicles, setVehicles] = useState<Fahrzeug[]>([]);
|
||||
const [bookings, setBookings] = useState<FahrzeugBuchungListItem[]>([]);
|
||||
const [maintenanceWindows, setMaintenanceWindows] = useState<MaintenanceWindow[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
@@ -123,12 +126,13 @@ function FahrzeugBuchungen() {
|
||||
setLoading(true);
|
||||
try {
|
||||
const end = endOfWeek(currentWeekStart, { weekStartsOn: 1 });
|
||||
const [vehiclesData, bookingsData] = await Promise.all([
|
||||
const [vehiclesData, calendarData] = await Promise.all([
|
||||
fetchVehicles(),
|
||||
bookingApi.getCalendarRange(currentWeekStart, end),
|
||||
]);
|
||||
setVehicles(vehiclesData);
|
||||
setBookings(bookingsData);
|
||||
setBookings(calendarData.bookings);
|
||||
setMaintenanceWindows(calendarData.maintenanceWindows);
|
||||
setError(null);
|
||||
} catch (e: unknown) {
|
||||
const msg = e instanceof Error ? e.message : 'Fehler beim Laden';
|
||||
@@ -160,6 +164,22 @@ function FahrzeugBuchungen() {
|
||||
};
|
||||
|
||||
const isOutOfService = (vehicle: Fahrzeug, day: Date): boolean => {
|
||||
// Check from maintenance windows (server-side filtered)
|
||||
const mw = maintenanceWindows.find((w) => w.id === vehicle.id);
|
||||
if (mw) {
|
||||
try {
|
||||
if (
|
||||
isWithinInterval(day, {
|
||||
start: parseISO(mw.ausser_dienst_von),
|
||||
end: parseISO(mw.ausser_dienst_bis),
|
||||
})
|
||||
)
|
||||
return true;
|
||||
} catch {
|
||||
/* ignore parse errors */
|
||||
}
|
||||
}
|
||||
// Fallback to vehicle-level dates
|
||||
if (!vehicle.ausser_dienst_von || !vehicle.ausser_dienst_bis) return false;
|
||||
try {
|
||||
return isWithinInterval(day, {
|
||||
@@ -171,6 +191,29 @@ function FahrzeugBuchungen() {
|
||||
}
|
||||
};
|
||||
|
||||
/** Get the maintenance tooltip text for an out-of-service cell */
|
||||
const getMaintenanceTooltip = (vehicle: Fahrzeug): string => {
|
||||
const mw = maintenanceWindows.find((w) => w.id === vehicle.id);
|
||||
const statusLabel =
|
||||
(mw?.status ?? vehicle.status) === 'ausser_dienst_wartung'
|
||||
? 'Wartung'
|
||||
: 'Schaden';
|
||||
const bemerkung = mw?.status_bemerkung ?? vehicle.status_bemerkung;
|
||||
const von = mw?.ausser_dienst_von ?? vehicle.ausser_dienst_von;
|
||||
const bis = mw?.ausser_dienst_bis ?? vehicle.ausser_dienst_bis;
|
||||
|
||||
let tooltip = `Außer Dienst (${statusLabel})`;
|
||||
if (bemerkung) tooltip += `: ${bemerkung}`;
|
||||
if (von && bis) {
|
||||
try {
|
||||
tooltip += `\n${format(parseISO(von), 'dd.MM.yyyy')} – ${format(parseISO(bis), 'dd.MM.yyyy')}`;
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
return tooltip;
|
||||
};
|
||||
|
||||
// ── Create / Edit dialog ──────────────────────────────────────────────────
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [editingBooking, setEditingBooking] =
|
||||
@@ -485,9 +528,15 @@ function FahrzeugBuchungen() {
|
||||
}}
|
||||
>
|
||||
{oos && (
|
||||
<Tooltip title="Fahrzeug außer Dienst">
|
||||
<Tooltip
|
||||
title={
|
||||
<span style={{ whiteSpace: 'pre-line' }}>
|
||||
{getMaintenanceTooltip(vehicle)}
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<Chip
|
||||
icon={<Block fontSize="small" />}
|
||||
icon={<Build fontSize="small" />}
|
||||
label="Außer Dienst"
|
||||
size="small"
|
||||
color="error"
|
||||
@@ -570,9 +619,14 @@ function FahrzeugBuchungen() {
|
||||
border: '1px solid',
|
||||
borderColor: (theme) => theme.palette.mode === 'dark' ? 'error.700' : 'error.300',
|
||||
borderRadius: 0.5,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
/>
|
||||
<Typography variant="caption">Außer Dienst</Typography>
|
||||
>
|
||||
<Build sx={{ fontSize: 10, color: 'error.main' }} />
|
||||
</Box>
|
||||
<Typography variant="caption">Außer Dienst (Wartung/Schaden)</Typography>
|
||||
</Box>
|
||||
{(Object.entries(BUCHUNGS_ART_LABELS) as [BuchungsArt, string][]).map(
|
||||
([art, label]) => (
|
||||
|
||||
Reference in New Issue
Block a user