Skip to content
Snippets Groups Projects
MaxConsumptionCard.tsx 5.67 KiB
Newer Older
  • Learn to ignore specific revisions
  • Bastien DUMONT's avatar
    Bastien DUMONT committed
    import { IconButton } from '@material-ui/core'
    import classNames from 'classnames'
    
    import BarChart from 'components/Charts/BarChart'
    
    import StyledIcon from 'components/CommonKit/Icon/StyledIcon'
    
    import DataloadSection from 'components/ConsumptionVisualizer/DataloadSection'
    import { useChartResize } from 'components/Hooks/useChartResize'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import Loader from 'components/Loader/Loader'
    import { useClient } from 'cozy-client'
    
    import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
    
    import { DataloadSectionType, FluidType, TimeStep } from 'enums'
    
    import { Datachart, Dataload, TimePeriod } from 'models'
    
    import React, { useEffect, useRef, useState } from 'react'
    
    import ConsumptionDataManager from 'services/consumption.service'
    
    import { setSelectedDate } from 'store/chart/chart.slice'
    
    import { useAppDispatch, useAppSelector } from 'store/hooks'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import { getActiveFluidIcon } from 'utils/picto'
    
    import { getFluidName } from 'utils/utils'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import './maxConsumptionCard.scss'
    
    const MaxConsumptionCard = ({
      fluidsWithData,
    }: {
      fluidsWithData: FluidType[]
    }) => {
    
      const { t } = useI18n()
      const client = useClient()
    
      const dispatch = useAppDispatch()
      const { analysisMonth } = useAppSelector(state => state.ecolyo.analysis)
    
      const [isLoading, setIsLoading] = useState<boolean>(false)
    
      const [maxDayData, setMaxDayData] = useState<Dataload | null>(null)
    
      const [currentFluid, setCurrentFluid] = useState<FluidType>(fluidsWithData[0])
    
      const [chartData, setChartData] = useState<Datachart>({
        actualData: [],
        comparisonData: null,
      })
      const containerRef = useRef<HTMLDivElement>(null)
    
      const { height, width } = useChartResize(containerRef, isLoading, 250, 940)
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      const handleFluidChange = (fluidType: FluidType) => {
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
        setIsLoading(true)
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
        setCurrentFluid(fluidType)
    
    
      useEffect(() => {
        let subscribed = true
        async function getMaxLoadData() {
    
          if (currentFluid === undefined) return
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
          setIsLoading(true)
    
          const timePeriod: TimePeriod = {
    
            startDate: analysisMonth.minus({ month: 1 }).startOf('month'),
            endDate: analysisMonth.minus({ month: 1 }).endOf('month'),
    
          }
          const consumptionService = new ConsumptionDataManager(client)
    
          const monthlyData = await consumptionService.getGraphData({
    
            timeStep: TimeStep.DAY,
            fluidTypes: [currentFluid],
          })
    
    
          if (monthlyData && monthlyData?.actualData.length > 0) {
            setChartData(monthlyData)
            const maxDay = getMaxConsumptionDay(monthlyData.actualData)
            if (maxDay) {
              setMaxDayData(maxDay)
              dispatch(setSelectedDate(maxDay.date))
            } else {
              setMaxDayData(null)
            }
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
          setIsLoading(false)
    
        subscribed && getMaxLoadData()
    
    
        return () => {
          subscribed = false
        }
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      }, [analysisMonth, client, currentFluid, dispatch])
    
    
      const getMaxConsumptionDay = (dataload: Dataload[]) => {
        let maxIndex = -1
        let maxValue = -1
        dataload.forEach((day, index) => {
          if (day.value > 0 && day.value > maxValue) {
            maxValue = day.value
            maxIndex = index
          }
        })
        if (maxIndex === -1) return null
        return dataload[maxIndex]
      }
    
    
        <div className="max-consumption-container" ref={containerRef}>
    
          <div className="text-20-normal title">{t('analysis.max_day')}</div>
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
          <div className="fluid-navigation" role="tablist">
            {fluidsWithData.map(fluid => (
              <FluidMaxButton
                key={fluid}
                fluidType={fluid}
                handleClick={handleFluidChange}
                isActive={currentFluid === fluid}
              />
            ))}
    
          <div className="data-container">
    
            {isLoading && (
              <div className="loaderContainer">
    
                <Loader fluidType={currentFluid} />
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
            {!isLoading && (
              <>
                {!maxDayData && (
    
                  <p className="text-20-bold no_data">{t('analysis.no_data')}</p>
    
                {maxDayData && currentFluid !== undefined && (
    
                    <div className="text-16-bold maxDay-date">
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
                      {maxDayData.date.setLocale('fr').toFormat('cccc dd LLLL')}
                    </div>
    
                    <div>
                      <DataloadSection
                        dataload={maxDayData}
    
                        fluidType={currentFluid}
    
                        dataloadSectionType={DataloadSectionType.NO_COMPARE}
                        toggleEstimationModal={() => null}
                      />
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
                    </div>
    
                    <BarChart
                      chartData={chartData}
    
                      fluidType={currentFluid}
    
                      height={height}
                      width={width}
                      isSwitching={false}
                      clickable={false}
                    />
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    const FluidMaxButton = ({
      handleClick,
      isActive,
      fluidType,
    }: {
      handleClick: (fluidType: FluidType) => void
      isActive: boolean
      fluidType: FluidType
    }) => {
      const { t } = useI18n()
      const fluidName = getFluidName(fluidType)
      return (
        <IconButton
          role="tab"
          className={classNames('fluidMaxButton', { active: isActive })}
          onClick={() => handleClick(fluidType)}
        >
          <StyledIcon
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
            icon={getActiveFluidIcon(fluidType, isActive, true)}
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
            size={fluidType === FluidType.MULTIFLUID ? 36 : 32}
          />
    
          <div
    
            className={classNames('text-14-normal fluidLabel', {
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
              active: isActive,
            })}
          >
            {t(`FLUID.${fluidName.toLocaleUpperCase()}.LABEL`)}
          </div>
        </IconButton>
      )
    }
    
    
    export default MaxConsumptionCard