Skip to content
Snippets Groups Projects
MaxConsumptionCard.tsx 6.02 KiB
Newer Older
  • Learn to ignore specific revisions
  • Bastien DUMONT's avatar
    Bastien DUMONT committed
    import IconButton from '@material-ui/core/IconButton'
    import GraphIcon from 'assets/icons/ico/graph-icon.svg'
    
    import LeftArrowIcon from 'assets/icons/ico/left-arrow.svg'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import RightArrowIcon from 'assets/icons/ico/right-arrow.svg'
    
    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/I18n'
    
    import Icon from 'cozy-ui/transpiled/react/Icon'
    
    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 './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 [chartData, setChartData] = useState<Datachart>({
        actualData: [],
        comparisonData: null,
      })
      const containerRef = useRef<HTMLDivElement>(null)
    
      const { height, width } = useChartResize(containerRef, isLoading, 250, 940)
    
      const [currentFluid, setCurrentFluid] = useState<FluidType | undefined>()
    
      useEffect(() => {
        setCurrentFluid(fluidsWithData[0])
      }, [fluidsWithData])
    
      const currentFluidSlug = FluidType[currentFluid || 0] as
    
        | 'ELECTRICITY'
        | 'WATER'
        | 'GAZ'
    
      const handleFluidChange = (direction: number) => {
    
        if (currentFluid === undefined) return
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
        setIsLoading(true)
    
        let newIndex = fluidsWithData.indexOf(currentFluid) + direction
        if (newIndex >= fluidsWithData.length) {
    
          newIndex = 0
        } else if (newIndex < 0) {
    
          newIndex = fluidsWithData.length - 1
    
        setCurrentFluid(fluidsWithData[newIndex])
    
    
      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(
    
    
          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)
    
        }
        if (subscribed) {
          getMaxLoadData()
        }
        return () => {
          subscribed = false
        }
    
      }, [analysisMonth, client, fluidsWithData, 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]
      }
    
      const buttonPrev = () => (
        <IconButton
          aria-label={t('consumption.accessibility.button_previous_value')}
          onClick={() => handleFluidChange(-1)}
          className="arrow-prev"
        >
          <Icon icon={LeftArrowIcon} size={24} />
        </IconButton>
      )
    
      const buttonNext = () => (
        <IconButton
          aria-label={t('consumption.accessibility.button_next_value')}
          onClick={() => handleFluidChange(1)}
          className="arrow-next"
        >
          <Icon icon={RightArrowIcon} size={24} />
        </IconButton>
      )
    
    
        <div className="max-consumption-container" ref={containerRef}>
    
          <StyledIcon icon={GraphIcon} size={38} />
          <div className="text-16-normal title">{t('analysis.max_day')}</div>
          <div className="fluid-navigation">
    
            {fluidsWithData.length > 1 && buttonPrev()}
            <div className={`text-20-bold fluid ${currentFluidSlug.toLowerCase()}`}>
              {t(`FLUID.${currentFluidSlug}.LABEL`)}
    
            {fluidsWithData.length > 1 && buttonNext()}
    
          <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 && (
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
                  <>
                    <div className="text-24-bold maxDay-date">
                      {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}
                    />
    
          </div>
        </div>
      )
    }
    
    export default MaxConsumptionCard