Newer
Older
import {
Accordion,
AccordionDetails,
AccordionSummary,
} from '@material-ui/core'
import Button from '@material-ui/core/Button'
import chevronDown from 'assets/icons/ico/chevron-down.svg'
import ProfileEditIcon from 'assets/icons/ico/profile-edit.svg'
import AnalysisIcon from 'assets/icons/visu/analysis/analysis.svg'
import PlaceHolderIcon from 'assets/icons/visu/analysis/no-profile-placeholder.svg'
import StyledIcon from 'components/CommonKit/Icon/StyledIcon'
import Loader from 'components/Loader/Loader'
import { Client, useClient } from 'cozy-client'
import { useI18n } from 'cozy-ui/transpiled/react/I18n'
import Icon from 'cozy-ui/transpiled/react/Icon'
import { FluidType } from 'enum/fluid.enum'
import { DateTime } from 'luxon'
import { MonthlyForecast, ProfileType } from 'models/profileType.model'
import React, { useCallback, useEffect, useState } from 'react'
import { useSelector } from 'react-redux'
import { useNavigate } from 'react-router-dom'
import ProfileTypeService from 'services/profileType.service'
import ProfileTypeEntityService from 'services/profileTypeEntity.service'
import { AppStore } from 'store'
import AnalysisConsumptionRow from './AnalysisConsumptionRow'
interface AnalysisConsumptionProps {
aggregatedPerformanceIndicator: PerformanceIndicator
performanceIndicators: PerformanceIndicator[]

Guilhem CARRON
committed
analysisDate: DateTime
}
const AnalysisConsumption: React.FC<AnalysisConsumptionProps> = ({
aggregatedPerformanceIndicator,

Guilhem CARRON
committed
analysisDate,
}: AnalysisConsumptionProps) => {
const { t } = useI18n()
const navigate = useNavigate()

Guilhem CARRON
committed
const client: Client = useClient()
const userPriceConsumption: number = aggregatedPerformanceIndicator.value || 0
const {
global: { fluidTypes },
profile,
} = useSelector((state: AppStore) => state.ecolyo)
const [homePriceConsumption, setHomePriceConsumption] = useState<number>(0)
const [forecast, setForecast] = useState<MonthlyForecast | null>(null)
const [isLoading, setIsLoading] = useState<boolean>(true)
const [activeAverageHome, setActiveAverageHome] = useState<boolean>(false)
const toggleAccordion = () => {
setActiveAverageHome(prev => !prev)
if (!activeAverageHome) {
setTimeout(() => {
const content = document.querySelector('.consumption-electricity')
if (content) {
content.scrollIntoView({
behavior: 'smooth',
block: 'start',
})
}
}, 300)
}
}
// Disconnected + empty fluids to show in AnalysisConsumptionRow
const disconnectedFluidTypes: FluidType[] = [
FluidType.ELECTRICITY,
FluidType.WATER,
FluidType.GAS,
].filter(fluidType => !fluidTypes.includes(fluidType))
const emptyFluidTypes: FluidType[] = []
for (let i = 0; i < performanceIndicators.length; i++) {
if (!performanceIndicators[i]?.value && fluidTypes[i]) {
emptyFluidTypes.push(fluidTypes[i])
}
}
const getTotalValueWithConnectedFluids = useCallback(
(monthlyForecast: MonthlyForecast) => {
if (fluidTypes.length === 3) {
setHomePriceConsumption(monthlyForecast.totalValue)
} else {
let totalPrice = 0
fluidTypes.forEach(fluid => {
if (monthlyForecast.fluidForecast[fluid].value)
totalPrice += monthlyForecast.fluidForecast[fluid].value
setHomePriceConsumption(totalPrice)
navigate('/profileType')
useEffect(() => {
let subscribed = true
async function loadAverageConsumption() {
const profileTypeEntityService = new ProfileTypeEntityService(client)
const profileType: ProfileType | null =
await profileTypeEntityService.getProfileType(
analysisDate.minus({ month: 1 }).startOf('month')
)
if (profileType !== null) {
const profileTypeService: ProfileTypeService = new ProfileTypeService(
profileType,
client,
analysisDate.year
)
const monthlyForecast: MonthlyForecast =
await profileTypeService.getMonthlyForecast(
analysisDate.minus({ month: 1 }).startOf('month').month
)
if (subscribed) {
setForecast(monthlyForecast)
if (monthlyForecast) {
getTotalValueWithConnectedFluids(monthlyForecast)
}
return () => {
subscribed = false
}
}, [
profile.monthlyAnalysisDate.month,
getTotalValueWithConnectedFluids,

Guilhem CARRON
committed
client,
analysisDate.month,

Guilhem CARRON
committed
analysisDate,
<div className="no-profile">
<div className="text-16-normal">
{t('analysis.approximative_description')}
</div>
<Button
aria-label={t('analysis.accessibility.button_go_to_profil')}
onClick={goToForm}
classes={{
root: 'btn-highlight',
label: 'text-18-bold',
}}
>
{t('analysis.accessibility.button_go_to_profil')}
</Button>
<Icon
icon={PlaceHolderIcon}
width="100%"
height="60%"
alt="pas de profil remplis"
/>
</div>
)
<div className="analysis-graph">
{isLoading ? (
<div className="loader-container">
<Loader color="elec" />
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
) : (
<>
<div className="consumption-title text-20-bold">
<div className="user-title">{t('analysis.user_consumption')}</div>
<div className={`average-title`}>{t(`analysis.comparison`)}</div>
</div>
<div className="consumption-price">
<AnalysisConsumptionRow
fluid={FluidType.MULTIFLUID}
userPriceConsumption={userPriceConsumption}
homePriceConsumption={homePriceConsumption}
performanceValue={null}
forecast={forecast}
connected={fluidTypes.length > 0}
noData={false}
/>
</div>
{fluidTypes.map(
fluid =>
Boolean(performanceIndicators[fluid]?.value) && (
<AnalysisConsumptionRow
key={fluid}
fluid={fluid}
userPriceConsumption={userPriceConsumption}
homePriceConsumption={homePriceConsumption}
performanceValue={performanceIndicators[fluid].value}
forecast={forecast}
connected={true}
noData={false}
/>
)
)}
{fluidTypes.length < 3 && <hr className="consumption-sep" />}
{disconnectedFluidTypes.map(fluid => (
<AnalysisConsumptionRow
key={fluid}
fluid={fluid}
userPriceConsumption={userPriceConsumption}
homePriceConsumption={homePriceConsumption}
performanceValue={null}
forecast={forecast}
connected={false}
noData={false}
/>
))}
{emptyFluidTypes.map(fluid => (
<AnalysisConsumptionRow
key={fluid}
fluid={fluid}
userPriceConsumption={userPriceConsumption}
homePriceConsumption={homePriceConsumption}
performanceValue={null}
forecast={forecast}
connected={false}
noData={true}
/>
))}
<Accordion
expanded={activeAverageHome}
onChange={toggleAccordion}
<AccordionSummary
aria-label={t(
'profile_type.accessibility.button_toggle_average_home'
)}
expandIcon={
<Icon icon={chevronDown} size={16} className="accordion-icon" />
}
root: 'expansion-panel-summary',
content: 'expansion-panel-content',
<div className="accordion-title accordion-title">
{t('analysis.average_home')}
</div>
</AccordionSummary>
<AccordionDetails
classes={{
root: 'expansion-panel-details',
}}
>
<span className="accordion-desc text-16-normal">
{t('analysis.average_home_description')}
</span>
</AccordionDetails>
</Accordion>
</>
)}
</div>
<>
<div className="status-header">
<div>
<StyledIcon icon={AnalysisIcon} size={44} />
<p className="text-16-normal">{t('analysis.compare.title')}</p>
</div>
{profile.isProfileTypeCompleted && (
<Button
aria-label={t('analysis.accessibility.button_go_to_profil')}
root: 'btn-secondary-negative',
label: 'text-16-normal',
<StyledIcon icon={ProfileEditIcon} size={40} />
)}
</div>
<div className="analysis-graph">
{!profile.isProfileTypeCompleted && profileNotCompleted}
{profile.isProfileTypeCompleted && Consumption}
)
}
export default AnalysisConsumption