Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test adresse comparateur #938

Draft
wants to merge 16 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/Cities/City.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import styled from 'styled-components';

export const CityContainer = styled.div`
.sticky-form-title {
color: #2731b1;
color: black;
}
`;
export const Image = styled.img`
Expand Down
11 changes: 0 additions & 11 deletions src/components/Cities/Networks.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,3 @@ export const NetworkContainer = styled.div`
min-height: 500px;
}
`;

export const NetworkColumn = styled.div`
${({ theme }) => theme.media.md`
:nth-child(even) {
padding-left: 16px;
}
:nth-child(odd) {
padding-right: 16px;
}
`}
`;
10 changes: 5 additions & 5 deletions src/components/Cities/Networks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import WrappedText from '@components/WrappedText/WrappedText';
import { createMapConfiguration } from 'src/services/Map/map-configuration';
import { Network } from 'src/types/Summary/Network';

import { NetworkContainer, NetworkColumn } from './Networks.styles';
import { NetworkContainer } from './Networks.styles';

type NetworksData = {
isClassed: boolean;
Expand All @@ -20,7 +20,7 @@ type NetworksData = {
const Networks = ({ networksData, network, cityCoord }: { networksData: NetworksData; network?: Network; cityCoord: [number, number] }) => {
return (
<NetworkContainer>
<NetworkColumn className="fr-col-md-6 fr-col-12">
<div className="fr-col-md-6 fr-col-12">
{networksData.gestionnaires && <WrappedText body={`::arrow-item[${networksData.gestionnaires}]`} />}
{networksData.isClassed && (
<>
Expand Down Expand Up @@ -53,8 +53,8 @@ const Networks = ({ networksData, network, cityCoord }: { networksData: Networks
</Slice>
</>
)}
</NetworkColumn>
<NetworkColumn className="fr-col-md-6 fr-col-12">
</div>
<div className="fr-col-md-6 fr-col-12">
<Map
noPopup
withCenterPin
Expand All @@ -67,7 +67,7 @@ const Networks = ({ networksData, network, cityCoord }: { networksData: Networks
filtreIdentifiantReseau: networksData.identifiant ? [networksData.identifiant] : [],
})}
/>
</NetworkColumn>
</div>
</NetworkContainer>
);
};
Expand Down
21 changes: 1 addition & 20 deletions src/components/ComparateurPublicodes/ComparateurPublicodes.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { DottedName } from '@betagouv/france-chaleur-urbaine-publicodes';
import { fr } from '@codegouvfr/react-dsfr';
import Alert from '@codegouvfr/react-dsfr/Alert';
import ToggleSwitch from '@codegouvfr/react-dsfr/ToggleSwitch';
Expand All @@ -24,6 +23,7 @@ import { ObjectEntries } from '@utils/typescript';
import { FloatingButton, Results, Section, Simulator } from './ComparateurPublicodes.style';
import DebugDrawer from './DebugDrawer';
import Graph from './Graph';
import { addresseToPublicodesRules } from './mappings';
import ModesDeChauffageAComparer from './ModesDeChauffageAComparer';
import ParametresDesModesDeChauffage from './ParametresDesModesDeChauffage';
import ParametresDuBatimentGrandPublic from './ParametresDuBatimentGrandPublic';
Expand All @@ -38,25 +38,6 @@ type ComparateurPublicodesProps = React.HTMLAttributes<HTMLDivElement> & {

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

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'],
'caractéristique réseau de chaleur . part fixe': (infos) => infos.nearestReseauDeChaleur?.['PF%'],
'caractéristique réseau de chaleur . part variable': (infos) => infos.nearestReseauDeChaleur?.['PV%'],
'caractéristique réseau de chaleur . prix moyen': (infos) => infos.nearestReseauDeChaleur?.['PM'],
'caractéristique réseau de chaleur . production totale': (infos) => infos.nearestReseauDeChaleur?.['production_totale_MWh'],
'caractéristique réseau de chaleur . taux EnRR': (infos) => infos.nearestReseauDeChaleur?.['Taux EnR&R'],

'caractéristique réseau de froid . contenu CO2': (infos) => infos.nearestReseauDeFroid?.['contenu CO2'],
'caractéristique réseau de froid . contenu CO2 ACV': (infos) => infos.nearestReseauDeFroid?.['contenu CO2 ACV'],
'caractéristique réseau de froid . livraisons totales': (infos) => infos.nearestReseauDeFroid?.['livraisons_totale_MWh'],
'caractéristique réseau de froid . production totale': (infos) => infos.nearestReseauDeFroid?.['production_totale_MWh'],

'code département': (infos) => `'${infos.infosVille.departement_id}'`,
'température de référence chaud commune': (infos) => +infos.infosVille.temperature_ref_altitude_moyenne,
} as const satisfies Partial<Record<DottedName, (infos: LocationInfoResponse) => any>>;

const ComparateurPublicodes: React.FC<ComparateurPublicodesProps> = ({
children,
className,
Expand Down
124 changes: 124 additions & 0 deletions src/components/ComparateurPublicodes/ComparateurPublicodesWidget.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { fr } from '@codegouvfr/react-dsfr';
import React from 'react';

import { FormProvider } from '@components/form/publicodes/FormProvider';
import Heading from '@components/ui/Heading';
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, modesDeChauffage } from './mappings';
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, label }) => (type as any).includes('collectif') && !label.includes('PAC'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normalement on ne devrait pas avoir besoin du cast car il y a que 2 choix possibles. Mais c'est plus à voir avec la définition où il faudrait ajouter un type sur type.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oui le type est mal inféré et je n'ai pas trouvé comment faire, donc je veux bien ton aide

.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: 'Coût annuel chauffage',
flex: 2,
field: 'bilan',
renderCell: ({ value }) => value.toLocaleString('fr-FR', { currency: 'EUR', maximumFractionDigits: 0, style: 'currency' }),
},
{
headerName: 'Émissions 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{' '}
<a
href={`/outils/comparateur-performances?address=${encodeURIComponent(
address as string
)}&modes-de-chauffage=${encodeURIComponent(
modesDeChauffageToDisplay.map(({ label }) => label).join(',')
)}&tabId=modes-de-chauffage`}
target="_blank"
rel="noopener noreferrer"
>
comparateur complet
</a>
</div>
</FormProvider>
</div>
);
};

export default ComparateurPublicodesWidget;
2 changes: 1 addition & 1 deletion src/components/ComparateurPublicodes/DebugDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Link from '@components/ui/Link';
import { formatUnit } from '@helpers/publicodes/usePublicodesEngine';
import { clientConfig } from 'src/client-config';

import { modesDeChauffage } from './modes-de-chauffage';
import { modesDeChauffage } from './mappings';
import { type SimulatorEngine } from './useSimulatorEngine';

type DebugDrawerProps = {
Expand Down
2 changes: 1 addition & 1 deletion src/components/ComparateurPublicodes/Graph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { deepMergeObjects } from '@utils/core';
import cx from '@utils/cx';

import { ChartPlaceholder, GraphTooltip } from './ComparateurPublicodes.style';
import { modesDeChauffage } from './modes-de-chauffage';
import { modesDeChauffage } from './mappings';
import { Logos } from './Placeholder';
import { type SimulatorEngine } from './useSimulatorEngine';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import useArrayQueryState from '@hooks/useArrayQueryState';
import { LocationInfoResponse } from '@pages/api/location-infos';

import { Separator, Title } from './ComparateurPublicodes.style';
import { ModeDeChauffage, modesDeChauffage } from './modes-de-chauffage';
import { ModeDeChauffage, modesDeChauffage } from './mappings';
import { Disclaimer, modalDisclaimer } from './Placeholder';
import SelectClimatisation from './SelectClimatisation';
import SelectProductionECS from './SelectProductionECS';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { UrlStateAccordion as Accordion, UrlStateAccordion } from '@components/u
import useArrayQueryState from '@hooks/useArrayQueryState';

import { Title } from './ComparateurPublicodes.style';
import { ModeDeChauffage } from './modes-de-chauffage';
import { ModeDeChauffage } from './mappings';
import { type SimulatorEngine } from './useSimulatorEngine';

type ParametresDesModesDeChauffageFormProps = React.HTMLAttributes<HTMLDivElement> & {
Expand Down
Loading
Loading