import { useEffect } from 'react' import { DateRange } from 'react-day-picker' import { isAfter, isEqual, isBefore, endOfDay, isWithinInterval, areIntervalsOverlapping, } from 'date-fns' import { DisableCalendarDates, RangeContext } from '../CalendarTypes' type Props = { setCalendarHasError?: (arg: boolean) => void rangeContext?: RangeContext calendarRange?: DateRange calendarHasError?: boolean disabledDates?: DisableCalendarDates['disabledDates'] } // Case: If the selected dates do not overlap with the rangeContext during continuous selection, // set setCalendarHasError to true. This will display an error message and // prevent the submission of the selected dates. export const checkForContinuousSelection = ({ setCalendarHasError, rangeContext, calendarRange, calendarHasError, disabledDates, }: Props) => { const calendarRangeFrom = calendarRange?.from && endOfDay(calendarRange.from) const calendarRangeTo = calendarRange?.to && endOfDay(calendarRange.to) const rangeContextFrom = rangeContext?.from && endOfDay(rangeContext.from) const rangeContextTo = rangeContext?.to && endOfDay(rangeContext.to) // Checking if rangeFrom is equal to or before rangeContextTo const startIsEqualOrBeforeRangeContextEnd = calendarRangeFrom && rangeContextTo ? isBefore(calendarRangeFrom, rangeContextTo) || isEqual(calendarRangeFrom, rangeContextTo) : null // Checking if rangeTo is equal to or after rangeContextFrom const endIsEqualOrAfterRangeContextStart = calendarRangeTo && rangeContextFrom && rangeContextTo ? isAfter(calendarRangeTo, rangeContextFrom) || isEqual(calendarRangeTo, rangeContextFrom) : null // Check if selection overlapping unavailable dates const selectionOverlappingUnavailableDate = disabledDates?.find((range) => { const rangeFrom = endOfDay(range.from) const rangeTo = endOfDay(range.to) return ( rangeContextFrom && rangeContextTo && areIntervalsOverlapping( { start: rangeContextFrom, end: rangeContextTo }, { start: rangeFrom, end: rangeTo } ) && calendarRangeFrom && calendarRangeTo && areIntervalsOverlapping( { start: calendarRangeFrom, end: calendarRangeTo }, { start: rangeFrom, end: rangeTo } ) ) }) useEffect(() => { if ( (rangeContext && calendarRangeFrom && !startIsEqualOrBeforeRangeContextEnd) || (rangeContext && calendarRangeTo && !endIsEqualOrAfterRangeContextStart) || selectionOverlappingUnavailableDate ) { !!(setCalendarHasError && !calendarHasError) && setCalendarHasError(true) } }) }