Skip to content

Commit

Permalink
Affiche le comparateur uniquement pour le Collectif
Browse files Browse the repository at this point in the history
  • Loading branch information
martinratinaud committed Nov 20, 2024
1 parent 6f41a59 commit c3433c1
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type ComparateurPublicodesProps = React.HTMLAttributes<HTMLDivElement> & {

export type TabId = (typeof simulatorTabs)[number]['tabId'];

const addresseToPublicodesRules = {
export const addresseToPublicodesRules = {
'caractéristique réseau de chaleur . contenu CO2': (infos) => infos.nearestReseauDeChaleur?.['contenu CO2'],
'caractéristique réseau de chaleur . contenu CO2 ACV': (infos) => infos.nearestReseauDeChaleur?.['contenu CO2 ACV'],
'caractéristique réseau de chaleur . livraisons totales': (infos) => infos.nearestReseauDeChaleur?.['livraisons_totale_MWh'],
Expand Down
116 changes: 116 additions & 0 deletions src/components/ComparateurPublicodes/ComparateurPublicodesWidget.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { fr } from '@codegouvfr/react-dsfr';
import React from 'react';

import { FormProvider } from '@components/form/publicodes/FormProvider';
import Heading from '@components/ui/Heading';
import Link from '@components/ui/Link';
import { Table, type ColumnDef } from '@components/ui/Table';
import { LocationInfoResponse } from '@pages/api/location-infos';
import { postFetchJSON } from '@utils/network';
import { ObjectEntries } from '@utils/typescript';

import { addresseToPublicodesRules } from './ComparateurPublicodes';
import { modesDeChauffage } from './modes-de-chauffage';
import { simulatorTabs } from './Placeholder';
import useSimulatorEngine from './useSimulatorEngine';

type ComparateurPublicodesWidgetProps = React.HTMLAttributes<HTMLDivElement> & {
coords?: [longitude?: number, latitude?: number];
city?: string;
cityCode?: string;
address?: string;
};

export type TabId = (typeof simulatorTabs)[number]['tabId'];
const ComparateurPublicodesWidget: React.FC<ComparateurPublicodesWidgetProps> = ({
children,
coords,
city,
cityCode,
address,
...props
}) => {
const engine = useSimulatorEngine();

React.useEffect(() => {
if (!coords || !city || !cityCode) {
return;
}
const loadInfos = async () => {
const infos: LocationInfoResponse = await postFetchJSON('/api/location-infos', {
lon: coords[0],
lat: coords[1],
city,
cityCode,
});

engine.setSituation(
ObjectEntries(addresseToPublicodesRules).reduce(
(acc, [key, infoGetter]) => ({
...acc,
[key]: infoGetter(infos) ?? null,
}),
{}
)
);
};
loadInfos();
}, [coords, city, cityCode]);

const modesDeChauffageToDisplay = modesDeChauffage
.filter(({ type }) => (type as any).includes('collectif'))
.map((typeInstallation) => ({
id: typeInstallation.label,
label: typeInstallation.label,
bilan: engine.getFieldAsNumber(`Bilan x ${typeInstallation.coutPublicodeKey} . total avec aides`),
emissionsCO2: engine.getFieldAsNumber(`env . Installation x ${typeInstallation.emissionsCO2PublicodesKey} . Total`),
}))
.sort((a, b) => a.bilan - b.bilan);

const columns: ColumnDef<{ label: string; bilan: number }>[] = [
{
headerName: 'Mode de chauffage',
field: 'label',
flex: 3,
},
{
headerName: 'Cout annuel chauffage',
flex: 2,
field: 'bilan',
renderCell: ({ value }) => value.toLocaleString('fr-FR', { currency: 'EUR', maximumFractionDigits: 0, style: 'currency' }),
},
{
headerName: 'Emissions CO2',
flex: 2,
field: 'emissionsCO2',
renderCell: ({ value }) => `${value.toLocaleString('fr-FR', { maximumFractionDigits: 0 })} kgCO2e`,
},
];

return (
<div {...props}>
<FormProvider engine={engine}>
<Heading as="h2" size="h4">
Comparaison des modes de chauffage
</Heading>
<Table
style={{ width: '100%' }}
getRowClassName={({ id }) => (id === 'Réseau de chaleur' ? fr.cx('fr-text--bold') : '')}
columns={columns}
hideFooter
rows={modesDeChauffageToDisplay}
autosizeOnMount
disableRowSelectionOnClick
autoHeight
pageSize={20}
/>
<div className={fr.cx('fr-text--sm', 'fr-mt-2w')} style={{ textAlign: 'right', fontStyle: 'italic' }}>
Accéder au{' '}
<Link href={`/outils/comparateur-performances?address=${encodeURIComponent(address as string)}`}>comparateur complet</Link>
</div>
</FormProvider>
</div>
);
};

export default ComparateurPublicodesWidget;
16 changes: 16 additions & 0 deletions src/components/ComparateurPublicodes/modes-de-chauffage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,111 +5,127 @@ export const modesDeChauffage = [
coutPublicodeKey: 'Réseaux de chaleur',
reversible: false,
tertiaire: true,
type: ['individuel', 'collectif'],
},
{
label: 'Poêle à granulés individuel',
emissionsCO2PublicodesKey: 'Poêle à granulés indiv x Individuel',
coutPublicodeKey: 'Poêle à granulés indiv',
reversible: false,
tertiaire: false,
type: ['individuel'],
},
{
label: 'Chaudière à granulés collective',
emissionsCO2PublicodesKey: 'Chaudière à granulés coll x Collectif',
coutPublicodeKey: 'Chaudière à granulés coll',
reversible: false,
tertiaire: true,
type: ['collectif'],
},
{
label: 'Gaz à condensation individuel',
emissionsCO2PublicodesKey: 'Gaz indiv avec cond x Individuel',
coutPublicodeKey: 'Gaz indiv avec cond',
reversible: false,
tertiaire: false,
type: ['individuel'],
},
{
label: 'Gaz sans condensation individuel',
emissionsCO2PublicodesKey: 'Gaz indiv sans cond x Individuel',
coutPublicodeKey: 'Gaz indiv sans cond',
reversible: false,
tertiaire: false,
type: ['individuel'],
},
{
label: 'Gaz à condensation collectif',
emissionsCO2PublicodesKey: 'Gaz coll avec cond x Collectif',
coutPublicodeKey: 'Gaz coll avec cond',
reversible: false,
tertiaire: true,
type: ['collectif'],
},
{
label: 'Gaz sans condensation collectif',
emissionsCO2PublicodesKey: 'Gaz coll sans cond x Collectif',
coutPublicodeKey: 'Gaz coll sans cond',
reversible: false,
tertiaire: true,
type: ['collectif'],
},
{
label: 'Fioul individuel',
emissionsCO2PublicodesKey: 'Fioul indiv x Individuel',
coutPublicodeKey: 'Fioul indiv',
reversible: false,
tertiaire: false,
type: ['individuel'],
},
{
label: 'Fioul collectif',
emissionsCO2PublicodesKey: 'Fioul coll x Collectif',
coutPublicodeKey: 'Fioul coll',
reversible: false,
tertiaire: true,
type: ['collectif'],
},
{
label: 'PAC air/air individuelle',
emissionsCO2PublicodesKey: 'PAC air-air x Individuel',
coutPublicodeKey: 'PAC air-air indiv',
reversible: true,
tertiaire: false,
type: ['individuel'],
},
{
label: 'PAC air/air collective',
emissionsCO2PublicodesKey: 'PAC air-air x Collectif',
coutPublicodeKey: 'PAC air-air coll',
reversible: true,
tertiaire: true,
type: ['collectif'],
},
{
label: 'PAC air/eau individuelle',
emissionsCO2PublicodesKey: 'PAC air-eau x Individuel',
coutPublicodeKey: 'PAC air-eau indiv',
reversible: true,
tertiaire: false,
type: ['individuel'],
},
{
label: 'PAC air/eau collective',
emissionsCO2PublicodesKey: 'PAC air-eau x Collectif',
coutPublicodeKey: 'PAC air-eau coll',
reversible: true,
tertiaire: true,
type: ['collectif'],
},
{
label: 'PAC eau/eau individuelle',
emissionsCO2PublicodesKey: 'PAC eau-eau x Individuel',
coutPublicodeKey: 'PAC eau-eau indiv',
reversible: false,
tertiaire: false,
type: ['individuel'],
},
{
label: 'PAC eau/eau collective',
emissionsCO2PublicodesKey: 'PAC eau-eau x Collectif',
coutPublicodeKey: 'PAC eau-eau coll',
reversible: false,
tertiaire: true,
type: ['collectif'],
},
{
label: 'Radiateur électrique individuel',
emissionsCO2PublicodesKey: 'Radiateur électrique x Individuel',
coutPublicodeKey: 'Radiateur électrique',
reversible: false,
tertiaire: true,
type: ['individuel'],
},
] as const;

Expand Down
25 changes: 25 additions & 0 deletions src/components/EligibilityForm/EligibilityFormContact.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Alert } from '@codegouvfr/react-dsfr/Alert';
import dynamic from 'next/dynamic';
import Image from 'next/image';
import { useCallback, useMemo, useState } from 'react';

import Map from '@components/Map/Map';
import MarkdownWrapper from '@components/MarkdownWrapper';
import Box from '@components/ui/Box';
import Heading from '@components/ui/Heading';
import Link from '@components/ui/Link';
import { getReadableDistance } from 'src/services/Map/distance';
import { createMapConfiguration } from 'src/services/Map/map-configuration';
Expand All @@ -14,6 +16,20 @@ import { ContactFormInfos } from 'src/types/Summary/Demand';
import { ContactForm, ContactFormContentWrapper, ContactFormResultMessage, ContactFormWrapper, ContactMapResult } from './components';
import { bordeauxMetropoleCityCodes, getEligibilityResult } from './EligibilityResults';

const ComparateurPublicodesWidget = dynamic(() => import('@components/ComparateurPublicodes/ComparateurPublicodesWidget'), {
ssr: false,
loading: () => (
<div className="fr-mt-5w">
<Heading as="h2" size="h4">
Comparaison des modes de chauffage
</Heading>
<Box textAlign="center" p="5w" fontSize={'24px'} fontWeight="bold">
Chargement en cours...
</Box>
</div>
),
});

type EligibilityFormContactType = {
addressData: AddressDataType;
cardMode?: boolean;
Expand Down Expand Up @@ -154,6 +170,15 @@ const EligibilityFormContact = ({ addressData, cardMode, onSubmit }: Eligibility
/>
)
)}
{process.env.NEXT_PUBLIC_FLAG_ENABLE_COMPARATEUR === 'true' && addressData.heatingType === 'collectif' && (
<ComparateurPublicodesWidget
className="fr-mt-5w"
coords={[addressData?.coords?.lon, addressData?.coords?.lat]}
city={addressData.geoAddress?.properties.city}
cityCode={addressData.geoAddress?.properties.citycode}
address={addressData.geoAddress?.properties.label}
/>
)}
</ContactFormContentWrapper>
<ContactFormContentWrapper>
{!cardMode && (
Expand Down

0 comments on commit c3433c1

Please sign in to comment.