@@ -37,7 +37,7 @@ function CalendarSingleBooking({
37
37
const apiUrl = localStorage . getItem ( "apiUrl" ) ;
38
38
39
39
const [ bookableIntervals , setBookableIntervals ] = useState ( [ ] ) ;
40
- const [ fetchingIntervals , setFetchingIntervals ] = useState ( true ) ;
40
+ const [ fetchingIntervals , setFetchingIntervals ] = useState ( false ) ;
41
41
const [ currentTime , setCurrentTime ] = useState ( dayjs ( ) ) ;
42
42
const [ bookingResult , setBookingResult ] = useState ( null ) ;
43
43
const [ processingBooking , setProcessingBooking ] = useState ( false ) ;
@@ -51,6 +51,11 @@ function CalendarSingleBooking({
51
51
return ;
52
52
}
53
53
54
+ if ( fetchingIntervals ) {
55
+ console . info ( "Already fetching intervals..." ) ;
56
+ return ;
57
+ }
58
+
54
59
setFetchingIntervals ( true ) ;
55
60
56
61
const resources = slide ?. feed ?. configuration ?. resources ?? [ ] ;
@@ -89,26 +94,19 @@ function CalendarSingleBooking({
89
94
. locale ( localeDa )
90
95
. format ( "HH:mm" ) ;
91
96
92
- const renderSingleCalendarEvent = ( calendarEventsToRender ) => {
97
+ const renderFutureEvents = ( eventsToRender ) => {
93
98
const now = dayjs ( ) ;
94
99
const elements = [ ] ;
95
100
96
- if ( calendarEventsToRender . length > 0 ) {
97
- calendarEventsToRender
101
+ if ( eventsToRender . length > 0 ) {
102
+ eventsToRender
98
103
. filter (
99
104
( e ) => e . endTime > now . unix ( ) && e . endTime <= now . endOf ( "day" ) . unix ( )
100
105
)
101
106
. forEach ( ( event ) => {
102
107
if ( elements . length < 3 ) {
103
108
elements . push (
104
- < ContentItem
105
- key = { event . id }
106
- className = {
107
- elements . length === 0
108
- ? "content-item single--now"
109
- : "content-item single--next"
110
- }
111
- >
109
+ < ContentItem key = { event . id } className = "content-item" >
112
110
< Meta >
113
111
{ renderTimeOfDayFromUnixTimestamp ( event . startTime ) }
114
112
{ " - " }
@@ -174,11 +172,17 @@ function CalendarSingleBooking({
174
172
} ) ;
175
173
} ;
176
174
177
- const roomInUse = calendarEvents . some (
175
+ const currentEvents = calendarEvents . filter (
178
176
( cal ) =>
179
177
cal . startTime <= currentTime . unix ( ) && cal . endTime >= currentTime . unix ( )
180
178
) ;
181
179
180
+ const futureEvents = calendarEvents . filter (
181
+ ( el ) => ! currentEvents . includes ( el )
182
+ ) ;
183
+
184
+ const roomInUse = currentEvents . length > 0 ;
185
+
182
186
const roomAvailableForInstantBooking =
183
187
! roomInUse && fetchingIntervals ? null : bookableIntervals ?. length > 0 ;
184
188
@@ -212,7 +216,13 @@ function CalendarSingleBooking({
212
216
< IconCheck style = { { color : "var(--color-green-600)" } } />
213
217
) }
214
218
</ StatusIcon >
215
- < StatusText > { roomInUse ? "Optaget" : "Ledigt" } </ StatusText >
219
+ < StatusText >
220
+ { roomInUse ? (
221
+ < FormattedMessage id = "room_in_use" defaultMessage = "Optaget" />
222
+ ) : (
223
+ < FormattedMessage id = "room_available" defaultMessage = "Ledigt" />
224
+ ) }
225
+ </ StatusText >
216
226
</ Status >
217
227
< DateTime
218
228
style = { {
@@ -224,27 +234,42 @@ function CalendarSingleBooking({
224
234
</ DateTime >
225
235
</ Header >
226
236
< Content className = "content" >
227
- { roomInUse && renderSingleCalendarEvent ( calendarEvents ) }
237
+ { roomInUse &&
238
+ currentEvents . map ( ( event ) => (
239
+ < ContentItem key = { event . id } className = "content-item" >
240
+ < Meta >
241
+ { renderTimeOfDayFromUnixTimestamp ( event . startTime ) }
242
+ { " - " }
243
+ { renderTimeOfDayFromUnixTimestamp ( event . endTime ) }
244
+ </ Meta >
245
+ < h1 > { getTitle ( event . title ) } </ h1 >
246
+ </ ContentItem >
247
+ ) ) }
228
248
{ ! roomInUse && (
229
249
< >
230
250
< ContentItem className = "content-item" >
231
251
{ ! processingBooking && ! bookingResult && (
232
252
< >
233
253
{ fetchingIntervals && (
234
- < p > Undersøger om lokalet kan straksbookes... </ p >
254
+ < p >
255
+ < FormattedMessage
256
+ id = "instant_booking_checking"
257
+ defaultMessage = "Undersøger om lokalet kan straksbookes..."
258
+ />
259
+ </ p >
235
260
) }
236
261
{ ! fetchingIntervals && roomAvailableForInstantBooking && (
237
262
< >
238
263
< h1 >
239
264
< FormattedMessage
240
- id = "instant_booked_not_available "
241
- defaultMessage = "instant_booked_available "
265
+ id = "instant_booking_available "
266
+ defaultMessage = "Lokalet er ledigt "
242
267
/>
243
268
</ h1 >
244
269
< p >
245
270
< FormattedMessage
246
271
id = "instant_booked_available_text"
247
- defaultMessage = "instant_booked_available_text "
272
+ defaultMessage = "Straksbook lokalet. Vælg varighed. "
248
273
/>
249
274
</ p >
250
275
< ButtonWrapper >
@@ -264,36 +289,43 @@ function CalendarSingleBooking({
264
289
< p >
265
290
< FormattedMessage
266
291
id = "instant_booked_not_available"
267
- defaultMessage = "instant_booked_not_available "
292
+ defaultMessage = "Straksbookes ikke tilgængeligt "
268
293
/>
269
294
</ p >
270
295
) }
271
296
</ >
272
297
) }
273
- { processingBooking && ! bookingResult && < p > Booker lokale...</ p > }
298
+ { processingBooking && ! bookingResult && (
299
+ < p >
300
+ < FormattedMessage
301
+ id = "instant_booking_processing"
302
+ defaultMessage = "Booker lokale..."
303
+ />
304
+ </ p >
305
+ ) }
274
306
{ bookingResult ?. status === 201 && (
275
307
< p >
276
308
< FormattedMessage
277
309
id = "instant_booked_until"
278
- defaultMessage = "instant_booked_until "
310
+ defaultMessage = "Lokalet er straksbooket indtil "
279
311
/> { " " }
280
312
{ dayjs ( bookingResult . interval . to )
281
313
. locale ( localeDa )
282
314
. format ( "HH:mm" ) }
283
315
</ p >
284
316
) }
285
317
</ ContentItem >
286
- { calendarEvents ?. length > 0 && (
287
- < >
288
- < h3 >
289
- < FormattedMessage
290
- id = "coming_events"
291
- defaultMessage = "comming_events"
292
- />
293
- </ h3 >
294
- { renderSingleCalendarEvent ( calendarEvents ) }
295
- </ >
296
- ) }
318
+ </ >
319
+ ) }
320
+ { futureEvents . length > 0 && (
321
+ < >
322
+ < h3 >
323
+ < FormattedMessage
324
+ id = "coming_events"
325
+ defaultMessage = "Kommende begivenheder"
326
+ />
327
+ </ h3 >
328
+ { renderFutureEvents ( futureEvents ) }
297
329
</ >
298
330
) }
299
331
</ Content >
@@ -308,13 +340,14 @@ const Wrapper = styled.div`
308
340
background-repeat: no-repeat;
309
341
background-size: cover;
310
342
/*
311
- --bg-color is local to this template file and is populated from configuration.
312
- --background-color serves as fallback to the global variable, that will serve a light og dark background color depending on the user preferences.
313
- */
343
+ --bg-color is local to this template file and is populated from configuration.
344
+ --background-color serves as fallback to the global variable, that will serve a light og dark background color depending on the user preferences.
345
+ */
314
346
background-color: var(--bg-color, var(--background-color));
315
347
background-image: var(--bg-image, none);
316
348
317
349
color: var(--text-color);
350
+ overflow: hidden;
318
351
` ;
319
352
320
353
const Header = styled . div `
0 commit comments