import React, { useState, useEffect, useContext } from 'react' import { DateTime } from 'luxon' import { IConsumptionDataManager, IDataload, IChartData, ChartData, TimeStep, ITimePeriod, } from 'services/dataConsumptionContracts' import { defineTimePeriod } from 'services/dateChartService' import { FluidType } from 'enum/fluid.enum' import BarChart from 'components/ContentComponents/Charts/BarChart' import { AppContext } from 'components/Contexts/AppContextProvider' import StyledSpinner from 'components/CommonKit/Spinner/StyledSpinner' interface FluidChartSlideProps { index: number fluidTypes: FluidType[] timeStep: TimeStep multiFluid: boolean referenceDate: DateTime selectedDate: DateTime showCompare: boolean width: number height: number challengePeriod: ITimePeriod | null handleClickData: ( dataload: IDataload, compareDataload: IDataload | null ) => void consumptionDataManager: IConsumptionDataManager isSwitching: boolean } const FluidChartSlide: React.FC<FluidChartSlideProps> = ({ index, fluidTypes, timeStep, multiFluid, referenceDate, selectedDate, showCompare, width, height, challengePeriod, handleClickData, consumptionDataManager, isSwitching, }: FluidChartSlideProps) => { const [chartData, setChartData] = useState<IChartData>(new ChartData([])) const [isLoaded, setIsLoaded] = useState<boolean>(false) const { setChartIsLoaded, maxLoads, chartIsLoaded } = useContext(AppContext) const isHome: boolean = !window.location.hash.split('/')[2] ? true : false useEffect(() => { let subscribed = true async function loadData() { const [timePeriod, compareTimePeriod] = await Promise.all([ defineTimePeriod(referenceDate, timeStep, index), defineTimePeriod(referenceDate, timeStep, index + 1), ]) const graphData = await consumptionDataManager.getGraphData( timePeriod, timeStep, fluidTypes, compareTimePeriod, isHome ) if (subscribed && graphData && graphData.actualData.length > 0) { setChartData(graphData) setIsLoaded(true) } } setIsLoaded(false) loadData() return () => { subscribed = false } }, [timeStep, fluidTypes]) useEffect(() => { let subscribed = true const actualMonth = selectedDate.startOf('week').month const actualYear = selectedDate.startOf('week').year const maxTimePeriod = { startDate: timeStep === TimeStep.HALF_AN_HOUR ? selectedDate.startOf('month') : selectedDate.startOf('week').startOf('month').weekdayLong === 'lundi' ? selectedDate.startOf('week').startOf('month') : selectedDate .startOf('week') .startOf('month') .plus({ days: +7 }) .startOf('week'), endDate: timeStep === TimeStep.HALF_AN_HOUR ? selectedDate.endOf('month') : selectedDate.startOf('week').month !== selectedDate.endOf('week').month ? selectedDate.endOf('week') : selectedDate.endOf('month').endOf('week'), } const compareMaxTimePeriod = maxTimePeriod const key = `${actualMonth}/${actualYear}-${isHome}-${fluidTypes .sort() .join('-')}-${timeStep}` async function loadData() { setChartIsLoaded(false) const graphMaxLoad = await consumptionDataManager.getMaxLoad( maxTimePeriod, timeStep, fluidTypes, compareMaxTimePeriod, isHome ) maxLoads[key] = graphMaxLoad if (subscribed && graphMaxLoad) { setIsLoaded(true) setChartIsLoaded(true) } } if ( key in maxLoads === false && (timeStep === TimeStep.DAY || timeStep === TimeStep.HALF_AN_HOUR) ) { loadData() } return () => { subscribed = false } }, [selectedDate, fluidTypes]) return ( <> <div className="fs-slide"> {!chartIsLoaded || !isLoaded ? ( <div className="chart-loading"> <StyledSpinner size="5em" fluidTypes={fluidTypes} isHome={isHome} /> </div> ) : ( <BarChart chartData={chartData} fluidTypes={fluidTypes} timeStep={timeStep} multiFluid={multiFluid} selectedDate={selectedDate} showCompare={showCompare} handleClickData={handleClickData} height={height} width={width} challengePeriod={challengePeriod} isSwitching={isSwitching} isHome={isHome} /> )} </div> </> ) } export default FluidChartSlide