From 7fb9e245d976017c300dc54d816a95aeee1579db Mon Sep 17 00:00:00 2001 From: jtricerolph Date: Sat, 4 Jul 2026 18:43:59 +0000 Subject: [PATCH] Vacancy participates in the Gantt bracket system - A vacant room spans into adjacent vacant days (left/right border removed, card extends into the margin) exactly like multi-night bookings - An occupied room adjacent to a vacant day shows a grey 'vacant' sliver bracket on that side (previously no bracket rendered at all when the neighbouring day was empty) - previous_status falls back to 'vacant' when nothing occupied yesterday; next_status falls back to 'vacant' when nothing occupies tomorrow Co-Authored-By: Claude Sonnet 4.6 --- backend/src/lib/booking-flow.js | 17 +++++++++++++---- frontend/src/index.css | 2 ++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/backend/src/lib/booking-flow.js b/backend/src/lib/booking-flow.js index 1f16a8e..afec45e 100644 --- a/backend/src/lib/booking-flow.js +++ b/backend/src/lib/booking-flow.js @@ -118,6 +118,13 @@ export function classifyRoom(site, allBookings, viewDate, yesterday, tomorrow) { // flips the status to 'departed'. Do not override — let real status drive colour. const prevStatus = prevBooking ? (prevBooking.booking_status || '').toLowerCase() : null + // Vacancy participates in the bracket system like bookings: a vacant room + // spans into adjacent vacant days (no side border), while a day adjacent to + // vacancy on an occupied room shows a grey 'vacant' bracket on that side. + const prevVacant = !prevBooking + const nextVacant = !nextBooking + const isVacantFlow = !primaryBooking + // NewBook may return category info as flat fields or a nested object. const catId = site.site_category_id ?? site.category_id ?? site.category?.id ?? null const catName = site.site_category_name ?? site.category_name ?? site.category?.name ?? '' @@ -135,13 +142,15 @@ export function classifyRoom(site, allBookings, viewDate, yesterday, tomorrow) { flow_type: flowType, booking: primaryBooking, - spans_previous: !!primaryBooking && !!arrivalDate && arrivalDate < viewDate, - spans_next: spansNext, + spans_previous: isVacantFlow + ? prevVacant + : !!primaryBooking && !!arrivalDate && arrivalDate < viewDate, + spans_next: isVacantFlow ? nextVacant : spansNext, previous_booking: prevBooking, next_booking: nextBooking, - previous_status: prevStatus, - next_status: nextBooking ? (nextBooking.booking_status || '').toLowerCase() : null, + previous_status: prevStatus ?? (prevVacant ? 'vacant' : null), + next_status: nextBooking ? (nextBooking.booking_status || '').toLowerCase() : 'vacant', departing_booking: effectiveDeparting, departing_time: effectiveDeparting ? toTimeStr(effectiveDeparting.booking_departure) : null, diff --git a/frontend/src/index.css b/frontend/src/index.css index 6cecc58..23d3682 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -440,6 +440,7 @@ html, body, #root { .room-card[data-previous-status="confirmed"]::before { border-color: #10b981; } .room-card[data-previous-status="unconfirmed"]::before { border-color: #f59e0b; } .room-card[data-previous-status="departed"]::before { border-color: #a855f7; } +.room-card[data-previous-status="vacant"]::before { border-color: #d1d5db; } /* Right bracket: next adjacent booking status. */ .room-card[data-next-status]::after { @@ -459,6 +460,7 @@ html, body, #root { .room-card[data-next-status="confirmed"]::after { border-color: #10b981; } .room-card[data-next-status="unconfirmed"]::after { border-color: #f59e0b; } .room-card[data-next-status="departed"]::after { border-color: #a855f7; } +.room-card[data-next-status="vacant"]::after { border-color: #d1d5db; } /* Departure time shown in left-bracket sliver (while prev booking still 'arrived'). The bracket widens to 19px when a time is shown; the time reads vertically. */