Skip to content
Snippets Groups Projects
ConsumptionView.tsx 9.44 KiB
Newer Older
  • Learn to ignore specific revisions
  • import ExpiredConsentModal from 'components/Connection/ExpiredConsentModal/ExpiredConsentModal'
    
    import { GrdfWaitConsentModal } from 'components/Connection/GRDFConnect/GrdfWaitConsent'
    
    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'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import { FluidState, FluidType, TimeStep } from 'enums'
    
    import { DateTime } from 'luxon'
    
    import React, { useCallback, useEffect, useState } from 'react'
    
    import { useNavigate } from 'react-router-dom'
    
    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 { showReleaseNotes } from 'store/global/global.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 {
      getKonnectorUpdateError,
      getTodayDate,
      isKonnectorActive,
    } from 'utils/utils'
    
    import ConsumptionDetails from './ConsumptionDetails/ConsumptionDetails'
    import FluidButtons from './FluidButtons/FluidButtons'
    
    const ConsumptionView = ({ fluidType }: { fluidType: FluidType }) => {
    
      const navigate = useNavigate()
    
      const client = useClient()
    
      const dispatch = useAppDispatch()
    
      const isMulti = fluidType === FluidType.MULTIFLUID
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      const {
    
        chart: { currentTimeStep, showOfflineData, selectedDate, currentIndex },
    
        global: { fluidStatus, releaseNotes },
        modal: { partnersIssueModal, customPopupModal },
    
      } = useAppSelector(state => state.ecolyo)
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      const currentFluidStatus = fluidStatus[fluidType]
    
      const dateChartService = new DateChartService()
    
    
      const isWaitingForConsent =
        fluidType === FluidType.GAS &&
        currentFluidStatus.status === FluidState.CHALLENGE_ASKED
    
      const [waitConsent, setWaitConsent] = useState(isWaitingForConsent)
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      const [openExpiredConsentModal, setOpenExpiredConsentModal] = useState(true)
      const [openReleaseNoteModal, setOpenReleaseNoteModal] = useState<boolean>(
        releaseNotes.show
      )
      const [consentExpiredFluids, setConsentExpiredFluids] = useState<FluidType[]>(
        []
      )
    
    
      /** Show wait consent modal when navigating and consent is "A valider" */
      useEffect(() => {
        setWaitConsent(isWaitingForConsent)
      }, [isWaitingForConsent])
    
      const updateKey =
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
        fluidType !== FluidType.MULTIFLUID && currentFluidStatus.lastDataDate
          ? `${currentFluidStatus.lastDataDate.toLocaleString()} + ${
              currentFluidStatus.status + fluidType
    
          : ''
      const lastDataDateKey =
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
        fluidType !== FluidType.MULTIFLUID && currentFluidStatus.lastDataDate
          ? `${currentFluidStatus.lastDataDate.toLocaleString() + fluidType}`
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      const getPartnerKey = (fluidType: FluidType): 'enedis' | 'egl' | 'grdf' => {
        switch (fluidType) {
          case FluidType.ELECTRICITY:
            return 'enedis'
          case FluidType.WATER:
            return 'egl'
          case FluidType.GAS:
            return 'grdf'
          default:
            throw new Error('unknown fluidtype')
        }
      }
    
    
      const handleCloseReleaseNoteModal = useCallback(() => {
        setOpenReleaseNoteModal(false)
        dispatch(
    
          showReleaseNotes({
            show: false,
            notes: releaseNotes.notes,
            redirectLink: releaseNotes.redirectLink,
          })
    
        )
        if (releaseNotes.redirectLink) {
    
          navigate(releaseNotes.redirectLink)
    
      }, [dispatch, navigate, releaseNotes.notes, releaseNotes.redirectLink])
    
      const handleClosePartnerIssueModal = useCallback(
        async (fluidType: FluidType) => {
          const profileService = new ProfileService(client)
          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,
                })
              )
            }
          }
        },
    
        [client, dispatch, partnersIssueModal]
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      const handleCloseCustomPopupModal = async () => {
        const profileService = new ProfileService(client)
        const updatedProfile = await profileService.updateProfile({
          customPopupDate: getTodayDate(),
        })
        if (updatedProfile) {
          dispatch(
            setCustomPopup({
              ...customPopupModal,
              popupEnabled: false,
            })
          )
        }
      }
    
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      useEffect(
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
        /** Reset half-hour timestep for water & gas & multifluid */
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
        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])
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      /** Check if some fluids have expired consent error */
    
        const expiredConsents: FluidType[] = []
    
        // TODO only electricity can have expired consent error -> refactor this for of loop
    
          const error = fluid.connection.triggerState?.last_error
          if (error && getKonnectorUpdateError(error) === 'error_update_oauth') {
    
        if (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="common.title_consumption" />
    
          <Header desktopTitleKey="common.title_consumption">
    
            <DateNavigator
              disableNext={isLastDateReached(selectedDate, currentTimeStep)}
              disablePrev={disablePrev}
              handleNextDate={() => handleClickMove(true)}
              handlePrevDate={() => handleClickMove(false)}
              navigatorDate={selectedDate}
              timeStep={currentTimeStep}
            />
    
            <FluidButtons activeFluid={fluidType} key={updateKey} />
    
            {showOfflineData && (
              <>
                <FluidChart fluidType={fluidType} key={lastDataDateKey} />
                <ConsumptionDetails fluidType={fluidType} />
              </>
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
            {!isMulti && <KonnectorViewerCard fluidType={fluidType} />}
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
            {isMulti && !showOfflineData && <KonnectorViewerList />}
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
          {/* MODALS */}
          {openReleaseNoteModal && (
            <ReleaseNotesModal
              open={openReleaseNoteModal}
              handleCloseClick={handleCloseReleaseNoteModal}
            />
          )}
    
          {/* 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) &&
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
            consentExpiredFluids.map(fluid => (
              <ExpiredConsentModal
                key={fluid}
                open={openExpiredConsentModal}
                handleCloseClick={() => setOpenExpiredConsentModal(false)}
                fluidType={fluid}
                toggleModal={() => setOpenExpiredConsentModal(prev => !prev)}
              />
            ))}
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    
          {/* GRDF Waiting screen */}
    
          <GrdfWaitConsentModal open={waitConsent} setOpen={setWaitConsent} />
    
        </>
      )
    }
    
    export default ConsumptionView