From 58988a4fe89c5c3eaef12dc76796d31f83a8fedc Mon Sep 17 00:00:00 2001 From: Philip Peterson <1326208+philip-peterson@users.noreply.github.com> Date: Wed, 3 Jun 2026 19:52:14 -0700 Subject: [PATCH] Fix calendar auto-advance and add fault injection for availability - Remove client-side serviceEarliestDate; instead auto-advance month by month until the server returns events (capped at 12 months) - Only mark initialized when a date is actually found, so empty months don't block auto-select on subsequent fetches - Add per-service fault injection flags in ScheduleController::events to force zero availability for testing the no-slots UI path Co-Authored-By: Claude Sonnet 4.6 --- .../riverside_pt/js/components/rpt-booking.js | 13 +++++++++---- .../src/Controller/ScheduleController.php | 10 ++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/web/modules/custom/riverside_pt/js/components/rpt-booking.js b/web/modules/custom/riverside_pt/js/components/rpt-booking.js index 7c4a2b0..3b28a99 100644 --- a/web/modules/custom/riverside_pt/js/components/rpt-booking.js +++ b/web/modules/custom/riverside_pt/js/components/rpt-booking.js @@ -45,6 +45,7 @@ function Booking({ settings }) { const calRef = useRef(null); const initializedRef = useRef(false); const prevServiceRef = useRef(null); + const autoAdvanceRef = useRef(0); const initDate = useMemo(nextBusinessDay, []); function buildEventsUrl(svc) { @@ -93,12 +94,11 @@ function Booking({ settings }) { eventsSet: function (events) { markDays(events); if (!initializedRef.current) { - initializedRef.current = true; - var dates = [...new Set(events.map(function (e) { return e.startStr.substring(0, 10); }))] - .filter(function (d) { return d >= initDate; }) - .sort(); + var dates = [...new Set(events.map(function (e) { return e.startStr.substring(0, 10); }))].sort(); var firstDate = dates[0]; if (firstDate) { + initializedRef.current = true; + autoAdvanceRef.current = 0; var targetEl = calEl.current.querySelector(".fc-daygrid-day[data-date=\"" + firstDate + "\"]"); if (targetEl) { targetEl.classList.add("is-selected"); @@ -108,6 +108,9 @@ function Booking({ settings }) { .sort(function (a, b) { return a.start - b.start; }) ); } + } else if (autoAdvanceRef.current < 12) { + autoAdvanceRef.current++; + cal.next(); } } }, @@ -144,9 +147,11 @@ function Booking({ settings }) { var isInitial = prevServiceRef.current === null; prevServiceRef.current = service; + serviceRef.current = service; if (!isInitial) { initializedRef.current = false; + autoAdvanceRef.current = 0; setSlots([]); setSelectedSlotId(null); setFormData(EMPTY_FORM); diff --git a/web/modules/custom/riverside_pt/src/Controller/ScheduleController.php b/web/modules/custom/riverside_pt/src/Controller/ScheduleController.php index 57875aa..7a3c29d 100644 --- a/web/modules/custom/riverside_pt/src/Controller/ScheduleController.php +++ b/web/modules/custom/riverside_pt/src/Controller/ScheduleController.php @@ -101,6 +101,16 @@ class ScheduleController extends ControllerBase { $end = $request->query->get('end'); $service = $request->query->get('service', 'diagnostic'); + $faultZeroAvailability = [ + 'diagnostic' => false, + 'sports' => false, + 'surgical' => false, + 'neuro' => false, + ]; + if ($faultZeroAvailability[$service] ?? false) { + return new JsonResponse([]); + } + // Each service gets different slot density and start hours so calendars // look meaningfully distinct when switching types. $serviceConfig = [