1- import { useState , useEffect , useContext } from 'react' ;
1+ import { useContext , useEffect , useState } from 'react' ;
2+ import { useRouter , useSearchParams } from 'next/navigation' ;
23import Select from 'react-dropdown-select' ;
34import { Box } from '@chakra-ui/react' ;
45import moment from 'moment' ;
56import { DateRange } from 'react-date-range' ;
6- import strftime , { timezone } from 'strftime' ;
7+ import strftime from 'strftime' ;
78import { DataContext } from '../../../contexts/data' ;
89import 'react-date-range/dist/styles.css' ;
910import 'react-date-range/dist/theme/default.css' ;
@@ -13,34 +14,63 @@ const DATA_START_DATE = new Date('2023-06-14T20:00:00.000');
1314const DATE_NOW = new Date ( ) ;
1415
1516export const DateRangeSelect = ( ) => {
16- const { setDates } = useContext ( DataContext ) ;
17-
17+ const { setDates, dates } = useContext ( DataContext ) ;
18+ const searchParams = useSearchParams ( ) ;
19+ const router = useRouter ( ) ;
1820 const [ selectedDateRangeOption , setSelectedDateRangeOption ] = useState < number | null > ( null ) ;
19- const [ rangeState , setRangeState ] = useState <
20- { startDate : Date | undefined ; endDate : Date | undefined ; key : string } [ ]
21- > ( [
22- {
23- startDate : DATA_START_DATE ,
24- endDate : DATE_NOW ,
25- key : 'selection' ,
26- } ,
27- ] ) ;
2821
29- console . log ( {
30- startDate : DATA_START_DATE ,
31- endDate : new Date ( ) ,
22+ const isValidDate = ( dateString : string ) => {
23+ return moment ( dateString , 'MM-DD-YY' , true ) . isValid ( ) ;
24+ } ;
25+
26+ const getInitialDate = ( key : string , fallback : Date ) => {
27+ const param = searchParams . get ( key ) ;
28+ if ( ! param || ! isValidDate ( param ) ) return fallback ;
29+ const date = moment ( param , 'MM-DD-YY' ) . toDate ( ) ;
30+ if ( key === 'from' && date < DATA_START_DATE ) return DATA_START_DATE ;
31+ if ( key === 'to' && date > DATE_NOW ) return DATE_NOW ;
32+ return date ;
33+ } ;
34+
35+ const initialFrom = getInitialDate ( 'from' , DATA_START_DATE ) ;
36+ const initialTo = getInitialDate ( 'to' , DATE_NOW ) ;
37+ const correctedFrom = initialFrom > initialTo ? DATA_START_DATE : initialFrom ;
38+ const correctedTo = initialFrom > initialTo ? DATE_NOW : initialTo ;
39+
40+ const [ rangeState , setRangeState ] = useState ( {
41+ startDate : correctedFrom ,
42+ endDate : correctedTo ,
3243 key : 'selection' ,
3344 } ) ;
3445
35- const [ dataRange , setDataRange ] = useState ( { fromValue : DATA_START_DATE , toValue : DATE_NOW } ) ;
46+ const updateQueryParams = ( from : Date , to : Date ) => {
47+ const params = new URLSearchParams ( searchParams . toString ( ) ) ;
48+ if ( from ) params . set ( 'from' , strftime ( '%m-%d-%y' , from ) ) ;
49+ else params . delete ( 'from' ) ;
50+ if ( to ) params . set ( 'to' , strftime ( '%m-%d-%y' , to ) ) ;
51+ else params . delete ( 'to' ) ;
52+ router . push ( `?${ params . toString ( ) } ` ) ;
53+ window . history . replaceState ( null , '' , `?${ params . toString ( ) } ` ) ;
54+ } ;
55+
56+ useEffect ( ( ) => {
57+ updateQueryParams ( rangeState . startDate , rangeState . endDate ) ;
58+ setDates ( {
59+ from : strftime ( '%Y-%m-%d' , rangeState . startDate ) ,
60+ to : strftime ( '%Y-%m-%d' , rangeState . endDate ) ,
61+ } ) ;
62+ } , [ ] ) ;
3663
3764 const onChange = ( selectedDates : any ) => {
3865 const [ start , end ] = selectedDates ;
3966 const from = start ? strftime ( '%Y-%m-%d' , new Date ( start ) ) : undefined ;
4067 const to = end ? strftime ( '%Y-%m-%d' , end ) : undefined ;
41- if ( from === to ) return ;
42- setDataRange ( { fromValue : start , toValue : end } ) ;
68+ if ( from === to || ! from || ! to ) return ;
69+ setRangeState ( { startDate : new Date ( from ) , endDate : new Date ( to ) , key : 'selection' } ) ;
4370 setDates ( { from, to } ) ;
71+ if ( from && to ) {
72+ updateQueryParams ( start , end ) ;
73+ }
4474 } ;
4575
4676 const dateRangeOptions = [
@@ -55,16 +85,6 @@ export const DateRangeSelect = () => {
5585 } ,
5686 ] ;
5787
58- useEffect ( ( ) => {
59- setRangeState ( [
60- {
61- startDate : dataRange . fromValue ,
62- endDate : dataRange . toValue ,
63- key : 'selection' ,
64- } ,
65- ] ) ;
66- } , [ dataRange . fromValue , dataRange . toValue ] ) ;
67-
6888 const onSelectItem = ( option : { id : number ; label : string ; isDefault ?: boolean } ) => {
6989 if ( option . id == ALL_TIME_ID ) {
7090 onChange ( [ null , null ] ) ;
@@ -95,7 +115,6 @@ export const DateRangeSelect = () => {
95115 } , [ ] ) ;
96116
97117 const onDateRangeChange = ( item : any ) => {
98- setRangeState ( [ item . selection ] ) ;
99118 if ( item . selection . startDate == item . selection . endDate ) {
100119 return ;
101120 }
@@ -105,13 +124,13 @@ export const DateRangeSelect = () => {
105124 const customContentRenderer = ( ) => {
106125 return (
107126 < div style = { { cursor : 'pointer' } } >
108- { dataRange . fromValue &&
109- dataRange . toValue &&
110- `${ strftime ( '%m-%d-%y' , dataRange . fromValue ) } to ${ strftime (
127+ { rangeState . startDate &&
128+ rangeState . endDate &&
129+ `${ strftime ( '%m-%d-%y' , rangeState . startDate ) } to ${ strftime (
111130 '%m-%d-%y' ,
112- dataRange . toValue
131+ rangeState . endDate
113132 ) } `}
114- { ( ! dataRange . fromValue || ! dataRange . toValue ) && 'All time' }
133+ { ( ! rangeState . startDate || ! rangeState . endDate ) && 'All time' }
115134 </ div >
116135 ) ;
117136 } ;
@@ -124,7 +143,7 @@ export const DateRangeSelect = () => {
124143 editableDateInputs = { true }
125144 onChange = { onDateRangeChange }
126145 moveRangeOnFirstSelection = { false }
127- ranges = { rangeState }
146+ ranges = { [ rangeState ] }
128147 showDateDisplay = { false }
129148 fixedHeight = { false }
130149 minDate = { DATA_START_DATE }
0 commit comments