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