diff --git a/app/shared/overnight-calendar/OvernightCalendar.js b/app/shared/overnight-calendar/OvernightCalendar.js index 97ce79774..5a20466a9 100644 --- a/app/shared/overnight-calendar/OvernightCalendar.js +++ b/app/shared/overnight-calendar/OvernightCalendar.js @@ -9,6 +9,7 @@ import { bindActionCreators } from 'redux'; import { injectT } from 'i18n'; import { areDatesSameAsInitialDates, + closedDaysModifier, filterSelectedReservation, getNotSelectableNotificationText, getNotificationText, @@ -177,7 +178,6 @@ function OvernightCalendar({ startDate, endDate, overnightStartTime, overnightEndTime); const isDurBelowMin = hasAdminBypass ? false : isDurationBelowMin(selectedDuration, minPeriod); - // TODO: accessibility, refactoring, tests return (
closedDaysModifier(day, openingHours), booked: (day) => ( startDate ? null : reservationsModifier(day, filteredReservations)), - nextBooked: (day) => nextDayBookedModifier(day, filteredReservations), + nextBooked: (day) => ( + startDate ? null : nextDayBookedModifier(day, filteredReservations)), nextBookedStartSelected: (day) => ( startDate ? nextDayBookedModifier(day, filteredReservations) : null), nextClosed: (day) => nextDayClosedModifier(day, openingHours), - prevBooked: (day) => prevDayBookedModifier(day, filteredReservations), + prevBooked: (day) => ( + startDate ? null : prevDayBookedModifier(day, filteredReservations)), prevClosed: (day) => prevDayClosedModifier(day, openingHours), }} onDayClick={validateAndSelect} diff --git a/app/shared/overnight-calendar/_overnight-calendar.scss b/app/shared/overnight-calendar/_overnight-calendar.scss index 268b81952..2a9f8459b 100644 --- a/app/shared/overnight-calendar/_overnight-calendar.scss +++ b/app/shared/overnight-calendar/_overnight-calendar.scss @@ -86,6 +86,14 @@ color: $dark-gray; } + &--closed { + cursor: pointer; + text-decoration: line-through; + background: initial !important; + background-color: $medium-gray !important; + color: $dark-gray !important; + } + &--available:not(.DayPicker-Day--disabled) { background-color: $available-color-green; @@ -148,7 +156,7 @@ &--end:not(.DayPicker-Day--disabled) { background: linear-gradient($half-day-angle, $highlighted-color 49%, $available-color 50%); - &.DayPicker-Day--nextBooked { + &.DayPicker-Day--nextBookedStartSelected { background: linear-gradient($half-day-angle, $highlighted-color 49%, $medium-gray 50%); } @@ -180,8 +188,9 @@ @include add-focus(2px, $black) {} } - .DayPicker-Day--nextClosed.DayPicker-Day--prevBooked:not(.DayPicker-Day--disabled) { + .DayPicker-Day--nextClosed.DayPicker-Day--prevBooked { background: linear-gradient($half-day-angle, $booked-color 49%, $medium-gray 50%); + color: $black; } .DayPicker-Day--nextBooked.DayPicker-Day--prevClosed:not(.DayPicker-Day--disabled) { @@ -192,11 +201,31 @@ background: linear-gradient($half-day-angle, $booked-color 49%, $medium-gray 50%); } - .DayPicker-Day--booked.DayPicker-Day--prevClosed:not(.DayPicker-Day--disabled) { + .DayPicker-Day--nextBooked.DayPicker-Day--disabled:not(.DayPicker-Day--booked) { background: linear-gradient($half-day-angle, $medium-gray 49%, $booked-color 50%); + color: $black; + } + + .DayPicker-Day--prevBooked.DayPicker-Day--disabled:not(.DayPicker-Day--booked) { + background: linear-gradient($half-day-angle, $booked-color 49%, $medium-gray 50%); + color: $black; + } + + .DayPicker-Day--booked.DayPicker-Day--prevClosed { + background: linear-gradient($half-day-angle, $medium-gray 49%, $booked-color 50%); + } + + .DayPicker-Day--nextBooked.DayPicker-Day--prevBooked:not(.DayPicker-Day--closed) { + background: initial; + background-color: $booked-color; + text-decoration: line-through; + + &:hover { + background-color: $booked-color !important; + } } - .DayPicker-Day--nextBooked.DayPicker-Day--prevBooked:not(.DayPicker-Day--disabled) { + .DayPicker-Day--nextBooked.DayPicker-Day--prevBooked.DayPicker-Day--disabled:not(.DayPicker-Day--closed) { background: initial; background-color: $booked-color; text-decoration: line-through; diff --git a/app/shared/overnight-calendar/overnightUtils.js b/app/shared/overnight-calendar/overnightUtils.js index 7242c7ded..6a2f35365 100644 --- a/app/shared/overnight-calendar/overnightUtils.js +++ b/app/shared/overnight-calendar/overnightUtils.js @@ -180,6 +180,24 @@ export function prevDayBookedModifier(day, reservations) { return false; } +/** + * Returns closed days modifier for DayPicker + * @param {Date} day + * @param {Object[]} openingHours + * @returns {boolean} is day closed + */ +export function closedDaysModifier(day, openingHours) { + const closedDays = getClosedDays(openingHours); + const momentDay = moment(day); + for (let index = 0; index < closedDays.length; index += 1) { + const closedDay = closedDays[index]; + if (momentDay.isSame(closedDay.date, 'day')) { + return true; + } + } + return false; +} + /** * Modifier for DayPicker that checks if the next day is closed. * @param {Date} day diff --git a/app/shared/overnight-calendar/tests/overnightUtils.spec.js b/app/shared/overnight-calendar/tests/overnightUtils.spec.js index 6acae358e..ce1bbfe9b 100644 --- a/app/shared/overnight-calendar/tests/overnightUtils.spec.js +++ b/app/shared/overnight-calendar/tests/overnightUtils.spec.js @@ -2,6 +2,7 @@ import moment from 'moment'; import { areDatesSameAsInitialDates, + closedDaysModifier, filterSelectedReservation, findFirstClosedDay, findFirstClosestReservation, @@ -326,6 +327,36 @@ describe('app/shared/overnight-calendar/overnightUtils', () => { }); }); + describe('closedDaysModifier', () => { + const openingHours = [ + { date: '2024-04-19', closes: null, opens: null }, + { date: '2024-04-20', closes: '2024-04-20T20:00:00+03:00', opens: '2024-04-20T06:00:00+03:00' }, + { date: '2024-04-21', closes: null, opens: null }, + { date: '2024-04-22', closes: '2024-04-22T20:00:00+03:00', opens: '2024-04-22T06:00:00+03:00' }, + { date: '2024-04-23', closes: '2024-04-23T20:00:00+03:00', opens: '2024-04-23T06:00:00+03:00' }, + { date: '2024-04-24', closes: null, opens: null }, + ]; + test('returns true when day is closed', () => { + expect(closedDaysModifier( + moment('2024-04-19').toDate(), openingHours)).toBe(true); + expect(closedDaysModifier( + moment('2024-04-21').toDate(), openingHours)).toBe(true); + expect(closedDaysModifier( + moment('2024-04-24').toDate(), openingHours)).toBe(true); + }); + + test('returns false when day is not closed', () => { + expect(closedDaysModifier( + moment('2024-04-20').toDate(), openingHours)).toBe(false); + expect(closedDaysModifier( + moment('2024-04-22').toDate(), openingHours)).toBe(false); + expect(closedDaysModifier( + moment('2024-04-23').toDate(), openingHours)).toBe(false); + expect(closedDaysModifier( + moment('2024-04-25').toDate(), openingHours)).toBe(false); + }); + }); + describe('nextDayClosedModifier', () => { const openingHours = [ { date: '2024-04-19', closes: null, opens: null },