'use client';
import {
Dialog,
Button,
TextField,
Typography,
Box,
Divider,
Chip,
Paper,
IconButton,
Stack,
useMediaQuery,
CircularProgress,
} from '@mui/material';
import { useTheme } from '@mui/material/styles';
import { useState, useEffect, Suspense, lazy, useMemo } from 'react';
import { Tool, User } from '../types';
import { useReservationStore } from '../services/reservation-store';
import { useI18n } from '../services/i18n';
import { Calendar, Info, ShieldCheck, X, Check, MapPin, Clock } from 'lucide-react';
const AvailabilityCalendar = lazy(() => import('./AvailabilityCalendar'));
interface ReservationModalProps {
tool: Tool | null;
user: User;
open: boolean;
onClose: () => void;
}
const pillSx = {
height: 22,
fontWeight: 600,
fontSize: '0.7rem',
borderRadius: 1.25,
'& .MuiChip-icon': { marginLeft: '6px', marginRight: '-2px' },
'& .MuiChip-label': { px: 0.75 },
} as const;
export default function ReservationModal({
tool,
user,
open,
onClose,
}: ReservationModalProps) {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
const { t } = useI18n();
const reservations = useReservationStore((s) => s.reservations);
const addReservation = useReservationStore((s) => s.addReservation);
const today = useMemo(() => new Date().toISOString().split('T')[0], []);
const [startDate, setStartDate] = useState(today);
const [endDate, setEndDate] = useState('');
const [submitted, setSubmitted] = useState(false);
useEffect(() => {
if (open) {
setStartDate(today);
setEndDate('');
setSubmitted(false);
}
}, [open, today]);
if (!tool) return null;
const toolEvents = reservations
.filter((r) => r.toolId === tool.id && r.status !== 'completed')
.map((r) => ({
title: 'Belegt',
start: r.startDate,
end: r.endDate,
display: 'background' as const,
color: '#F59E0B',
}));
const duration = (() => {
if (!startDate || !endDate) return 0;
const ms = new Date(endDate).getTime() - new Date(startDate).getTime();
return Math.max(0, Math.round(ms / 86_400_000) + 1);
})();
const exceedsMax = duration > tool.maxRentalDays;
const invalidRange = Boolean(endDate) && endDate < startDate;
const hasTraining =
!tool.trainingRequired || user.trainings.includes(tool.requiredTrainingId!);
const canReserve =
!!startDate &&
!!endDate &&
!exceedsMax &&
!invalidRange &&
(hasTraining || user.role === 'admin');
const handleSubmit = () => {
if (!canReserve) return;
addReservation({ userId: user.id, toolId: tool.id, startDate, endDate });
setSubmitted(true);
setTimeout(onClose, 1100);
};
return (
);
}
function LegendDot({
color,
label,
outline,
}: {
color?: string;
label: string;
outline?: boolean;
}) {
return (
{label}
);
}