@@ -5,47 +5,63 @@ import type {
55 Query ,
66 QueryReservationUnitByPkArgs ,
77 QueryUnitsArgs ,
8+ ReservationType ,
89 ReservationUnitByPkTypeReservationsArgs ,
910 ReservationUnitType ,
1011} from "common/types/gql-types" ;
1112import { ReservationUnitsReservationUnitReservationStartIntervalChoices } from "common/types/gql-types" ;
1213import type { UseFormReturn } from "react-hook-form" ;
1314import type { RecurringReservationForm } from "app/schemas" ;
14- import { addDays } from "date-fns" ;
15+ import { addDays , addSeconds } from "date-fns" ;
1516import { generateReservations } from "./generateReservations" ;
1617import { useNotification } from "../../../context/NotificationContext" ;
1718import { RECURRING_RESERVATION_UNIT_QUERY } from "../queries" ;
1819import { GET_RESERVATIONS_IN_INTERVAL } from "./queries" ;
1920import { NewReservationListItem } from "../../ReservationsList" ;
20- import { DateRange , convertToDate , isOverlapping } from "./utils" ;
21+ import { convertToDate , isOverlapping } from "./utils" ;
2122
22- export const useMultipleReservation = (
23- form : UseFormReturn < RecurringReservationForm > ,
24- interval : ReservationUnitsReservationUnitReservationStartIntervalChoices = ReservationUnitsReservationUnitReservationStartIntervalChoices . Interval_15Mins
25- ) => {
23+ export const useMultipleReservation = ( {
24+ form,
25+ reservationUnit,
26+ interval = ReservationUnitsReservationUnitReservationStartIntervalChoices . Interval_15Mins ,
27+ } : {
28+ form : UseFormReturn < RecurringReservationForm > ;
29+ reservationUnit ?: ReservationUnitType ;
30+ interval ?: ReservationUnitsReservationUnitReservationStartIntervalChoices ;
31+ } ) => {
2632 const { watch } = form ;
2733
28- const selectedReservationParams = watch ( [
29- "startingDate" ,
30- "endingDate" ,
31- "startTime" ,
32- "endTime" ,
33- "repeatPattern" ,
34- "repeatOnDays" ,
35- ] ) ;
36-
3734 // NOTE useMemo is useless here, watcher already filters out unnecessary runs
38- return generateReservations (
35+ const result = generateReservations (
3936 {
40- startingDate : selectedReservationParams [ 0 ] ,
41- endingDate : selectedReservationParams [ 1 ] ,
42- startTime : selectedReservationParams [ 2 ] ,
43- endTime : selectedReservationParams [ 3 ] ,
44- repeatPattern : selectedReservationParams [ 4 ] ,
45- repeatOnDays : selectedReservationParams [ 5 ] ,
37+ startingDate : watch ( "startingDate" ) ,
38+ endingDate : watch ( "endingDate" ) ,
39+ startTime : watch ( "startTime" ) ,
40+ endTime : watch ( "endTime" ) ,
41+ repeatPattern : watch ( "repeatPattern" ) ,
42+ repeatOnDays : watch ( "repeatOnDays" ) ,
4643 } ,
4744 interval
4845 ) ;
46+
47+ const isBlocked = watch ( "type" ) === "BLOCKED" ;
48+
49+ return {
50+ ...result ,
51+ reservations : result . reservations . map ( ( item ) => ( {
52+ ...item ,
53+ buffers : {
54+ before :
55+ watch ( "bufferTimeBefore" ) && ! isBlocked
56+ ? reservationUnit ?. bufferTimeBefore ?? 0
57+ : 0 ,
58+ after :
59+ watch ( "bufferTimeAfter" ) && ! isBlocked
60+ ? reservationUnit ?. bufferTimeAfter ?? 0
61+ : 0 ,
62+ } ,
63+ } ) ) ,
64+ } ;
4965} ;
5066
5167// NOTE pks are integers even though the query uses strings
@@ -73,6 +89,27 @@ export const useRecurringReservationsUnits = (unitId: number) => {
7389 return { loading, reservationUnits } ;
7490} ;
7591
92+ type TimeInterval = {
93+ begin : Date ;
94+ end : Date ;
95+ buffers : {
96+ before : number ;
97+ after : number ;
98+ } ;
99+ } ;
100+
101+ const reservationToInterval = ( x : ReservationType ) : TimeInterval | undefined =>
102+ x . begin && x . end
103+ ? {
104+ begin : new Date ( x . begin ) ,
105+ end : new Date ( x . end ) ,
106+ buffers : {
107+ before : x . bufferTimeBefore ?? 0 ,
108+ after : x . bufferTimeAfter ?? 0 ,
109+ } ,
110+ }
111+ : undefined ;
112+
76113export const useReservationsInInterval = ( {
77114 begin,
78115 end,
@@ -113,12 +150,8 @@ export const useReservationsInInterval = ({
113150 const reservations = useMemo (
114151 ( ) =>
115152 data ?. reservationUnitByPk ?. reservations
116- ?. map ( ( x ) =>
117- x ?. begin && x ?. end
118- ? { begin : new Date ( x . begin ) , end : new Date ( x . end ) }
119- : undefined
120- )
121- ?. filter ( ( x ) : x is { begin : Date ; end : Date } => x != null ) ?? [ ] ,
153+ ?. map ( ( x ) => ( x ? reservationToInterval ( x ) : undefined ) )
154+ ?. filter ( ( x ) : x is TimeInterval => x != null ) ?? [ ] ,
122155 [ data ]
123156 ) ;
124157
@@ -144,15 +177,20 @@ export const useFilteredReservationList = ({
144177
145178 const isReservationInsideRange = (
146179 res : NewReservationListItem ,
147- range : DateRange
180+ range : TimeInterval
148181 ) => {
149182 const startDate = convertToDate ( res . date , res . startTime ) ;
150183 const endDate = convertToDate ( res . date , res . endTime ) ;
184+ const bufferBefore = Math . max (
185+ res . buffers ?. before ?? 0 ,
186+ range . buffers . before
187+ ) ;
188+ const bufferAfter = Math . max ( res . buffers ?. after ?? 0 , range . buffers . after ) ;
151189 if ( startDate && endDate ) {
152190 return isOverlapping (
153191 {
154- begin : startDate ,
155- end : endDate ,
192+ begin : addSeconds ( startDate , - bufferBefore ) ,
193+ end : addSeconds ( endDate , bufferAfter ) ,
156194 } ,
157195 range
158196 ) ;
0 commit comments