Skip to content
Snippets Groups Projects
FluidChart.tsx 6.22 KiB
Newer Older
  • Learn to ignore specific revisions
  • Bastien DUMONT's avatar
    Bastien DUMONT committed
    import { Button, Slide } from '@material-ui/core'
    
    import LegendComparisonIcon from 'assets/icons/ico/legendComparison.svg'
    import StyledIcon from 'components/CommonKit/Icon/StyledIcon'
    
    import StyledSwitch from 'components/CommonKit/Switch/StyledSwitch'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import useExploration from 'components/Hooks/useExploration'
    
    import { useMoveToLatestDate } from 'components/Hooks/useMoveToDate'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import { useClient } from 'cozy-client'
    
    import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
    
    import { FluidType, TimeStep, UserExplorationID } from 'enums'
    
    import React, { useCallback, useEffect, useState } from 'react'
    
    import { useNavigate } from 'react-router-dom'
    
    import ConsumptionService from 'services/consumption.service'
    
    import { setShowCompare, setShowOfflineData } from 'store/chart/chart.slice'
    
    import { useAppDispatch, useAppSelector } from 'store/hooks'
    
    import { getFluidName, getKonnectorSlug, isKonnectorActive } from 'utils/utils'
    
    import FluidChartSwipe from './FluidChartSwipe'
    
    import HalfHourNoDataFailure from './HalfHourNoDataFailure/HalfHourNoDataFailure'
    import HalfHourUpcoming from './HalfHourUpcoming/HalfHourUpcoming'
    
    import TimeStepSelector from './TimeStepSelector/TimeStepSelector'
    
    import './fluidChart.scss'
    
    const FluidChart = ({ fluidType }: { fluidType: FluidType }) => {
    
      const { t } = useI18n()
    
      const client = useClient()
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      const {
    
        chart: { currentTimeStep, selectedDate, showCompare },
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
        global: { fluidStatus },
    
      } = useAppSelector(state => state.ecolyo)
      const dispatch = useAppDispatch()
    
      const navigate = useNavigate()
    
      const currentFluidStatus = fluidStatus[fluidType]
      const isFluidConnected = isKonnectorActive(fluidStatus, fluidType)
    
      const { moveToLatestDate } = useMoveToLatestDate(
        currentFluidStatus?.lastDataDate
      )
    
      const [, setValidExploration] = useExploration()
    
      const [containsHalfHourData, setContainsHalfHourData] =
        useState<boolean>(false)
    
      const lowercaseTimeStep = TimeStep[currentTimeStep].toLowerCase()
    
      const lowercaseFluidType = getFluidName(fluidType)
    
      const handleChangeSwitch = () => {
    
        dispatch(setShowCompare(!showCompare))
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
      useEffect(() => {
        let subscribed = true
        async function loadData() {
    
          if (fluidType === FluidType.ELECTRICITY) {
    
            const consumptionService = new ConsumptionService(client)
    
            const halfHourData = await consumptionService.checkDoctypeEntries(
    
              FluidType.ELECTRICITY,
              TimeStep.HALF_AN_HOUR
            )
    
            if (halfHourData) {
              setContainsHalfHourData(true)
            }
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
        }
    
        subscribed && loadData()
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
        return () => {
          subscribed = false
        }
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
      }, [client, fluidStatus, selectedDate, currentTimeStep, fluidType])
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
      useEffect(() => {
    
        if (containsHalfHourData && currentTimeStep === TimeStep.HALF_AN_HOUR) {
    
          setValidExploration(UserExplorationID.EXPLORATION004)
    
    Yoan VALLET's avatar
    Yoan VALLET committed
        } else if (currentTimeStep === TimeStep.YEAR) {
    
          setValidExploration(UserExplorationID.EXPLORATION003)
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
        }
    
      }, [containsHalfHourData, currentTimeStep, setValidExploration])
    
    
      const compareLegend = useCallback(
    
        () => (
          <div className="compareLegend">
            <div>
              <StyledIcon
                icon={LegendComparisonIcon}
                className={`${lowercaseFluidType} compare`}
              />
              <span className={`${lowercaseFluidType} compare`}>
                {t(`timestep.${lowercaseTimeStep}.last`)}
              </span>
            </div>
            <div>
              <StyledIcon
                icon={LegendComparisonIcon}
                className={lowercaseFluidType}
              />
              <span className={lowercaseFluidType}>
                {t(`timestep.${lowercaseTimeStep}.current`)}
              </span>
            </div>
          </div>
        ),
        [lowercaseFluidType, lowercaseTimeStep, t]
      )
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    
      const toggleModalConnection = () => {
        switch (fluidType) {
          case FluidType.ELECTRICITY:
    
            navigate('/connect/electricity')
    
            break
          case FluidType.GAS:
    
            navigate('/connect/gas')
            break
    
          case FluidType.WATER:
            dispatch(setShowOfflineData(false))
            break
    
          default:
            throw new Error('Unexpected fluid type')
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      const LastDataValid = fluidType !== FluidType.MULTIFLUID && (
    
        <div className="lastValidData">
    
          <Button className="btnText" onClick={moveToLatestDate}>
    
            {t('consumption_visualizer.last_valid_data', {
    
              date: currentFluidStatus?.lastDataDate?.toFormat('dd/MM/yy') ?? '-',
    
          <p>{t('auth.warningOfflineData')}</p>
    
          <Button className="btnSecondary" onClick={toggleModalConnection}>
    
            {t(`auth.${getKonnectorSlug(fluidType)}.connect`)}
          </Button>
        </div>
      )
    
    
      const isKonnectorUpdatedWithinLastThreeDays =
        DateTime.fromISO(
    
          currentFluidStatus?.connection?.trigger?.cozyMetadata?.createdAt || ''
    
      /** Display no half hour components or FluidChart otherwise */
      const chartContent = () => {
        if (currentTimeStep === TimeStep.HALF_AN_HOUR && !containsHalfHourData) {
          return isKonnectorUpdatedWithinLastThreeDays ? (
            <HalfHourUpcoming />
          ) : (
            <HalfHourNoDataFailure />
          )
        }
        return (
          <>
            <div className="fluidchart-content">
    
              <FluidChartSwipe fluidType={fluidType} />
    
            </div>
            {showCompare && currentTimeStep !== TimeStep.YEAR && (
              <Slide direction="right" in={showCompare}>
                {compareLegend()}
              </Slide>
            )}
          </>
        )
      }
    
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
      return (
    
        <div className="fluidchart-root">
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
          {!isFluidConnected && LastDataValid}
    
          {chartContent()}
    
          <TimeStepSelector fluidType={fluidType} />
          {currentTimeStep !== TimeStep.YEAR && (
    
            <div className="fluidchart-footer">
    
              <div className="fluidchart-footer-compare text-15-normal">
                <StyledSwitch
                  fluidType={fluidType}
                  checked={showCompare}
    
                  aria-label={t('consumption.accessibility.checkbox_compare')}
                  onClick={handleChangeSwitch}
    
                />
                <span className="fluidchart-footer-label graph-switch-text">
                  {t(`timestep.${lowercaseTimeStep}.comparelabel`)}
                </span>
              </div>
    
    Romain CREY's avatar
    Romain CREY committed
          )}
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
      )
    }
    
    
    export default FluidChart