@@ -25,9 +25,9 @@ export function TimeRangeSlider() {
2525 const { t } = useTranslation ( ) ;
2626 const { language } = useLanguage ( ) ;
2727 const { minDate, maxDate, loading : dateRangeLoading } = useDateRange ( ) ;
28-
28+
2929 // Default to collapsed on mobile (screen width < 640px)
30- // We initialize state lazily to avoid hydration mismatch if we were doing SSR,
30+ // We initialize state lazily to avoid hydration mismatch if we were doing SSR,
3131 // but since this is a SPA, simple matching is fine, explicitly controlled by user mainly.
3232 const [ isCollapsed , setIsCollapsed ] = useState ( false ) ;
3333
@@ -41,42 +41,35 @@ export function TimeRangeSlider() {
4141 sqlDateToDayIndex ( filters . timeRange . end , effectiveMinDate ) ,
4242 ] ) ;
4343
44- // Sync effect: When real data range loads, update filters if they are currently default or invalid
44+ // Sync slider position when the data range or filter range changes
45+ // (e.g. catalog loads → AppState sets latest-day default → slider should position correctly)
4546 useEffect ( ( ) => {
4647 if ( ! dateRangeLoading && minDate && maxDate ) {
47- const DEFAULT_START = 20250119 ;
48- const DEFAULT_END = 20260127 ;
49-
50- const isDefault = filters . timeRange . start === DEFAULT_START && filters . timeRange . end === DEFAULT_END ;
51- const isOutOfBounds = filters . timeRange . start < minDate || filters . timeRange . end > maxDate ;
52- const isReversed = filters . timeRange . start > filters . timeRange . end ;
53-
54- if ( isDefault || isOutOfBounds || isReversed ) {
55- console . log ( 'Syncing time range to data:' , minDate , maxDate ) ;
56- updateTimeRange ( { start : minDate , end : maxDate } ) ;
57- setLocalRange ( [ 0 , sqlDateToDayIndex ( maxDate , minDate ) ] ) ;
58- } else {
59- // Even if we don't change the filter, we MUST re-calculate localRange
60- // because effectiveMinDate has changed from fallback to real minDate.
61- // The current localRange (day indices) was calculated against the fallback date.
62- setLocalRange ( [
63- sqlDateToDayIndex ( filters . timeRange . start , minDate ) ,
64- sqlDateToDayIndex ( filters . timeRange . end , minDate )
65- ] ) ;
66- }
48+ // Clamp filter range into the catalog range to handle the placeholder → real transition
49+ const clampedStart = Math . max ( filters . timeRange . start , minDate ) ;
50+ const clampedEnd = Math . min ( filters . timeRange . end , maxDate ) ;
51+ setLocalRange ( [
52+ sqlDateToDayIndex ( clampedStart , minDate ) ,
53+ sqlDateToDayIndex ( clampedEnd , minDate ) ,
54+ ] ) ;
6755 }
68- } , [ minDate , maxDate , dateRangeLoading , updateTimeRange ] ) ; // Removed filters.timeRange to avoid loops, explicit checks inside
56+ } , [ minDate , maxDate , dateRangeLoading , filters . timeRange . start , filters . timeRange . end ] ) ;
6957
7058 // Debounce: only update filters after user stops sliding
7159 useEffect ( ( ) => {
7260 const timer = setTimeout ( ( ) => {
7361 // Guard against NaN
74- if ( ! localRange || typeof localRange [ 0 ] !== 'number' || typeof localRange [ 1 ] !== 'number' ) return ;
62+ if ( ! localRange || typeof localRange [ 0 ] !== 'number' || typeof localRange [ 1 ] !== 'number' )
63+ return ;
7564
7665 const startSQL = dayIndexToSQLDate ( localRange [ 0 ] , effectiveMinDate ) ;
7766 const endSQL = dayIndexToSQLDate ( localRange [ 1 ] , effectiveMinDate ) ;
7867
79- if ( startSQL && endSQL && ( startSQL !== filters . timeRange . start || endSQL !== filters . timeRange . end ) ) {
68+ if (
69+ startSQL &&
70+ endSQL &&
71+ ( startSQL !== filters . timeRange . start || endSQL !== filters . timeRange . end )
72+ ) {
8073 updateTimeRange ( { start : startSQL , end : endSQL } ) ;
8174 }
8275 } , 300 ) ;
0 commit comments