From c23164619083d1c30a7a79ad48958e7e26bee228 Mon Sep 17 00:00:00 2001 From: Thomas Ruoff Date: Wed, 23 Sep 2020 23:56:52 +0200 Subject: [PATCH] disable selection of range over other bookings --- components/wizard/calendar.tsx | 16 ++++++++++++++-- styles/index.css | 23 ++++++++++++++++++----- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/components/wizard/calendar.tsx b/components/wizard/calendar.tsx index 620cf34..e216fa9 100644 --- a/components/wizard/calendar.tsx +++ b/components/wizard/calendar.tsx @@ -2,8 +2,9 @@ import React, { useContext } from 'react' import classnames from 'classnames' import { isPast, isSameDay, isAfter, isWithinInterval } from 'date-fns' import useSWR from 'swr' -import Calendar, { DateCallback } from 'react-calendar' +import Calendar from 'react-calendar' import { dateFormatBackend } from '../../helpers/date' +import { getNextBigger, getNextSmaller } from '../../helpers/array' import { WizardContext } from './context/wizardStore' const fetcher = (path: string) => fetch(path).then((r) => r.json()) @@ -18,6 +19,10 @@ export default function MyCalendar() { fetcher ) + const inSelection = !!start && !end + const prevBooked = inSelection && getNextSmaller(daysBooked, start) + const nextBooked = inSelection && getNextBigger(daysBooked, start) + function tileClassName({ date, view }) { const isMonthView = view === 'month' const isDaysBookedLoaded = !!daysBooked @@ -29,6 +34,8 @@ export default function MyCalendar() { isMonthView && isDaysBookedLoaded && isBooked && !isInPast, 'react-calendar__tile--free': isMonthView && isDaysBookedLoaded && !isBooked && !isInPast, + 'react-calendar__tile--selected-start': isSameDay(date, startDate), + 'react-calendar__tile--selected-end': isSameDay(date, endDate), 'react-calendar__tile--selected': (startDate && isWithinInterval(date, { @@ -36,6 +43,10 @@ export default function MyCalendar() { end: endDate || startDate, })) || isSameDay(date, startDate), + 'react-calendar__tile--unselectable': + inSelection && + ((prevBooked && date < new Date(prevBooked)) || + (nextBooked && date > new Date(nextBooked))), }) } @@ -62,7 +73,8 @@ export default function MyCalendar() { if ( targetClassList.contains('react-calendar__tile--past') || - targetClassList.contains('react-calendar__tile--booked') + targetClassList.contains('react-calendar__tile--booked') || + targetClassList.contains('react-calendar__tile--unselectable') ) { return } diff --git a/styles/index.css b/styles/index.css index 51e24ac..eb47b0a 100644 --- a/styles/index.css +++ b/styles/index.css @@ -161,7 +161,7 @@ @apply text-red-600; } .react-calendar__month-view__days__day--neighboringMonth { - @apply text-gray-400; + @apply text-gray-600; } .react-calendar__year-view .react-calendar__tile, .react-calendar__decade-view .react-calendar__tile, @@ -169,7 +169,7 @@ } .react-calendar__tile { - @apply py-1; + @apply py-1 border border-gray-500; } .react-calendar__tile--free { @@ -177,6 +177,10 @@ cursor: pointer; } +.react-calendar__tile--free:hover:not(.react-calendar__tile--unselectable) { + @apply bg-gray-500; +} + .react-calendar__tile--booked { @apply bg-red-200 cursor-not-allowed; } @@ -190,12 +194,21 @@ } .react-calendar__tile--selected { - @apply bg-blue-200; + @apply bg-blue-400; } -.react-calendar__tile--free:hover { - @apply bg-gray-500; +.react-calendar__tile--unselectable { + @apply cursor-not-allowed; } + +.react-calendar__tile--selected-start { + @apply rounded-tl-sm rounded-bl-sm; +} + +.react-calendar__tile--selected-end { + @apply rounded-tr-sm rounded-br-sm; +} + .react-calendar__tile--now { @apply text-green-400; }