Skip to content

Commit

Permalink
Changed overnight calendar select logic and rules
Browse files Browse the repository at this point in the history
  • Loading branch information
SanttuA committed May 16, 2024
1 parent 332d3b8 commit 3fdb046
Show file tree
Hide file tree
Showing 12 changed files with 291 additions and 114 deletions.
2 changes: 2 additions & 0 deletions app/i18n/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@
"NotFoundPage.searchPageLink": "search page",
"NotFoundPage.title": "404 Page not found",
"Notifications.cannotReserveDuringMaintenance": "Cannot make reservations during maintenance.",
"Notifications.continousFreeDaysError": "You can only select a continuous period of available days",
"Notifications.errorMessage": "Something went wrong. Please try again in a moment.",
"Notifications.loginErrorMessage": "Failed to login. Please try again in a moment.",
"Notifications.userFetchErrorMessage": "Failed to retrieve user info. Please try again in a moment.",
Expand All @@ -266,6 +267,7 @@
"Overnight.legend.ownSelection": "Own selection",
"Overnight.legend.reserved": "Reserved",
"Overnight.nextMonth": "Next month",
"Overnight.overMaxAlert": "The selected time is over the maximum duration",
"Overnight.prevMonth": "Previous month",
"Partners.kaupunginkirjatoImageAlt": "Helsinki City Library",
"Partners.nuorisoasiainkeskusImageAlt": "City of Helsinki – Youth Department",
Expand Down
2 changes: 2 additions & 0 deletions app/i18n/messages/fi.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@
"NotFoundPage.searchPageLink": "hakusivulta",
"NotFoundPage.title": "404 Sivua ei löydy",
"Notifications.cannotReserveDuringMaintenance": "Huoltotyön aikana ei voi tehdä varauksia.",
"Notifications.continousFreeDaysError": "Voit valita vain yhtenäisen jakson vapaita päiviä",
"Notifications.errorMessage": "Jotain meni vikaan. Yritä hetken päästä uudelleen.",
"Notifications.loginErrorMessage": "Kirjautuminen epäonnistui. Yritä hetken päästä uudelleen.",
"Notifications.userFetchErrorMessage": "Käyttäjätietojen hakeminen epäonnistui. Yritä hetken päästä uudelleen.",
Expand All @@ -266,6 +267,7 @@
"Overnight.legend.ownSelection": "Oma valinta",
"Overnight.legend.reserved": "Varattu",
"Overnight.nextMonth": "Seuraava kuukausi",
"Overnight.overMaxAlert": "Valittu aika ylittää maksimipituuden",
"Overnight.prevMonth": "Edellinen kuukausi",
"Partners.kaupunginkirjatoImageAlt": "Helsingin kaupunginkirjasto",
"Partners.nuorisoasiainkeskusImageAlt": "Helsingin kaupunki - nuorisoasiainkeskus",
Expand Down
2 changes: 2 additions & 0 deletions app/i18n/messages/sv.json
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@
"NotFoundPage.searchPageLink": "söksidan",
"NotFoundPage.title": "404 Webbplatsen hittades inte",
"Notifications.cannotReserveDuringMaintenance": "Det går inte att göra reservationer under underhåll.",
"Notifications.continousFreeDaysError": "Du kan bara välja en sammanhängande period av lediga dagar",
"Notifications.errorMessage": "Ett fel uppstod. Försök på nytt om en liten stund.",
"Notifications.loginErrorMessage": "Inloggning misslyckades. Försök igen om en liten stund.",
"Notifications.userFetchErrorMessage": "Användarinformations hämtning misslyckades. Försök igen om en liten stund.",
Expand All @@ -268,6 +269,7 @@
"Overnight.legend.ownSelection": "Egen val",
"Overnight.legend.reserved": "Reserverad",
"Overnight.nextMonth": "Nästa månad",
"Overnight.overMaxAlert": "Den valda tiden överskrider maximal varaktighet",
"Overnight.prevMonth": "Föregående månad",
"Partners.kaupunginkirjatoImageAlt": "Helsingfors stadsbibliotek",
"Partners.nuorisoasiainkeskusImageAlt": "Helsingfors stad - ungdomscentralen",
Expand Down
51 changes: 33 additions & 18 deletions app/shared/overnight-calendar/OvernightCalendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ import {
handleDisableDays,
handleFormattingSelected,
isDurationBelowMin,
isDurationOverMax,
isReservingAllowed,
isSelectionContinous,
nextDayBookedModifier,
nextDayClosedModifier,
prevDayBookedModifier,
Expand Down Expand Up @@ -78,14 +80,23 @@ function OvernightCalendar({
const selectedDuration = getSelectedDuration(
startDate, endDate, overnightStartTime, overnightEndTime);
const isDurBelowMin = isDurationBelowMin(selectedDuration, minPeriod);
const minDurationText = getPrettifiedPeriodUnits(minPeriod, t('common.unit.time.day.short'));
if (isDurBelowMin) {
const minDurationText = getPrettifiedPeriodUnits(minPeriod, t('common.unit.time.day.short'));
actions.addNotification({
message: `${t('Overnight.belowMinAlert')} (${minDurationText})`,
type: 'info',
timeOut: 10000,
});
}
const isDurOverMax = isDurationOverMax(selectedDuration, maxPeriod);
if (isDurOverMax) {
const maxDurationText = getPrettifiedPeriodUnits(maxPeriod, t('common.unit.time.day.short'));
actions.addNotification({
message: `${t('Overnight.overMaxAlert')} (${maxDurationText})`,
type: 'info',
timeOut: 10000,
});
}
}
}, [startDate, endDate]);

Expand All @@ -107,20 +118,16 @@ function OvernightCalendar({
});

const validateAndSelect = (day, { booked, nextBooked, nextClosed }) => {
const isNextBlocked = !startDate && (nextBooked || nextClosed);
const isNextBlocked = (!startDate || (startDate && endDate)) && (nextBooked || nextClosed);
const isDateDisabled = handleDisableDays({
day,
now,
reservable,
reservableAfter,
reservableBefore,
startDate,
openingHours,
reservations: filteredReservations,
maxPeriod,
minPeriod,
overnightEndTime,
overnightStartTime,
hasAdminBypass: isUnitManagerOrHigher,
});

Expand All @@ -135,6 +142,16 @@ function OvernightCalendar({
return;
}

if ((startDate && !endDate)
&& !isSelectionContinous(startDate, day, filteredReservations, openingHours)) {
actions.addNotification({
message: t('Notifications.continousFreeDaysError'),
type: 'info',
timeOut: 10000,
});
return;
}

if (!isDateDisabled && !booked && !isNextBlocked) {
handleDateSelect({
value: day,
Expand Down Expand Up @@ -184,6 +201,9 @@ function OvernightCalendar({
const isDurBelowMin = isUnitAdminOrHigher ? false
: isDurationBelowMin(selectedDuration, minPeriod);

const isDurOverMax = isUnitAdminOrHigher ? false
: isDurationOverMax(selectedDuration, maxPeriod);

return (
<div className="overnight-calendar">
<OvernightHiddenHeading
Expand All @@ -198,13 +218,9 @@ function OvernightCalendar({
reservable,
reservableAfter,
reservableBefore,
startDate,
openingHours,
reservations: filteredReservations,
maxPeriod,
minPeriod,
overnightEndTime,
overnightStartTime,
hasAdminBypass: isUnitManagerOrHigher,
})}
enableOutsideDays
Expand All @@ -219,15 +235,10 @@ function OvernightCalendar({
highlighted,
available,
closed: (day) => closedDaysModifier(day, openingHours),
booked: (day) => (
startDate ? null : reservationsModifier(day, filteredReservations)),
nextBooked: (day) => (
startDate ? null : nextDayBookedModifier(day, filteredReservations)),
nextBookedStartSelected: (day) => (
startDate ? nextDayBookedModifier(day, filteredReservations) : null),
booked: (day) => reservationsModifier(day, filteredReservations),
nextBooked: (day) => nextDayBookedModifier(day, filteredReservations),
nextClosed: (day) => nextDayClosedModifier(day, openingHours),
prevBooked: (day) => (
startDate ? null : prevDayBookedModifier(day, filteredReservations)),
prevBooked: (day) => prevDayBookedModifier(day, filteredReservations),
prevClosed: (day) => prevDayClosedModifier(day, openingHours),
}}
onDayClick={validateAndSelect}
Expand All @@ -243,6 +254,8 @@ function OvernightCalendar({
endDatetime={getOvernightDatetime(endDate, overnightEndTime, t)}
handleSelectDatetimes={handleSelectDatetimes}
isDurationBelowMin={isDurBelowMin}
isDurationOverMax={isDurOverMax}
maxDuration={maxPeriod || ''}
minDuration={minPeriod}
selected={selected}
startDatetime={getOvernightDatetime(startDate, overnightStartTime, t)}
Expand All @@ -254,6 +267,8 @@ function OvernightCalendar({
duration={selectedDuration}
endDatetime={getOvernightDatetime(endDate, overnightEndTime, t)}
isDurationBelowMin={isDurBelowMin}
isDurationOverMax={isDurOverMax}
maxDuration={maxPeriod || ''}
minDuration={minPeriod}
onCancel={onEditCancel}
onConfirm={handleSelectDatetimes}
Expand Down
12 changes: 10 additions & 2 deletions app/shared/overnight-calendar/OvernightEditSummary.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ import { getPrettifiedPeriodUnits } from '../../utils/timeUtils';

function OvernightEditSummary({
startDatetime, endDatetime, selected, onCancel, onConfirm, t,
duration, minDuration, isDurationBelowMin, datesSameAsInitial
duration, minDuration, isDurationBelowMin, datesSameAsInitial,
maxDuration, isDurationOverMax
}) {
const timeRange = startDatetime && endDatetime ? `${startDatetime} - ${endDatetime}` : `${selected[0]} - ${selected[1]}`;
const durationText = getPrettifiedPeriodUnits(duration, t('common.unit.time.day.short'));
const minDurationText = getPrettifiedPeriodUnits(minDuration, t('common.unit.time.day.short'));
const maxDurationText = getPrettifiedPeriodUnits(maxDuration, t('common.unit.time.day.short'));
const hasMinDurationError = !datesSameAsInitial && isDurationBelowMin;
const hasMaxDurationError = !datesSameAsInitial && isDurationOverMax;
const validRange = startDatetime && endDatetime;

return (
Expand All @@ -32,6 +35,9 @@ function OvernightEditSummary({
{hasMinDurationError && (
<p className="overnight-error">{`${t('Overnight.belowMinAlert')} (${minDurationText})`}</p>
)}
{hasMaxDurationError && (
<p className="overnight-error">{`${t('Overnight.overMaxAlert')} (${maxDurationText})`}</p>
)}
</div>
<div className="app-ReservationTime__controls">
<Button bsStyle="warning" className="cancel_Button" onClick={onCancel}>
Expand All @@ -40,7 +46,7 @@ function OvernightEditSummary({
<Button
bsStyle="primary"
className="next_Button"
disabled={!startDatetime || !endDatetime || hasMinDurationError}
disabled={!startDatetime || !endDatetime || hasMinDurationError || hasMaxDurationError}
onClick={onConfirm}
>
{t('common.continue')}
Expand All @@ -61,6 +67,8 @@ OvernightEditSummary.propTypes = {
isDurationBelowMin: PropTypes.bool.isRequired,
minDuration: PropTypes.string.isRequired,
datesSameAsInitial: PropTypes.bool.isRequired,
maxDuration: PropTypes.string.isRequired,
isDurationOverMax: PropTypes.bool.isRequired,
};

export default injectT(OvernightEditSummary);
10 changes: 8 additions & 2 deletions app/shared/overnight-calendar/OvernightSummary.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import { getPrettifiedPeriodUnits } from '../../utils/timeUtils';

function OvernightSummary({
t, selected, endDatetime, startDatetime, handleSelectDatetimes,
duration, isDurationBelowMin, minDuration
duration, isDurationBelowMin, minDuration, isDurationOverMax, maxDuration
}) {
const timeRange = startDatetime && endDatetime ? `${startDatetime} - ${endDatetime}` : `${selected[0]} - ${selected[1]}`;
const durationText = getPrettifiedPeriodUnits(duration, t('common.unit.time.day.short'));
const minDurationText = getPrettifiedPeriodUnits(minDuration, t('common.unit.time.day.short'));
const maxDurationText = getPrettifiedPeriodUnits(maxDuration, t('common.unit.time.day.short'));
const validRange = startDatetime && endDatetime;

return (
Expand All @@ -32,11 +33,14 @@ function OvernightSummary({
{isDurationBelowMin && (
<p className="overnight-error">{`${t('Overnight.belowMinAlert')} (${minDurationText})`}</p>
)}
{isDurationOverMax && (
<p className="overnight-error">{`${t('Overnight.overMaxAlert')} (${maxDurationText})`}</p>
)}
</div>
<div>
<Button
bsStyle="primary"
disabled={isDurationBelowMin || !validRange}
disabled={isDurationBelowMin || isDurationOverMax || !validRange}
onClick={handleSelectDatetimes}
>
{t('TimeSlots.reserveButton')}
Expand All @@ -55,6 +59,8 @@ OvernightSummary.propTypes = {
duration: PropTypes.object.isRequired,
isDurationBelowMin: PropTypes.bool.isRequired,
minDuration: PropTypes.string.isRequired,
isDurationOverMax: PropTypes.bool.isRequired,
maxDuration: PropTypes.string.isRequired,
};

export default injectT(OvernightSummary);
28 changes: 16 additions & 12 deletions app/shared/overnight-calendar/_overnight-calendar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -141,47 +141,51 @@
border: 2px solid $black;
}

&--start:not(.DayPicker-Day--disabled) {
background: linear-gradient($half-day-angle, $medium-gray 49%, $highlighted-color 50%);
&--start {
background: linear-gradient($half-day-angle, $available-color 49%, $highlighted-color 50%);

&.DayPicker-Day--prevBooked {
background: linear-gradient($half-day-angle, $medium-gray 49%, $highlighted-color 50%);
background: linear-gradient($half-day-angle, $busy-color 49%, $highlighted-color 50%);
}

&.DayPicker-Day--prevClosed {
background: linear-gradient($half-day-angle, $medium-gray 49%, $highlighted-color 50%);
}
}

&--end:not(.DayPicker-Day--disabled) {
&--end {
background: linear-gradient($half-day-angle, $highlighted-color 49%, $available-color 50%);

&.DayPicker-Day--nextBookedStartSelected {
background: linear-gradient($half-day-angle, $highlighted-color 49%, $medium-gray 50%);
}

&.DayPicker-Day--nextClosed {
background: linear-gradient($half-day-angle, $highlighted-color 49%, $medium-gray 50%);
}
}

&--nextBooked:not(.DayPicker-Day--disabled) {
background: linear-gradient($half-day-angle, $available-color 49%, $booked-color 50%);
}

&--nextBookedStartSelected:not(.DayPicker-Day--disabled) {
background: linear-gradient($half-day-angle, $available-color 49%, $medium-gray 50%);
&.DayPicker-Day--selected {
background: linear-gradient($half-day-angle, $highlighted-color 49%, $booked-color 50%);
}
}

&--prevBooked:not(.DayPicker-Day--disabled) {
background: linear-gradient($half-day-angle, $booked-color 49%, $available-color 50%);

&.DayPicker-Day--selected {
background: linear-gradient($half-day-angle, $booked-color 49%, $highlighted-color 50%);
}
}

&--nextClosed:not(.DayPicker-Day--disabled) {
background: linear-gradient($half-day-angle, $available-color 49%, $medium-gray 50%);

&.DayPicker-Day--selected {
background: linear-gradient($half-day-angle, $highlighted-color 49%, $medium-gray 50%);
}
}

&--prevClosed:not(.DayPicker-Day--disabled) {
&--prevClosed:not(.DayPicker-Day--disabled):not(.DayPicker-Day--start) {
background: linear-gradient($half-day-angle, $medium-gray 49%, $available-color 50%);
}

Expand Down
Loading

0 comments on commit 3fdb046

Please sign in to comment.