From c7ec19b74e6de45676411c06fed7992618c95547 Mon Sep 17 00:00:00 2001 From: jtricerolph Date: Wed, 8 Jul 2026 13:50:52 +0000 Subject: [PATCH] Fix: vacant card after a departure no longer spans left past the checkout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bookingsForSiteOnDate uses strict `departure > viewDate`, so a booking that departed yesterday (departure_date = yesterday) doesn't appear as prevBooking when computing today's card. prevVacant was therefore true, causing the vacant card to span left into yesterday's margin — visually indistinguishable from an ongoing stay. Fix: check departingBookingForSite(yesterday) as prevDepartedBooking. Include it in prevVacant guard (prevVacant = !prevBooking && !prevDepartedBooking) and use its status for previous_status so the correct coloured bracket appears on the left without the card spanning into yesterday. Result: day after a checkout shows vacant card with coloured left bracket (blue = still-arrived, purple = departed in NewBook) but full left border; consecutive vacant days from the second night onward still span left into each other correctly. Co-Authored-By: Claude Sonnet 4.6 --- backend/src/lib/booking-flow.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/backend/src/lib/booking-flow.js b/backend/src/lib/booking-flow.js index 030ad12..f0618b1 100644 --- a/backend/src/lib/booking-flow.js +++ b/backend/src/lib/booking-flow.js @@ -79,6 +79,13 @@ export function classifyRoom(site, allBookings, viewDate, yesterday, tomorrow, o const prevBooking = bookingsForSiteOnDate(allBookings, siteId, yesterday)[0] ?? null const nextBooking = bookingsForSiteOnDate(allBookings, siteId, tomorrow)[0] ?? null + // A booking departing yesterday occupies the previous-night slot in NewBook terms + // (arrival <= yesterday < departure=yesterday is strict, so it won't appear in prevBooking). + // We need it for the bracket and to prevent the vacant card spanning backward past a checkout. + const prevDepartedBooking = !prevBooking + ? departingBookingForSite(allBookings, siteId, yesterday) + : null + // Determine flow type let flowType = 'vacant' @@ -119,12 +126,18 @@ export function classifyRoom(site, allBookings, viewDate, yesterday, tomorrow, o // Previous-day bracket: use real NewBook status so the sliver remains 'arrived' // (wide, with checkout time) until the guest actually checks out and NewBook // flips the status to 'departed'. Do not override — let real status drive colour. - const prevStatus = prevBooking ? (prevBooking.booking_status || '').toLowerCase() : null + // prevStatus: prefer the actively-occupying booking; fall back to the one that departed yesterday + const prevStatus = prevBooking + ? (prevBooking.booking_status || '').toLowerCase() + : prevDepartedBooking + ? (prevDepartedBooking.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 + // prevVacant: yesterday was truly empty — no occupant AND no departure that morning + const prevVacant = !prevBooking && !prevDepartedBooking const nextVacant = !nextBooking const isVacantFlow = !primaryBooking @@ -150,7 +163,7 @@ export function classifyRoom(site, allBookings, viewDate, yesterday, tomorrow, o : !!primaryBooking && !!arrivalDate && arrivalDate < viewDate, spans_next: isVacantFlow ? nextVacant : spansNext, - previous_booking: prevBooking, + previous_booking: prevBooking ?? prevDepartedBooking, next_booking: nextBooking, previous_status: prevStatus ?? (prevVacant ? 'vacant' : null), next_status: nextBooking ? (nextBooking.booking_status || '').toLowerCase() : 'vacant',