Skip to content
Snippets Groups Projects
ConsumptionView.tsx 8.41 KiB
Newer Older
  • Learn to ignore specific revisions
  • import ExpiredConsentModal from 'components/Connection/ExpiredConsentModal/ExpiredConsentModal'
    
    import Content from 'components/Content/Content'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import CustomPopupModal from 'components/CustomPopup/CustomPopupModal'
    
    import DateNavigator from 'components/DateNavigator/DateNavigator'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import FluidChart from 'components/FluidChart/FluidChart'
    import CozyBar from 'components/Header/CozyBar'
    import Header from 'components/Header/Header'
    
    import KonnectorViewerCard from 'components/Konnector/KonnectorViewerCard'
    import KonnectorViewerList from 'components/Konnector/KonnectorViewerList'
    
    import PartnerIssueModal from 'components/PartnerIssue/PartnerIssueModal'
    
    import ReleaseNotesModal from 'components/ReleaseNotesModal/ReleaseNotesModal'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import { useClient } from 'cozy-client'
    
    import { FluidState, FluidType, TimeStep } from 'enums'
    
    import { DateTime } from 'luxon'
    
    import React, { useCallback, useEffect, useMemo, useState } from 'react'
    
    import DateChartService from 'services/dateChart.service'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import ProfileService from 'services/profile.service'
    
    import {
      setCurrentIndex,
      setCurrentTimeStep,
      setSelectedDate,
      setShowOfflineData,
    } from 'store/chart/chart.slice'
    
    import { useAppDispatch, useAppSelector } from 'store/hooks'
    
    import { openPartnersModal, setCustomPopup } from 'store/modal/modal.slice'
    
    import { isLastDateReached } from 'utils/date'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import {
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      getKonnectorUpdateError,
    
      getPartnerKey,
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      getTodayDate,
      isKonnectorActive,
    } from 'utils/utils'
    
    import ConsumptionDetails from './ConsumptionDetails/ConsumptionDetails'
    import FluidButtons from './FluidButtons/FluidButtons'
    
    import { WaterPricing } from './WaterPricing/WaterPricing'
    
    /**
     * http://ecolyo.cozy.tools:8080/#/consumption
     * http://ecolyo.cozy.tools:8080/#/consumption/electricity
     * http://ecolyo.cozy.tools:8080/#/consumption/water
     * http://ecolyo.cozy.tools:8080/#/consumption/gas
     */
    
    const ConsumptionView = ({ fluidType }: { fluidType: FluidType }) => {
    
      const client = useClient()
    
      const dispatch = useAppDispatch()
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      const {
    
        chart: { currentTimeStep, showOfflineData, selectedDate, currentIndex },
    
        global: { fluidStatus, releaseNotes },
        modal: { partnersIssueModal, customPopupModal },
    
      } = useAppSelector(state => state.ecolyo)
    
      const isMulti = fluidType === FluidType.MULTIFLUID
    
      const currentFluidStatus = fluidStatus[fluidType]
    
      const dateChartService = new DateChartService()
    
    
      /** Show wait consent screen when consent is "A valider" */
      const isWaitingForConsent =
        fluidType === FluidType.GAS &&
        currentFluidStatus.status === FluidState.CHALLENGE_ASKED
    
      const [openExpiredConsentModal, setOpenExpiredConsentModal] = useState(true)
    
      const [consentExpiredFluids, setConsentExpiredFluids] = useState<FluidType[]>(
    
      const profileService = useMemo(() => new ProfileService(client), [client])
    
    
      const updateKey =
    
        !isMulti && currentFluidStatus.lastDataDate
          ? `${currentFluidStatus.lastDataDate.toLocaleString()} + ${
              currentFluidStatus.status + fluidType
    
          : ''
      const lastDataDateKey =
    
        !isMulti && currentFluidStatus.lastDataDate
          ? `${currentFluidStatus.lastDataDate.toLocaleString() + fluidType}`
    
      const getTitleKey = (fluidType: FluidType): string => {
        if (fluidType === FluidType.MULTIFLUID) return 'common.title_consumption'
        return `common.title_consumption_${getFluidName(fluidType)}`
      }
    
    
      const handleClosePartnerIssueModal = useCallback(async () => {
        const profileValues = await profileService.getProfile()
        if (profileValues) {
          const updatedProfile = await profileService.updateProfile({
            partnersIssueSeenDate: {
              ...profileValues.partnersIssueSeenDate,
              [getPartnerKey(fluidType)]: getTodayDate(),
            },
          })
          if (updatedProfile) {
            dispatch(
              openPartnersModal({
                ...partnersIssueModal,
                [getPartnerKey(fluidType)]: false,
              })
            )
    
      }, [dispatch, fluidType, partnersIssueModal, profileService])
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      const handleCloseCustomPopupModal = async () => {
        const updatedProfile = await profileService.updateProfile({
          customPopupDate: getTodayDate(),
        })
        if (updatedProfile) {
          dispatch(
            setCustomPopup({
              ...customPopupModal,
              popupEnabled: false,
            })
          )
        }
      }
    
    
      useEffect(
        /** Reset half-hour timestep for water & gas & multifluid */
        function setDefaultTimeStep() {
          if (
            fluidType !== FluidType.ELECTRICITY &&
            currentTimeStep == TimeStep.HALF_AN_HOUR
          ) {
            dispatch(setCurrentTimeStep(TimeStep.WEEK))
          }
        },
        [dispatch, fluidType, currentTimeStep]
      )
    
      /**
       * If fluid is not connected, display Connect components
       * If fluid is connected, dispatch FluidChart
       */
    
      useEffect(() => {
    
        const isFluidConnected = isKonnectorActive(fluidStatus, fluidType)
        dispatch(setShowOfflineData(isFluidConnected))
      }, [dispatch, fluidStatus, fluidType])
    
      /** Check if some fluids have expired consent error */
    
        const expiredConsents: FluidType[] = []
    
          const error = fluid.connection.triggerState?.last_error
          if (error && getKonnectorUpdateError(error) === 'error_update_oauth') {
    
        subscribed && setConsentExpiredFluids(expiredConsents)
    
      const disablePrev =
        selectedDate <
          DateTime.local(0, 1, 1).setZone('utc', {
            keepLocalTime: true,
          }) && !isKonnectorActive(fluidStatus, FluidType.MULTIFLUID)
    
      const getIncrement = (next: boolean) =>
        next
          ? dateChartService.defineIncrementForNextIndex(
              currentTimeStep,
              selectedDate,
              currentIndex
            )
          : dateChartService.defineIncrementForPreviousIndex(
              currentTimeStep,
              selectedDate,
              currentIndex
            )
    
      const handleClickMove = (next: boolean) => {
        const increment = getIncrement(next)
        const updatedDate = dateChartService.incrementDate(
          currentTimeStep,
          selectedDate,
          increment
        )
        const updatedIndex = dateChartService.defineDateIndex(
          currentTimeStep,
          updatedDate
        )
        dispatch(setSelectedDate(updatedDate))
        dispatch(setCurrentIndex(updatedIndex))
      }
    
    
          <CozyBar titleKey={getTitleKey(fluidType)} />
          <Header desktopTitleKey={getTitleKey(fluidType)}>
    
            <DateNavigator
              disableNext={isLastDateReached(selectedDate, currentTimeStep)}
              disablePrev={disablePrev}
              handleNextDate={() => handleClickMove(true)}
              handlePrevDate={() => handleClickMove(false)}
              navigatorDate={selectedDate}
              timeStep={currentTimeStep}
            />
    
            <FluidButtons activeFluid={fluidType} key={updateKey} />
    
            {showOfflineData && !isWaitingForConsent && (
    
                <FluidChart fluidType={fluidType} key={lastDataDateKey} />
                <ConsumptionDetails fluidType={fluidType} />
    
    
            {fluidType === FluidType.WATER && showOfflineData && <WaterPricing />}
    
    
            {!isMulti && <KonnectorViewerCard fluidType={fluidType} />}
    
            {isMulti && !showOfflineData && <KonnectorViewerList />}
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
          {releaseNotes.show && <ReleaseNotesModal open={releaseNotes.show} />}
    
          {/* Partner issue modals for individual fluids */}
          {fluidStatus
            .filter(fluid => fluid.maintenance)
            .filter(fluid => fluid.fluidType === fluidType)
            .map(issuedFluid => (
              <PartnerIssueModal
                key={issuedFluid.fluidType}
    
                issuedFluid={issuedFluid.fluidType}
    
                open={partnersIssueModal[getPartnerKey(issuedFluid.fluidType)]}
    
                handleCloseClick={handleClosePartnerIssueModal}
              />
            ))}
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
          <CustomPopupModal
            customPopup={customPopupModal}
            handleCloseClick={handleCloseCustomPopupModal}
          />
    
          {Boolean(consentExpiredFluids.length) &&
    
            consentExpiredFluids.map(fluid => (
              <ExpiredConsentModal
                key={fluid}
                open={openExpiredConsentModal}
                handleCloseClick={() => setOpenExpiredConsentModal(false)}
                fluidType={fluid}
                toggleModal={() => setOpenExpiredConsentModal(prev => !prev)}
              />
            ))}
    
        </>
      )
    }
    
    export default ConsumptionView