Skip to content

Commit

Permalink
feat: show DGFIP address on owner edition modals
Browse files Browse the repository at this point in the history
  • Loading branch information
loicguillois committed Nov 13, 2024
1 parent e9a8aac commit 93ca6da
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 157 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,6 @@ function AddressSearchableSelectNext(props: Props) {
justifyContent="space-between"
sm
>
<Typography component="span">
Adresse (source : 
<a
href="https://adresse.data.gouv.fr/base-adresse-nationale#4.4/46.9/1.7"
rel="noreferrer"
target="_blank"
>
Base Adresse Nationale
</a>
)
</Typography>
<a
className={fr.cx('fr-link--sm')}
href="https://zerologementvacant.crisp.help/fr/article/comment-choisir-entre-ladresse-ban-et-ladresse-lovac-1ivvuep/?bust=1705403706774"
Expand All @@ -107,7 +96,7 @@ function AddressSearchableSelectNext(props: Props) {
</a>
</Grid>
}
hintText="Commencez à taper votre recherche dans le champ de saisi et choisissez une des options proposées dans la liste (exemple : 72 rue de Varenne, Paris)"
hintText="Cette adresse est la plus proche identifiée dans la Base Adresse Nationale. Ce format est recommandé pour vos courriers. Pour modifier l'adresse, commencez à saisir votre recherche et choisissez une des options dans la liste."
nativeInputProps={{
type: 'search',
placeholder: 'Rechercher une adresse',
Expand Down
10 changes: 6 additions & 4 deletions frontend/src/components/HousingList/HousingList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,12 @@ const HousingList = ({
const addressColumn = {
name: 'address',
headerRender: () => getSortButton('rawAddress', 'Adresse du logement'),
render: ({ id, rawAddress }: Housing) => (
<AppLink className="capitalize" isSimple to={`/logements/${id}`}>
{rawAddress.map((line) => capitalize(line)).join('\n')}
</AppLink>
render: ({ id, rawAddress, owner }: Housing) => (
<>
<AppLink className="capitalize" isSimple to={`/logements/${id}`}>
{rawAddress.map((line) => capitalize(line)).join('\n')}
</AppLink>
</>
)
};

Expand Down
124 changes: 13 additions & 111 deletions frontend/src/components/OwnerAddressEdition/OwnerAddressEdition.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import Button from '@codegouvfr/react-dsfr/Button';
import ButtonsGroup from '@codegouvfr/react-dsfr/ButtonsGroup';
import Typography from '@mui/material/Typography';
import { useState } from 'react';

import { Text } from '../_dsfr';
import { Address, isBanEligible } from '../../models/Address';
import { AddressSearchResult } from '../../services/address.service';
import AddressSearchableSelectNext from '../AddressSearchableSelect/AddressSearchableSelectNext';
import CallOut from '@codegouvfr/react-dsfr/CallOut';

interface Props {
banAddress?: Address;
Expand All @@ -15,66 +12,15 @@ interface Props {
help?: boolean;
rawAddress: string[];
onSelectAddress(address: AddressSearchResult | null): void;
warningVisible: boolean;
setWarningVisible: (visible: boolean) => void;
}

function OwnerAddressEdition(props: Props) {
const [searchAddressFromLovac, setSearchAddressFromLovac] = useState(false);
const [previousAddress, setPreviousAddress] = useState<AddressSearchResult>();

const [inputValue, setInputValue] = useState('');
const [open, setOpen] = useState(false);

if (searchAddressFromLovac) {
return (
<>
<AddressSearchableSelectNext
className="fr-mb-2w"
disabled={props.disabled}
value={props.banAddress ?? null}
inputValue={inputValue}
open={open}
onChange={(address) => {
props.onSelectAddress(
address
? {
...address,
banId: address.banId ?? '',
latitude: address.latitude ?? 0,
longitude: address.longitude ?? 0,
// Consider that the user has validated the address
score: 1
}
: null
);
}}
onInputChange={setInputValue}
onOpen={() => setOpen(true)}
onClose={() => setOpen(false)}
stateRelatedMessage={props.errorMessage}
/>
{previousAddress && (
<div className="fr-p-2w fr-mb-2w bg-bf975">
<Typography mb={2}>Adresse précédente :</Typography>
<Typography mb={2} sx={{ fontWeight: 900 }}>
{previousAddress.label}
</Typography>
<div className="align-right">
<Button
priority="secondary"
onClick={() => {
setSearchAddressFromLovac(false);
props.onSelectAddress(previousAddress);
}}
>
Appliquer
</Button>
</div>
</div>
)}
</>
);
}

return (
<>
<AddressSearchableSelectNext
Expand All @@ -101,60 +47,16 @@ function OwnerAddressEdition(props: Props) {
onOpen={() => setOpen(true)}
onClose={() => setOpen(false)}
/>
{props.banAddress && !isBanEligible(props.banAddress) && (
<div className="fr-mt-3w fr-p-2w bg-bf975">
<Text size="md" className="color-info-425 weight-900">
Amélioration possible
</Text>
<Typography mb={2}>
L’adresse issue de la <u>Base Adresse Nationale</u>, indiquée dans
le champ Adresse ci-dessus, semble différente de l’adresse issue de
la <u>DGFIP</u> : <b>{props.rawAddress.join(' ')}</b>
</Typography>
<Typography mb={2}>
Modifier le champ Adresse à partir de l’adresse DGFIP ?
</Typography>
<ButtonsGroup
buttons={[
{
children: 'Oui',
priority: 'secondary',
onClick: () => {
if (props.banAddress) {
setPreviousAddress({
...props.banAddress,
banId: props.banAddress.banId ?? '',
latitude: props.banAddress.latitude ?? 0,
longitude: props.banAddress.longitude ?? 0,
score: props.banAddress.score ?? Number.NaN
});
}
setInputValue(props.rawAddress.join(' '));
setSearchAddressFromLovac(true);
setOpen(true);
}
},
{
children: 'Non',
priority: 'secondary',
onClick: () => {
if (props.banAddress) {
props.onSelectAddress({
...props.banAddress,
banId: props.banAddress.banId ?? '',
latitude: props.banAddress.latitude ?? 0,
longitude: props.banAddress.longitude ?? 0,
// Consider that the user has validated the address
score: 1
});
}
}
}
]}
alignment="left"
inlineLayoutWhen="sm and up"
></ButtonsGroup>
</div>
{props.banAddress && props.warningVisible && !isBanEligible(props.banAddress) && (
<CallOut
className="fr-mt-3w"
buttonProps={{
children: 'Ignorer',
onClick: () => {props.setWarningVisible(false)}
}}
>
L'adresse de la Base Adresse Nationale diffère de celle de la DGFIP. Veuillez vérifier attentivement ces informations ou ignorez l’alerte.
</CallOut>
)}
</>
);
Expand Down
37 changes: 22 additions & 15 deletions frontend/src/components/OwnerCard/OwnerCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@ function OwnerCard(props: OwnerCardProps) {
const archivedOwners =
props.coOwners?.filter((owner) => owner.rank <= 0) ?? [];

const address: ReadonlyArray<ReactNode> = (
props.owner.banAddress
? formatAddress(props.owner.banAddress)
: props.owner.rawAddress
).map((line: string) => <Typography key={line}>{line}</Typography>);

return (
<Paper component="article" elevation={0} sx={{ padding: 3 }}>
<Grid component="header" container sx={{ mb: 1 }}>
Expand Down Expand Up @@ -64,6 +58,22 @@ function OwnerCard(props: OwnerCardProps) {
</Grid>
) : null}

<Grid xs={12}>
<LabelNext component="h3">
<span
className={fr.cx(
'fr-icon-bank-line',
'fr-icon--sm',
'fr-mr-1w'
)}
aria-hidden={true}
/>
Adresse fiscale (source: DGFIP)
</LabelNext>
<Typography>{props.owner.rawAddress ? props.owner.rawAddress : 'Inconnue'}</Typography>
</Grid>


<Grid xs={12}>
<LabelNext component="h3">
<span
Expand All @@ -74,27 +84,24 @@ function OwnerCard(props: OwnerCardProps) {
)}
aria-hidden={true}
/>
Adresse postale
Adresse postale (source: BAN)
</LabelNext>
<Typography>{address}</Typography>
<Typography>{props.owner.banAddress ? formatAddress(props.owner.banAddress) : 'Inconnue'}</Typography>
</Grid>

{!isBanEligible(props.owner.banAddress) && (

{props.owner.banAddress && !isBanEligible(props.owner.banAddress) && (
<Grid xs={12}>
<Alert
severity="info"
classes={{ title: fr.cx('fr-mb-2w') }}
title="Adresse à vérifier"
as="h3"
description={
<>
<Typography>
Cette adresse issue de la BAN est différente de l’adresse
fiscale.
L'adresse Base Adresse Nationale ne correspond pas à celle de la DGFIP.
</Typography>
<Typography>
Cliquez sur “Modifier” pour valider l’adresse que vous
souhaitez utiliser.
Nous vous recommandons de vérifier en cliquant sur "Modifier".
</Typography>
</>
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { fr } from '@codegouvfr/react-dsfr';
import Button from '@codegouvfr/react-dsfr/Button';
import { FormEvent, useState } from 'react';
import { object, string } from 'yup';
Expand All @@ -10,6 +11,8 @@ import { Owner } from '../../models/Owner';
import { banAddressValidator, useForm } from '../../hooks/useForm';
import { useUpdateOwnerMutation } from '../../services/owner.service';
import { useNotification } from '../../hooks/useNotification';
import { Grid, Typography } from '@mui/material';
import LabelNext from '../Label/LabelNext';

interface Props {
className?: string;
Expand All @@ -19,24 +22,24 @@ interface Props {
function OwnerEditionSideMenu(props: Props) {
const { active, setActive, toggle } = useToggle();

const storedWarningVisible = localStorage.getItem('OwnerEdition.warningVisible');
const [warningVisible, setWarningVisible] = useState(storedWarningVisible === null || storedWarningVisible === 'true');

const shape = {
fullName: string().optional(),
address: banAddressValidator.optional(),
additionalAddress: string().optional().nullable()
};
type FormShape = typeof shape;
const schema = object(shape);

const [fullName, setFullName] = useState(props.owner.fullName);
const [address, setAddress] = useState(props.owner.banAddress);
const [additionalAddress, setAdditionalAddress] = useState(
props.owner.additionalAddress ?? ''
);
const formId = 'owner-edition-form';
const form = useForm(schema, {
address,
additionalAddress,
fullName
additionalAddress
});

function open(): void {
Expand All @@ -50,11 +53,11 @@ function OwnerEditionSideMenu(props: Props) {
const [updateOwner, mutation] = useUpdateOwnerMutation();

async function save(event: FormEvent): Promise<void> {
localStorage.setItem('OwnerEditionSideMenu.warningVisible', warningVisible.toString());
event.preventDefault();
await form.validate(async () => {
await updateOwner({
...props.owner,
fullName,
banAddress: address,
additionalAddress
}).unwrap();
Expand Down Expand Up @@ -97,20 +100,43 @@ function OwnerEditionSideMenu(props: Props) {
title="Modifier les informations du propriétaire"
content={
<form id={formId} className="fr-px-6w">
<AppTextInput<FormShape>
inputForm={form}
inputKey="fullName"
label="Nom prénom"
value={fullName}
onChange={(e) => setFullName(e.target.value)}
/>
<section className="fr-mb-3w">
<Grid>
<LabelNext component="h3">
<span
className={fr.cx(
'fr-icon-bank-line',
'fr-icon--sm',
'fr-mr-1w'
)}
aria-hidden={true}
/>
Adresse fiscale (source: DGFIP)
</LabelNext>
<Grid>
<span className='fr-hint-text'>Cette adresse est issue du fichier LOVAC, récupérée via le fichier 1767BIS-COM. Celle-ci n’est pas modifiable.</span>
<Typography>{props.owner.rawAddress ? props.owner.rawAddress : 'Inconnue'}</Typography>
</Grid>
</Grid>
<section className="fr-mb-3w fr-mt-3w">
<LabelNext component="h3">
<span
className={fr.cx(
'fr-icon-home-4-line',
'fr-icon--sm',
'fr-mr-1w'
)}
aria-hidden={true}
/>
Adresse postale (source: Base Adresse Nationale)
</LabelNext>
<OwnerAddressEdition
banAddress={address}
errorMessage={form.message('address')}
help={false}
rawAddress={props.owner.rawAddress}
onSelectAddress={(value) => setAddress(value ?? undefined)}
warningVisible={warningVisible}
setWarningVisible={setWarningVisible}
/>
</section>
<AppTextInput<FormShape>
Expand Down
Loading

0 comments on commit 93ca6da

Please sign in to comment.