1- import  React  from  "react" ; 
1+ import  React ,   {   useState   }  from  "react" ; 
22import  {  styled  }  from  "@mui/material/styles" ; 
33import  {  format  as  formatDate  }  from  "date-fns" ; 
44import  {  Popover ,  Chip ,  useTheme ,  Drawer ,  Button ,  useMediaQuery ,  colors  }  from  "@mui/material" ; 
55import  {  ArrowDropDown  as  ArrowDropDownIcon ,  Cancel  as  CancelIcon  }  from  "@mui/icons-material" ; 
6- import  InfiniteCalendar ,   {   Calendar ,   withRange   }   from  "react-infinite -calendar" ; 
6+ import  Calendar   from  "react-calendar" ; 
77
8- import  "react-infinite- calendar/styles .css" ; 
9- import  {  TransactionDateRangePayload  }  from  "../models" ; 
10- import  {  hasDateQueryFields  }  from  "../utils/transactionUtils" ; 
8+ import  "react-calendar/dist/Calendar .css" ; 
9+ import  {  TransactionDateRangePayload ,   Value ,   ValuePiece  }  from  "../models" ; 
10+ import  {  hasDateQueryFields ,   localDateToUTCISOString  }  from  "../utils/transactionUtils" ; 
1111
1212const  PREFIX  =  "TransactionListDateRangeFilter" ; 
1313
@@ -27,7 +27,6 @@ const Root = styled("div")(({ theme }) => ({
2727} ) ) ; 
2828
2929const  {  indigo }  =  colors ; 
30- const  CalendarWithRange  =  withRange ( Calendar ) ; 
3130
3231export  type  TransactionListDateRangeFilterProps  =  { 
3332  filterDateRange : Function ; 
@@ -43,15 +42,19 @@ const TransactionListDateRangeFilter: React.FC<TransactionListDateRangeFilterPro
4342  const  theme  =  useTheme ( ) ; 
4443  const  xsBreakpoint  =  useMediaQuery ( theme . breakpoints . only ( "xs" ) ) ; 
4544  const  queryHasDateFields  =  dateRangeFilters  &&  hasDateQueryFields ( dateRangeFilters ) ; 
45+   const  [ calendarValue ,  setCalendarValue ]  =  useState < Value > ( null ) ; 
4646
4747  const  [ dateRangeAnchorEl ,  setDateRangeAnchorEl ]  =  React . useState < HTMLDivElement  |  null > ( null ) ; 
4848
49-   const  onCalendarSelect  =  ( e : {  eventType : number ;  start : any ;  end : any  } )  =>  { 
50-     if  ( e . eventType  ===  3 )  { 
51-       filterDateRange ( { 
52-         dateRangeStart : new  Date ( e . start . setUTCHours ( 0 ,  0 ,  0 ,  0 ) ) . toISOString ( ) , 
53-         dateRangeEnd : new  Date ( e . end . setUTCHours ( 23 ,  59 ,  59 ,  999 ) ) . toISOString ( ) , 
54-       } ) ; 
49+   const  onCalendarSelect  =  ( val : Value )  =>  { 
50+     if  ( val  &&  ! ( val  instanceof  Date ) )  { 
51+       const  [ rangeStart ,  rangeEnd ]  =  val ; 
52+       const  calValue  =  { 
53+         dateRangeStart : localDateToUTCISOString ( rangeStart ) , 
54+         dateRangeEnd : localDateToUTCISOString ( rangeEnd ) , 
55+       } ; 
56+       setCalendarValue ( val ) ; 
57+       filterDateRange ( calValue ) ; 
5558      setDateRangeAnchorEl ( null ) ; 
5659    } 
5760  } ; 
@@ -67,13 +70,16 @@ const TransactionListDateRangeFilter: React.FC<TransactionListDateRangeFilterPro
6770  const  dateRangeOpen  =  Boolean ( dateRangeAnchorEl ) ; 
6871  const  dateRangeId  =  dateRangeOpen  ? "date-range-popover"  : undefined ; 
6972
70-   const  formatButtonDate  =  ( date : string )  =>  { 
71-     return  formatDate ( new   Date ( date ) ,  "MMM, d yyyy" ) ; 
73+   const  formatButtonDate  =  ( date : Date )  =>  { 
74+     return  formatDate ( date ,  "MMM, d yyyy" ) ; 
7275  } ; 
7376
74-   const  dateRangeLabel  =  ( dateRangeFields : TransactionDateRangePayload )  =>  { 
75-     const  {  dateRangeStart,  dateRangeEnd }  =  dateRangeFields ; 
76-     return  `${ formatButtonDate ( dateRangeStart ! ) } ${ formatButtonDate ( dateRangeEnd ! ) }  ; 
77+   const  dateRangeLabel  =  ( dateRangeFields : Value )  =>  { 
78+     if  ( dateRangeFields  &&  ! ( dateRangeFields  instanceof  Date ) )  { 
79+       const  [ dateRangeStart ,  dateRangeEnd ]  =  dateRangeFields ; 
80+       const  label  =  `${ formatButtonDate ( dateRangeStart ! ) } ${ formatButtonDate ( dateRangeEnd ! ) }  ; 
81+       return  label ; 
82+     } 
7783  } ; 
7884
7985  return  ( 
@@ -95,9 +101,10 @@ const TransactionListDateRangeFilter: React.FC<TransactionListDateRangeFilterPro
95101          variant = "outlined" 
96102          onClick = { handleDateRangeClick } 
97103          data-test = "transaction-list-filter-date-range-button" 
98-           label = { `Date: ${ dateRangeLabel ( dateRangeFilters ) }  } 
104+           label = { `Date: ${ dateRangeLabel ( calendarValue ) }  } 
99105          deleteIcon = { < CancelIcon  data-test = "transaction-list-filter-date-clear-button"  /> } 
100106          onDelete = { ( )  =>  { 
107+             setCalendarValue ( null ) ; 
101108            resetDateRange ( ) ; 
102109          } } 
103110        /> 
@@ -118,28 +125,12 @@ const TransactionListDateRangeFilter: React.FC<TransactionListDateRangeFilterPro
118125          } } 
119126          className = { classes . popover } 
120127        > 
121-           < InfiniteCalendar 
122-             data-test = "transaction-list-filter-date-range" 
123-             width = { xsBreakpoint  ? window . innerWidth  : 350 } 
124-             height = { xsBreakpoint  ? window . innerHeight  : 300 } 
125-             rowHeight = { 50 } 
126-             Component = { CalendarWithRange } 
127-             selected = { false } 
128-             onSelect = { onCalendarSelect } 
129-             locale = { { 
130-               headerFormat : "MMM Do" , 
131-             } } 
132-             theme = { { 
133-               accentColor : indigo [ "400" ] , 
134-               headerColor : indigo [ "500" ] , 
135-               weekdayColor : indigo [ "300" ] , 
136-               selectionColor : indigo [ "300" ] , 
137-               floatingNav : { 
138-                 background : indigo [ "400" ] , 
139-                 color : "#FFF" , 
140-                 chevron : "#FFA726" , 
141-               } , 
142-             } } 
128+           < RangeCalendar 
129+             onCalendarSelect = { onCalendarSelect } 
130+             xsBreakpoint = { xsBreakpoint } 
131+             color = { indigo } 
132+             dataTest = "transaction-list-filter-date-range" 
133+             defaultValue = { calendarValue } 
143134          /> 
144135        </ Popover > 
145136      ) } 
@@ -154,33 +145,56 @@ const TransactionListDateRangeFilter: React.FC<TransactionListDateRangeFilterPro
154145          < Button  data-test = "date-range-filter-drawer-close"  onClick = { ( )  =>  handleDateRangeClose ( ) } > 
155146            Close
156147          </ Button > 
157-           < InfiniteCalendar 
158-             data-test = "transaction-list-filter-date-range" 
159-             width = { window . innerWidth } 
160-             height = { window . innerHeight  -  185 } 
161-             rowHeight = { 50 } 
162-             Component = { CalendarWithRange } 
163-             selected = { false } 
164-             onSelect = { onCalendarSelect } 
165-             locale = { { 
166-               headerFormat : "MMM Do" , 
167-             } } 
168-             theme = { { 
169-               accentColor : indigo [ "400" ] , 
170-               headerColor : indigo [ "500" ] , 
171-               weekdayColor : indigo [ "300" ] , 
172-               selectionColor : indigo [ "300" ] , 
173-               floatingNav : { 
174-                 background : indigo [ "400" ] , 
175-                 color : "#FFF" , 
176-                 chevron : "#FFA726" , 
177-               } , 
178-             } } 
148+           < RangeCalendar 
149+             onCalendarSelect = { onCalendarSelect } 
150+             xsBreakpoint = { xsBreakpoint } 
151+             color = { indigo } 
152+             dataTest = "transaction-list-filter-date-range" 
153+             defaultValue = { calendarValue } 
179154          /> 
180155        </ Drawer > 
181156      ) } 
182157    </ Root > 
183158  ) ; 
184159} ; 
185160
161+ export  function  RangeCalendar ( { 
162+   onCalendarSelect, 
163+   xsBreakpoint, 
164+   color, 
165+   dataTest, 
166+   defaultValue, 
167+ } : { 
168+   onCalendarSelect : ( value : Value )  =>  void ; 
169+   xsBreakpoint : boolean ; 
170+   color : Record < string ,  string > ; 
171+   dataTest : string ; 
172+   defaultValue : Value ; 
173+ } )  { 
174+   const  [ value ,  setValue ]  =  useState < Value > ( defaultValue ) ; 
175+ 
176+   const  width  =  xsBreakpoint  ? window . innerWidth  : 350 ; 
177+   const  height  =  xsBreakpoint  ? window . innerHeight  : 300 ; 
178+ 
179+   const  handleChange  =  ( val : Value ,  _ : any )  =>  { 
180+     setValue ( val ) ; 
181+     onCalendarSelect ( val ) ; 
182+   } ; 
183+ 
184+   return  ( 
185+     < div 
186+       data-test = { dataTest } 
187+       style = { { 
188+         width, 
189+         maxWidth : "100%" , 
190+         background : color [ "400" ] , 
191+         padding : 8 , 
192+         borderRadius : 8 , 
193+       } } 
194+     > 
195+       < Calendar  onChange = { handleChange }  value = { value }  selectRange = { true }  /> 
196+     </ div > 
197+   ) ; 
198+ } 
199+ 
186200export  default  TransactionListDateRangeFilter ; 
0 commit comments