Skip to content
Snippets Groups Projects
MonthlyAnalysis.tsx 6.78 KiB
Newer Older
  • Learn to ignore specific revisions
  • Bastien DUMONT's avatar
    Bastien DUMONT committed
    import { Fade } from '@material-ui/core'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import Loader from 'components/Loader/Loader'
    
    import { useClient } from 'cozy-client'
    
    import { FluidState, FluidType, TimeStep } from 'enums'
    
    import { PerformanceIndicator, TimePeriod } from 'models'
    import React, { useEffect, useMemo, useState } from 'react'
    
    import ConsumptionService from 'services/consumption.service'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import PerformanceIndicatorService from 'services/performanceIndicator.service'
    
    import { useAppSelector } from 'store/hooks'
    
    import { allFluids } from 'utils/utils'
    
    import Comparison from './Comparison/Comparison'
    import ElecHalfHourMonthlyAnalysis from './ElecHalfHourMonthlyAnalysis/ElecHalfHourMonthlyAnalysis'
    
    import IncompleteDataWarning from './IncompleteDataWarning/IncompleteDataWarning'
    
    import MaxConsumptionCard from './MaxConsumptionCard/MaxConsumptionCard'
    
    import './monthlyanalysis.scss'
    import NewsletterReminder from './NewsletterReminder/NewsletterReminder'
    
    import NoAnalysisModal from './NoKonnector/NoAnalysisModal'
    
    import ProfileComparator from './ProfileComparator/ProfileComparator'
    import TotalAnalysisChart from './TotalAnalysisChart/TotalAnalysisChart'
    
    interface MonthlyAnalysisProps {
    
      saveLastScrollPosition: () => void
      scrollPosition: number
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    const MonthlyAnalysis = ({
    
      saveLastScrollPosition,
      scrollPosition,
    
    }: MonthlyAnalysisProps) => {
    
      const client = useClient()
    
        analysis: { analysisMonth, haveSeenNewsletterReminder },
    
        global: { fluidStatus },
    
        profile: { sendAnalysisNotification, isAnalysisReminderEnabled },
    
      } = useAppSelector(state => state.ecolyo)
    
    
      const consumptionService = useMemo(
        () => new ConsumptionService(client),
        [client]
      )
      const performanceIndicatorService = useMemo(
        () => new PerformanceIndicatorService(),
        []
      )
    
    
      const allKonnectorDisconnected = fluidStatus.some(
        fluid => fluid.status === FluidState.NOT_CONNECTED
      )
    
    
      const [isLoadingAnalysis, setLoadingAnalysis] = useState<boolean>(true)
    
      const [openNoDataModal, setOpenNoDataModal] = useState(false)
    
      const [fluidsWithData, setFluidsWithData] = useState<FluidType[]>([])
    
      const [incompleteDataFluids, setIncompleteDataFluids] = useState<FluidType[]>(
        []
      )
    
      const [performanceIndicators, setPerformanceIndicators] = useState<
        PerformanceIndicator[]
      >([])
    
      const [aggregatedPerformanceIndicators, setAggregatedPerformanceIndicators] =
        useState<PerformanceIndicator>({
          value: 0,
          compareValue: 0,
          percentageVariation: 0,
        })
    
      const displayNewsletterReminder =
        !sendAnalysisNotification &&
        isAnalysisReminderEnabled &&
        !haveSeenNewsletterReminder
    
    
      useEffect(() => {
    
        let subscribed = true
    
    
        const populateData = async () => {
    
          setLoadingAnalysis(true)
    
    
          const timePeriod: TimePeriod = {
            startDate: analysisMonth.minus({ month: 1 }).startOf('month'),
            endDate: analysisMonth.minus({ month: 1 }).endOf('month'),
          }
          const comparisonTimePeriod: TimePeriod = {
            startDate: analysisMonth.minus({ month: 2 }).startOf('month'),
            endDate: analysisMonth.minus({ month: 2 }).endOf('month'),
    
          const [resultFluids, fetchedIncompleteDataFluids] = await Promise.all([
            consumptionService.getFluidsWithDataForTimePeriod(
              allFluids,
    
            ),
            consumptionService.getFluidsWithIncompleteData(
              allFluids,
    
              timePeriod.startDate
    
          setIncompleteDataFluids(fetchedIncompleteDataFluids)
    
    
          const fetchedPerformanceIndicators =
            await consumptionService.getPerformanceIndicators(
    
              resultFluids,
              comparisonTimePeriod
    
          if (fetchedPerformanceIndicators) {
            setPerformanceIndicators(fetchedPerformanceIndicators)
    
            setLoadingAnalysis(false)
    
            setAggregatedPerformanceIndicators(
              performanceIndicatorService.aggregatePerformanceIndicators(
                fetchedPerformanceIndicators
              )
            )
    
          if (resultFluids.length === 0 && allKonnectorDisconnected) {
            setOpenNoDataModal(true)
          }
    
          setFluidsWithData(resultFluids)
    
          setLoadingAnalysis(false)
    
        subscribed && populateData()
    
        return () => {
    
          subscribed = false
        }
    
        allKonnectorDisconnected,
    
        analysisMonth,
        consumptionService,
        performanceIndicatorService,
        saveLastScrollPosition,
      ])
    
        if (!isLoadingAnalysis) {
    
          const app = document.querySelector('.app-content')
          window.scrollTo(0, scrollPosition)
    
          app?.scrollTo(0, scrollPosition)
    
      }, [isLoadingAnalysis, scrollPosition])
    
          {isLoadingAnalysis && (
    
            <div className="loaderContainer">
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
              <Loader />
    
          <NoAnalysisModal open={openNoDataModal} onClose={setOpenNoDataModal} />
    
          {!isLoadingAnalysis && (
            <Fade in={!isLoadingAnalysis}>
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
              <div className="analysis-root">
    
                {displayNewsletterReminder && (
                  <div className="analysis-content">
                    <NewsletterReminder />
                  </div>
                )}
    
    
                {incompleteDataFluids.length !== 0 && (
                  <div className="analysis-content">
                    <IncompleteDataWarning
                      incompleteDataFluids={incompleteDataFluids}
                    />
                  </div>
                )}
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
                <div className="analysis-content">
                  <Comparison
    
                    fluidsWithData={fluidsWithData}
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
                    monthPerformanceIndicators={performanceIndicators}
    
                <div className="analysis-content">
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
                  <div className="card rich-card">
                    <TotalAnalysisChart fluidsWithData={fluidsWithData} />
                  </div>
                </div>
                <div className="analysis-content">
                  <div className="card rich-card">
                    <MaxConsumptionCard fluidsWithData={fluidsWithData} />
                  </div>
                </div>
                <div className="analysis-content">
                  <div className="card rich-card">
                    <ProfileComparator
                      aggregatedPerformanceIndicator={
                        aggregatedPerformanceIndicators
                      }
                      performanceIndicators={performanceIndicators}
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
                {fluidsWithData.includes(FluidType.ELECTRICITY) && (
                  <div className="analysis-content">
                    <div className="card">
                      <ElecHalfHourMonthlyAnalysis
                        perfIndicator={performanceIndicators[FluidType.ELECTRICITY]}
                      />
                    </div>
                  </div>
                )}
              </div>
            </Fade>
    
    export default MonthlyAnalysis