import React from 'react' import classnames from 'classnames' import { isPast, isSameDay, isAfter, isWithinInterval, endOfDay, } from 'date-fns' import Calendar from 'react-calendar' import useBookedDays from '../helpers/useDaysBooked' import { dateFormatBackend } from '../helpers/date' import { getNextBigger, getNextSmaller } from '../helpers/array' import Loading from './loading' export default function MyCalendar({ start, end, onChange = null, className, }: { start?: string end?: string onChange?: (arg0: any) => void className?: string }) { const { daysBooked, daysBookedError, daysBookedLoading } = useBookedDays() const startDate = (start && new Date(start)) || null const endDate = (end && new Date(end)) || null const inSelection = !!start && !end const prevBooked = inSelection && getNextSmaller(daysBooked, start) const nextBooked = inSelection && getNextBigger(daysBooked, start) function isDateSelected(date: Date) { if (!startDate) { return false } if (isSameDay(date, startDate)) { return true } // if end is before start, it is not within if (endDate && !isAfter(endDate, startDate)) { return false } return isWithinInterval(date, { start: startDate, end: endDate || startDate, }) } function tileClassName({ date, view }) { const isMonthView = view === 'month' const isDaysBookedLoaded = !!daysBooked const isInPast = isPast(endOfDay(date)) const isBooked = daysBooked?.includes(dateFormatBackend(date)) const isSelected = isDateSelected(date) return classnames({ 'react-calendar__tile--past': isMonthView && isInPast, 'react-calendar__tile--booked': isMonthView && isDaysBookedLoaded && isBooked && !isInPast, 'react-calendar__tile--free': isMonthView && isDaysBookedLoaded && !isBooked && !isInPast && !isSelected, 'react-calendar__tile--selected-start': isMonthView && isSameDay(date, startDate), 'react-calendar__tile--selected-end': isMonthView && isSameDay(date, endDate), 'react-calendar__tile--selected': isSelected, 'react-calendar__tile--unselectable': inSelection && ((prevBooked && date < new Date(prevBooked)) || (nextBooked && date > new Date(nextBooked))), 'react-calendar__tile--not-interactive': !onChange, }) } if (daysBookedError) { return (
Entschuldigen Sie, aber die Buchungszeiten konnten nicht geladen werden. Versuchen Sie es später nochmals.
) } return (

Belegungsplan

) => { if (!onChange) { return } event.preventDefault() event.stopPropagation() const targetClassList = event.currentTarget.classList if ( targetClassList.contains('react-calendar__tile--past') || targetClassList.contains('react-calendar__tile--booked') || targetClassList.contains('react-calendar__tile--unselectable') ) { return } // when startDate missing or both are already set if (!startDate || (!!startDate && !!endDate)) { onChange({ startDate: dateFormatBackend(date), endDate: null }) return } // when startDate set, but end missing if (isAfter(date, startDate)) { onChange({ endDate: dateFormatBackend(date) }) } else { onChange({ startDate: dateFormatBackend(date), endDate: start }) } }} tileClassName={tileClassName} value={null} />
Frei
Belegt
) }