diff --git a/apps/frontend/src/features/booking/booking-provider.tsx b/apps/frontend/src/features/booking/booking-provider.tsx index 919976e..357d57f 100644 --- a/apps/frontend/src/features/booking/booking-provider.tsx +++ b/apps/frontend/src/features/booking/booking-provider.tsx @@ -292,7 +292,7 @@ export function BookingProvider({ children, complex }: BookingProviderProps) { useEffect(() => { const interval = setInterval(() => { setNow(getNowTime()); - }, 10 * 1000); + }, 60 * 1000); return () => clearInterval(interval); }, []); diff --git a/apps/frontend/src/features/booking/components/booking-timeline.tsx b/apps/frontend/src/features/booking/components/booking-timeline.tsx index c25192a..23cd311 100644 --- a/apps/frontend/src/features/booking/components/booking-timeline.tsx +++ b/apps/frontend/src/features/booking/components/booking-timeline.tsx @@ -1,6 +1,7 @@ import { Button } from '@/components/ui/button'; import { cn } from '@/lib/utils'; import { ChevronLeft, ChevronRight, Dumbbell, Plus, UserX, Users } from 'lucide-react'; +import { useEffect, useRef } from 'react'; import { useBooking } from '../booking-provider'; import type { BookingCourtSchedule, BookingTimelineSegment } from '../booking.types'; import { timeToMinutes } from '../lib/booking-time'; @@ -20,6 +21,9 @@ export function BookingTimeline() { errorMessage, } = useBooking(); + const scrollRef = useRef(null); + const prevCurrentTimeRef = useRef(null); + const rangeStart = timeToMinutes(visibleTimeRange.start); const rangeEnd = timeToMinutes(visibleTimeRange.end); const totalMinutes = rangeEnd - rangeStart; @@ -29,6 +33,25 @@ export function BookingTimeline() { left: ((timeToMinutes(hour) - rangeStart) / totalMinutes) * 100, })); + useEffect(() => { + if (!currentTime || !scrollRef.current) return; + if (currentTime === prevCurrentTimeRef.current) return; + prevCurrentTimeRef.current = currentTime; + + const container = scrollRef.current; + const indicatorLeft = + courtInfoWidth + ((timeToMinutes(currentTime) - rangeStart) / totalMinutes) * gridWidth; + const targetScroll = indicatorLeft - container.clientWidth / 2; + const clampedScroll = Math.max( + 0, + Math.min(targetScroll, container.scrollWidth - container.clientWidth) + ); + + requestAnimationFrame(() => { + container.scrollTo({ left: clampedScroll, behavior: 'smooth' }); + }); + }, [currentTime, rangeStart, totalMinutes, gridWidth]); + return (
@@ -58,7 +81,7 @@ export function BookingTimeline() { )} {!isLoading && !isError && schedules.length > 0 && ( -
+