diff --git a/src/api/signalement/index.ts b/src/api/signalement/index.ts index 66327d3..908af6d 100644 --- a/src/api/signalement/index.ts +++ b/src/api/signalement/index.ts @@ -8,23 +8,27 @@ export { OpenAPI } from './core/OpenAPI'; export type { OpenAPIConfig } from './core/OpenAPI'; export type { Author } from './models/Author'; -export type { AuthorDTO } from './models/AuthorDTO'; -export type { ChangesRequested } from './models/ChangesRequested'; +export type { AuthorInput } from './models/AuthorInput'; export type { Client } from './models/Client'; export type { CreateClientDTO } from './models/CreateClientDTO'; export { CreateSignalementDTO } from './models/CreateSignalementDTO'; export { CreateSourceDTO } from './models/CreateSourceDTO'; +export type { DeleteNumeroChangesRequestedDTO } from './models/DeleteNumeroChangesRequestedDTO'; export { ExistingLocation } from './models/ExistingLocation'; export { ExistingNumero } from './models/ExistingNumero'; export { ExistingToponyme } from './models/ExistingToponyme'; export { ExistingVoie } from './models/ExistingVoie'; -export type { ObjectId } from './models/ObjectId'; +export type { NumeroChangesRequestedDTO } from './models/NumeroChangesRequestedDTO'; export type { PaginatedSignalementsDTO } from './models/PaginatedSignalementsDTO'; export type { Point } from './models/Point'; export { Position } from './models/Position'; +export type { PositionCoordinatesDTO } from './models/PositionCoordinatesDTO'; +export { PositionDTO } from './models/PositionDTO'; export { Signalement } from './models/Signalement'; export { Source } from './models/Source'; +export type { ToponymeChangesRequestedDTO } from './models/ToponymeChangesRequestedDTO'; export { UpdateSignalementDTO } from './models/UpdateSignalementDTO'; +export type { VoieChangesRequestedDTO } from './models/VoieChangesRequestedDTO'; export { ClientsService } from './services/ClientsService'; export { SignalementsService } from './services/SignalementsService'; diff --git a/src/api/signalement/models/AuthorDTO.ts b/src/api/signalement/models/AuthorInput.ts similarity index 75% rename from src/api/signalement/models/AuthorDTO.ts rename to src/api/signalement/models/AuthorInput.ts index 81102c5..6369241 100644 --- a/src/api/signalement/models/AuthorDTO.ts +++ b/src/api/signalement/models/AuthorInput.ts @@ -2,8 +2,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -export type AuthorDTO = { +export type AuthorInput = { email?: string | null; - captchaToken: string; }; diff --git a/src/api/signalement/models/ChangesRequested.ts b/src/api/signalement/models/ChangesRequested.ts deleted file mode 100644 index 8462f81..0000000 --- a/src/api/signalement/models/ChangesRequested.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* generated using openapi-typescript-codegen -- do not edit */ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import type { Position } from './Position'; -export type ChangesRequested = { - numero?: number | null; - suffixe?: string | null; - positions?: Array | null; - parcelles?: Array | null; - nomVoie?: string | null; - nom?: string | null; - comment?: string | null; -}; - diff --git a/src/api/signalement/models/Client.ts b/src/api/signalement/models/Client.ts index 2683a42..c07fc54 100644 --- a/src/api/signalement/models/Client.ts +++ b/src/api/signalement/models/Client.ts @@ -2,12 +2,12 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { ObjectId } from './ObjectId'; export type Client = { - _id: ObjectId; - _createdAt: number; - _updatedAt: number; - _deletedAt?: number | null; + id: string; + createdAt: string; + updatedAt: string; + deletedAt?: string | null; nom: string; + processedSignalements?: Array | null; }; diff --git a/src/api/signalement/models/CreateSignalementDTO.ts b/src/api/signalement/models/CreateSignalementDTO.ts index 26616fe..6b5986c 100644 --- a/src/api/signalement/models/CreateSignalementDTO.ts +++ b/src/api/signalement/models/CreateSignalementDTO.ts @@ -2,14 +2,20 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { AuthorDTO } from './AuthorDTO'; -import type { ExistingLocation } from './ExistingLocation'; +import type { AuthorInput } from './AuthorInput'; +import type { DeleteNumeroChangesRequestedDTO } from './DeleteNumeroChangesRequestedDTO'; +import type { ExistingNumero } from './ExistingNumero'; +import type { ExistingToponyme } from './ExistingToponyme'; +import type { ExistingVoie } from './ExistingVoie'; +import type { NumeroChangesRequestedDTO } from './NumeroChangesRequestedDTO'; +import type { ToponymeChangesRequestedDTO } from './ToponymeChangesRequestedDTO'; +import type { VoieChangesRequestedDTO } from './VoieChangesRequestedDTO'; export type CreateSignalementDTO = { codeCommune: string; type: CreateSignalementDTO.type; - author?: AuthorDTO | null; - existingLocation?: ExistingLocation | null; - changesRequested: Record | null; + author?: AuthorInput | null; + existingLocation?: (ExistingNumero | ExistingVoie | ExistingToponyme) | null; + changesRequested: (NumeroChangesRequestedDTO | DeleteNumeroChangesRequestedDTO | ToponymeChangesRequestedDTO | VoieChangesRequestedDTO) | null; }; export namespace CreateSignalementDTO { export enum type { diff --git a/src/api/signalement/models/ObjectId.ts b/src/api/signalement/models/DeleteNumeroChangesRequestedDTO.ts similarity index 66% rename from src/api/signalement/models/ObjectId.ts rename to src/api/signalement/models/DeleteNumeroChangesRequestedDTO.ts index 870bb6a..466d4f8 100644 --- a/src/api/signalement/models/ObjectId.ts +++ b/src/api/signalement/models/DeleteNumeroChangesRequestedDTO.ts @@ -2,6 +2,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -export type ObjectId = { +export type DeleteNumeroChangesRequestedDTO = { + comment: string; }; diff --git a/src/api/signalement/models/NumeroChangesRequestedDTO.ts b/src/api/signalement/models/NumeroChangesRequestedDTO.ts new file mode 100644 index 0000000..e07bb04 --- /dev/null +++ b/src/api/signalement/models/NumeroChangesRequestedDTO.ts @@ -0,0 +1,14 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { PositionDTO } from './PositionDTO'; +export type NumeroChangesRequestedDTO = { + numero: number; + suffixe?: string; + nomVoie: string; + parcelles: Array; + positions: Array; + comment?: string | null; +}; + diff --git a/src/api/signalement/models/PaginatedSignalementsDTO.ts b/src/api/signalement/models/PaginatedSignalementsDTO.ts index f9d79f2..1991095 100644 --- a/src/api/signalement/models/PaginatedSignalementsDTO.ts +++ b/src/api/signalement/models/PaginatedSignalementsDTO.ts @@ -2,9 +2,8 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { Signalement } from './Signalement'; export type PaginatedSignalementsDTO = { - data: Array; + data: Array; page: number; limit: number; total: number; diff --git a/src/api/signalement/models/PositionCoordinatesDTO.ts b/src/api/signalement/models/PositionCoordinatesDTO.ts new file mode 100644 index 0000000..e20b79e --- /dev/null +++ b/src/api/signalement/models/PositionCoordinatesDTO.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type PositionCoordinatesDTO = { + coordinates: Array; + type: string; +}; + diff --git a/src/api/signalement/models/PositionDTO.ts b/src/api/signalement/models/PositionDTO.ts new file mode 100644 index 0000000..fe95916 --- /dev/null +++ b/src/api/signalement/models/PositionDTO.ts @@ -0,0 +1,23 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { PositionCoordinatesDTO } from './PositionCoordinatesDTO'; +export type PositionDTO = { + point: PositionCoordinatesDTO; + type: PositionDTO.type; +}; +export namespace PositionDTO { + export enum type { + ENTR_E = 'entrée', + B_TIMENT = 'bâtiment', + CAGE_D_ESCALIER = 'cage d’escalier', + LOGEMENT = 'logement', + SERVICE_TECHNIQUE = 'service technique', + D_LIVRANCE_POSTALE = 'délivrance postale', + PARCELLE = 'parcelle', + SEGMENT = 'segment', + INCONNUE = 'inconnue', + } +} + diff --git a/src/api/signalement/models/Signalement.ts b/src/api/signalement/models/Signalement.ts index a28addd..a06314c 100644 --- a/src/api/signalement/models/Signalement.ts +++ b/src/api/signalement/models/Signalement.ts @@ -3,25 +3,27 @@ /* tslint:disable */ /* eslint-disable */ import type { Author } from './Author'; -import type { ChangesRequested } from './ChangesRequested'; import type { Client } from './Client'; +import type { DeleteNumeroChangesRequestedDTO } from './DeleteNumeroChangesRequestedDTO'; import type { ExistingNumero } from './ExistingNumero'; import type { ExistingToponyme } from './ExistingToponyme'; import type { ExistingVoie } from './ExistingVoie'; -import type { ObjectId } from './ObjectId'; +import type { NumeroChangesRequestedDTO } from './NumeroChangesRequestedDTO'; import type { Source } from './Source'; +import type { ToponymeChangesRequestedDTO } from './ToponymeChangesRequestedDTO'; +import type { VoieChangesRequestedDTO } from './VoieChangesRequestedDTO'; export type Signalement = { - _id: ObjectId; - _createdAt: number; - _updatedAt: number; - _deletedAt?: number | null; + id: string; + createdAt: string; + updatedAt: string; + deletedAt?: string | null; codeCommune: string; type: Signalement.type; author?: Author | null; - source: Source; existingLocation?: (ExistingNumero | ExistingVoie | ExistingToponyme) | null; - changesRequested: ChangesRequested; + changesRequested: (NumeroChangesRequestedDTO | DeleteNumeroChangesRequestedDTO | ToponymeChangesRequestedDTO | VoieChangesRequestedDTO); status?: Signalement.status | null; + source: Source; processedBy?: Client | null; }; export namespace Signalement { diff --git a/src/api/signalement/models/Source.ts b/src/api/signalement/models/Source.ts index 1c0a90c..fc89213 100644 --- a/src/api/signalement/models/Source.ts +++ b/src/api/signalement/models/Source.ts @@ -2,14 +2,14 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { ObjectId } from './ObjectId'; export type Source = { - _id: ObjectId; - _createdAt: number; - _updatedAt: number; - _deletedAt?: number | null; + id: string; + createdAt: string; + updatedAt: string; + deletedAt?: string | null; nom: string; type: Source.type; + signalements?: Array | null; }; export namespace Source { export enum type { diff --git a/src/api/signalement/models/ToponymeChangesRequestedDTO.ts b/src/api/signalement/models/ToponymeChangesRequestedDTO.ts new file mode 100644 index 0000000..01d2562 --- /dev/null +++ b/src/api/signalement/models/ToponymeChangesRequestedDTO.ts @@ -0,0 +1,12 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { PositionDTO } from './PositionDTO'; +export type ToponymeChangesRequestedDTO = { + nom: string; + parcelles: Array; + positions: Array; + comment?: string | null; +}; + diff --git a/src/api/signalement/models/VoieChangesRequestedDTO.ts b/src/api/signalement/models/VoieChangesRequestedDTO.ts new file mode 100644 index 0000000..ea4d91e --- /dev/null +++ b/src/api/signalement/models/VoieChangesRequestedDTO.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type VoieChangesRequestedDTO = { + nom: string; + comment?: string | null; +}; + diff --git a/src/api/signalement/services/SourcesService.ts b/src/api/signalement/services/SourcesService.ts index 9d04cd5..66bceb9 100644 --- a/src/api/signalement/services/SourcesService.ts +++ b/src/api/signalement/services/SourcesService.ts @@ -58,4 +58,21 @@ export class SourcesService { }, }); } + /** + * Get source by token + * @param token + * @returns Source + * @throws ApiError + */ + public static getSourceByToken( + token: string, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/sources/token/{token}', + path: { + 'token': token, + }, + }); + } } diff --git a/src/composants/authentification/AuthentificationModal.tsx b/src/composants/authentification/AuthentificationModal.tsx new file mode 100644 index 0000000..2977a83 --- /dev/null +++ b/src/composants/authentification/AuthentificationModal.tsx @@ -0,0 +1,84 @@ +import React, { useContext, useState } from 'react' +import Modal from '../common/Modal' +import styled from 'styled-components' +import SourceContext from '../../contexts/source.context' + +const StyledWrapper = styled.form` + .form-control { + display: flex; + justify-content: flex-end; + width: 100%; + margin-top: 20px; + + > button:last-of-type { + margin-left: 10px; + } + } + + .fr-alert { + margin-top: 20px; + } +` + +interface AuthentificationModal { + onClose: () => void +} + +export function AuthentificationModal({ onClose }: AuthentificationModal) { + const [token, setToken] = useState('') + const [submitStatus, setSubmitStatus] = useState(null) + const { fetchSourceByToken } = useContext(SourceContext) + + const handleSubmit = async (event: React.FormEvent) => { + event.preventDefault() + setSubmitStatus('loading') + try { + await fetchSourceByToken(token) + setSubmitStatus('success') + onClose() + } catch (error) { + setSubmitStatus('error') + } + } + + return ( + + +

Connectez-vous pour accéder à vos signalements.

+ + setToken(event.target.value)} + /> + {submitStatus === 'success' && ( +
+

Authentification réussie

+
+ )} + {submitStatus === 'error' && ( +
+

Le jeton est incorrect

+
+ )} +
+ + +
+
+
+ ) +} diff --git a/src/composants/common/Header.tsx b/src/composants/common/Header.tsx index 5b8a29a..68af5bf 100644 --- a/src/composants/common/Header.tsx +++ b/src/composants/common/Header.tsx @@ -1,7 +1,8 @@ -import React from 'react' +import React, { useState } from 'react' import { Source } from '../../api/signalement' import useNavigateWithPreservedSearchParams from '../../hooks/useNavigateWithPreservedSearchParams' import styled from 'styled-components' +import { AuthentificationModal } from '../authentification/AuthentificationModal' const StyledHeader = styled.header` .fr-header__navbar > .fr-btns-group { @@ -27,75 +28,94 @@ interface HeaderProps { export function Header({ customSource, toggleShowInfo }: HeaderProps) { const { navigate } = useNavigateWithPreservedSearchParams() + const [showConnectionModal, setShowConnectionModal] = useState(false) return ( - -
-
-
-
-
-
-

+ <> + +

+
+
+
+
+
+

+

+
+
    +
  • + {customSource ? ( + + ) : ( + + )} +
  • +
  • + +
  • +
+
+
+
+ +

Mes Signalements

+
+

+ Signaler un problème dans la Base Adresse Nationale +

-
+
+
+
    - {customSource && ( -
  • +
  • + {customSource ? ( -
  • - )} + ) : ( + + )} +
  • -
-
- -

Mes Signalements

-
-

- Signaler un problème dans la Base Adresse Nationale -

-
-
-
-
-
    - {customSource && ( -
  • - -
  • - )} -
  • - -
  • -
-
-
- + + {showConnectionModal && ( + setShowConnectionModal(false)} /> + )} + ) } diff --git a/src/composants/map/SignalementMap.tsx b/src/composants/map/SignalementMap.tsx index 0babed0..60cc0ae 100644 --- a/src/composants/map/SignalementMap.tsx +++ b/src/composants/map/SignalementMap.tsx @@ -4,6 +4,7 @@ import { Position, Signalement } from '../../api/signalement' import { cadastreLayers, parcelleHoveredLayer } from '../../config/map/layers' import { positionTypeOptions } from '../../utils/signalement.utils' import { Marker } from './Marker' +import { ChangesRequested } from '../../types/signalement.types' interface SignalementMapProps { signalement: Signalement @@ -20,7 +21,7 @@ function SignalementMap({ }: SignalementMapProps) { const map = useMap() const [hoveredParcelle, setHoveredParcelle] = useState(null) - const { positions, parcelles } = signalement.changesRequested + const { positions, parcelles } = signalement.changesRequested as ChangesRequested const cadastreFiltre = useMemo( () => @@ -121,7 +122,7 @@ function SignalementMap({ ) const signalementLabel = useMemo(() => { - const { numero, suffixe, nomVoie } = signalement.changesRequested + const { numero, suffixe, nomVoie } = signalement.changesRequested as ChangesRequested return [numero, suffixe, nomVoie].reduce((acc, cur) => { return cur ? `${acc} ${cur}` : acc diff --git a/src/composants/signalement/RecapModal.tsx b/src/composants/signalement/RecapModal.tsx index 38f0417..f9a12b6 100644 --- a/src/composants/signalement/RecapModal.tsx +++ b/src/composants/signalement/RecapModal.tsx @@ -1,6 +1,5 @@ -import React, { useState } from 'react' +import React, { useContext, useState } from 'react' import HCaptcha from '@hcaptcha/react-hcaptcha' -import { useSearchParams } from 'react-router-dom' import { StyledForm } from './signalement.styles' import { @@ -8,10 +7,13 @@ import { Position, Signalement, SignalementsService, + Source, } from '../../api/signalement' import Modal from '../common/Modal' import { getPositionTypeLabel } from '../../utils/signalement.utils' import { getAdresseLabel } from '../../utils/adresse.utils' +import { ChangesRequested } from '../../types/signalement.types' +import SourceContext from '../../contexts/source.context' interface SignalementRecapModalProps { signalement: Signalement @@ -29,14 +31,13 @@ export default function SignalementRecapModal({ onSubmit, }: SignalementRecapModalProps) { const [submitStatus, setSubmitStatus] = useState(null) - const [searchParams] = useSearchParams() + const { source } = useContext(SourceContext) const handleSubmit = async (event: React.FormEvent) => { event.preventDefault() setSubmitStatus('loading') try { - const sourceId = - searchParams.get('sourceId') || process.env.REACT_APP_API_SIGNALEMENT_SOURCE_ID + const sourceId = source?.id || process.env.REACT_APP_API_SIGNALEMENT_SOURCE_ID await SignalementsService.createSignalement(signalement as CreateSignalementDTO, sourceId) setSubmitStatus('success') setTimeout(() => { @@ -48,7 +49,8 @@ export default function SignalementRecapModal({ } } - const { numero, suffixe, nomVoie, positions, parcelles, nom } = signalement.changesRequested + const { numero, suffixe, nomVoie, positions, parcelles, nom } = + signalement.changesRequested as ChangesRequested return ( @@ -196,34 +198,36 @@ export default function SignalementRecapModal({
)} -
-

Contact

-

- Vous pouvez nous laisser votre adresse email si vous souhaitez être tenu informé du - traitement de votre signalement. -

-
-
- - onEditSignalement('author', 'email')(event.target.value)} - /> + {source?.type !== Source.type.PRIVATE && ( +
+

Contact

+

+ Vous pouvez nous laisser votre adresse email si vous souhaitez être tenu informé du + traitement de votre signalement. +

+
+
+ + onEditSignalement('author', 'email')(event.target.value)} + /> +
-
-
- onEditSignalement('author', 'captchaToken')(token)} - /> -
-
+
+ onEditSignalement('author', 'captchaToken')(token)} + /> +
+ + )} {submitStatus === 'success' && (
diff --git a/src/composants/signalement/SignalementForm.tsx b/src/composants/signalement/SignalementForm.tsx index bf3247c..fb20859 100644 --- a/src/composants/signalement/SignalementForm.tsx +++ b/src/composants/signalement/SignalementForm.tsx @@ -6,6 +6,7 @@ import SignalementNumeroDeleteForm from './signalement-numero/SignalementNumeroD import { Signalement } from '../../api/signalement' import { BANPlateformeResultTypeEnum } from '../../api/ban-plateforme/types' import { MapRef } from 'react-map-gl/maplibre' +import SignalementVoieForm from './signalement-voie/SignalementVoieForm' interface SignalementFormProps { signalement: Signalement @@ -36,8 +37,7 @@ export default function SignalementForm({ return ( <> {signalement?.type === Signalement.type.LOCATION_TO_UPDATE && - (address.type === BANPlateformeResultTypeEnum.VOIE || - address.type === BANPlateformeResultTypeEnum.LIEU_DIT) && ( + address.type === BANPlateformeResultTypeEnum.LIEU_DIT && ( )} + {signalement?.type === Signalement.type.LOCATION_TO_UPDATE && + address.type === BANPlateformeResultTypeEnum.VOIE && ( + + )} + {signalement?.type === Signalement.type.LOCATION_TO_CREATE && address.type === BANPlateformeResultTypeEnum.VOIE && ( )} + {showRecapModal && ( { const { changesRequested } = signalement - const isDisabled = changesRequested.positions?.length === 0 + const isDisabled = (changesRequested as NumeroChangesRequestedDTO).positions?.length === 0 if (isCreation) { return isDisabled } @@ -43,7 +43,8 @@ export default function SignalementNumeroForm({ ) }, [address, signalement, isCreation]) - const { numero, suffixe, nomVoie, positions, parcelles } = signalement.changesRequested + const { numero, suffixe, nomVoie, positions, parcelles, comment } = + signalement.changesRequested as NumeroChangesRequestedDTO return ( @@ -71,7 +72,7 @@ export default function SignalementNumeroForm({ min={1} max={9998} type='number' - value={numero as number} + value={numero || ''} onChange={(event) => onEditSignalement('changesRequested', 'numero')(event.target.value) } @@ -168,6 +169,24 @@ export default function SignalementNumeroForm({
+
+
+
+ +