From b738d5db8b2273a252810dd4bda9f5a8eadaccd3 Mon Sep 17 00:00:00 2001
From: Benjamin Morali
Date: Wed, 27 Nov 2024 12:00:51 +0100
Subject: [PATCH] Retours formulaire (#253)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Retours formulaire
* Ajout de valeur par défaut pour les radio button
* Meileure validation de la dénomination de structrure
* Ajout de l'adresse complète pour les RIDET
* Modification du menu
* resolve error test
* gestion siret & ridet
* Ajout d'un état disabled sur le bouton envoyer
---------
Co-authored-by: ornella
---
src/components/Menu.js | 26 +++-
src/components/commun/BoutonRadio.jsx | 7 +-
src/components/commun/RadioGroup.jsx | 46 +++++++
.../CandidatureConseiller.jsx | 11 +-
.../CandidatureConseiller.test.jsx | 2 +
.../candidature-conseiller/Disponibilite.jsx | 61 +++++----
.../SituationEtExperience.jsx | 20 ++-
.../candidature-conseiller/useApiAdmin.js | 10 ++
.../BesoinEnCoordinateur.jsx | 38 ++++--
.../CandidatureCoordinateur.jsx | 16 ++-
.../CandidatureCoordinateur.test.jsx | 112 +++++++++++++++-
.../CompanyFinder.jsx | 4 +-
.../BesoinEnConseillerNumerique.jsx | 20 ++-
.../CandidatureStructure.jsx | 16 ++-
.../CandidatureStructure.test.jsx | 121 +++++++++++++++++-
.../candidature-structure/CompanyFinder.jsx | 2 +-
.../candidature-structure/Engagement.jsx | 1 -
.../InformationsDeStructure.jsx | 72 +++++++----
.../useEntrepriseFinder.js | 2 +-
19 files changed, 477 insertions(+), 110 deletions(-)
create mode 100644 src/components/commun/RadioGroup.jsx
diff --git a/src/components/Menu.js b/src/components/Menu.js
index f4a0c88..f316ba4 100644
--- a/src/components/Menu.js
+++ b/src/components/Menu.js
@@ -97,25 +97,37 @@ function Menu() {
aria-expanded={activeMenu === 'cnfs'}
aria-controls="menu-cnfs"
onClick={onClickMenu}
- {...(location.pathname.startsWith('/aide-candidat') || location.pathname.startsWith('/aide-structure') ? { 'aria-current': true } : {})}>
- Recrutement
+ {
+ ...(location.pathname.startsWith('/nouveau-formulaire-conseiller') ||
+ location.pathname.startsWith('/nouveau-formulaire-structure') ||
+ location.pathname.startsWith('/nouveau-formulaire-coordinateur') ? { 'aria-current': true } : {})
+ }>
+ Candidature
diff --git a/src/views/candidature-structure/CandidatureStructure.test.jsx b/src/views/candidature-structure/CandidatureStructure.test.jsx
index bca7d3b..da9f944 100644
--- a/src/views/candidature-structure/CandidatureStructure.test.jsx
+++ b/src/views/candidature-structure/CandidatureStructure.test.jsx
@@ -49,6 +49,7 @@ describe('candidature structure', () => {
expect(etapeInformationsDeStructure).toHaveAttribute('id', 'informations-de-structure');
const siretOuRidet = within(etapeInformationsDeStructure).getByLabelText('SIRET / RIDET * Format attendu : SIRET (12345678901234) ou RIDET (123456789)');
+ expect(siretOuRidet).toHaveAttribute('pattern', '^(?:[0-9]{6,10}|[0-9]{14})$');
expect(siretOuRidet).toHaveAttribute('id', 'siret');
expect(siretOuRidet).toBeRequired();
@@ -209,11 +210,10 @@ describe('candidature structure', () => {
'montée en compétences du public (ateliers numériques, initiations au numérique), gratuites,');
within(listDetail[1]).getByText('Qu’il consacre une partie de son temps aux rencontres locales et ' +
'nationales organisées pour la communauté et la formation continue, etc,');
- within(listDetail[2]).getByText('Qu’il revête une tenue vestimentaire dédiée fournie par l’Etat,');
- within(listDetail[3]).getByText('Tout mettre en oeuvre pour sélectionner le candidat dans un délai maximum d’un mois sur la plateforme,');
- within(listDetail[4]).getByText('Signer dans les 15 jours suivants un contrat avec ce candidat,');
- within(listDetail[5]).getByText('Laisser partir le conseiller numérique en formation initiale ou continue,');
- within(listDetail[6]).getByText('Mettre à sa disposition les moyens et ' +
+ within(listDetail[2]).getByText('Tout mettre en oeuvre pour sélectionner le candidat dans un délai maximum d’un mois sur la plateforme,');
+ within(listDetail[3]).getByText('Signer dans les 15 jours suivants un contrat avec ce candidat,');
+ within(listDetail[4]).getByText('Laisser partir le conseiller numérique en formation initiale ou continue,');
+ within(listDetail[5]).getByText('Mettre à sa disposition les moyens et ' +
'équipements pour réaliser sa mission (ordinateur, téléphone portable, voiture si nécessaire),');
const confirmationEngagement = screen.getByLabelText('Je confirme avoir lu et pris connaissance des conditions d’engagement.*');
@@ -459,7 +459,7 @@ describe('candidature structure', () => {
vi.useRealTimers();
});
- it('quand je valide le formulaire alors j’envoie toute les données nescessaires', async () => {
+ it('quand je valide le formulaire alors j’envoie toute les données nescessaires en renseignant un siret', async () => {
// GIVEN
const formData = [
[
@@ -557,6 +557,7 @@ describe('candidature structure', () => {
'telephone': '+33123456789'
},
'nom': 'AGENCE NATIONALE DE LA COHESION DES TERRITOIRES',
+ 'ridet': null,
'nomCommune': 'Paris 7e Arrondissement',
'codePostal': '75007',
'codeCommune': '75107',
@@ -567,7 +568,115 @@ describe('candidature structure', () => {
vi.useRealTimers();
});
+ it('quand je valide le formulaire alors j’envoie toute les données nescessaires en renseignant un ridet', async () => {
+ // GIVEN
+ const formData = [
+ [
+ 'siret',
+ '1234567'
+ ],
+ [
+ 'denomination',
+ 'AGENCE NATIONALE DE LA COHESION DES TERRITOIRES'
+ ],
+ [
+ 'adresse',
+ '20 AVENUE DE SEGUR, 75007 PARIS'
+ ],
+ [
+ 'type',
+ 'COMMUNE'
+ ],
+ [
+ 'prenom',
+ 'Jean'
+ ],
+ [
+ 'nom',
+ 'Dupont'
+ ],
+ [
+ 'fonction',
+ 'Test'
+ ],
+ [
+ 'email',
+ 'jean.dupont@example.com'
+ ],
+ [
+ 'telephone',
+ '+33123456789'
+ ],
+ [
+ 'nombreConseillersSouhaites',
+ '1'
+ ],
+ [
+ 'aIdentifieCandidat',
+ 'oui'
+ ],
+ [
+ 'dateDebutMission',
+ '2024-12-12'
+ ],
+ [
+ 'motivation',
+ 'je suis motivé !'
+ ],
+ [
+ 'confirmationEngagement',
+ 'on'
+ ],
+ [
+ 'g-recaptcha-response',
+ '1'
+ ],
+ [
+ 'cf-turnstile-response',
+ '1'
+ ]
+ ];
+
+ const { buildStructureData } = renderHook(() => useApiAdmin.useApiAdmin()).result.current;
+ const { getGeoLocationFromAddress } = renderHook(() => useEntrepriseFinder()).result.current;
+ let geoLocation;
+
+ // WHEN
+ await act(async () => {
+ geoLocation = await getGeoLocationFromAddress('20 AVENUE DE SEGUR, 75007 PARIS');
+ });
+ const result = await buildStructureData(formData, geoLocation, '75107');
+
+ // THEN
+ expect(result).toBe(JSON.stringify({
+ 'siret': null,
+ 'type': 'COMMUNE',
+ 'nombreConseillersSouhaites': '1',
+ 'aIdentifieCandidat': true,
+ 'dateDebutMission': '2024-12-12',
+ 'motivation': 'je suis motivé !',
+ 'confirmationEngagement': true,
+ 'cf-turnstile-response': '1',
+ 'location': { 'type': 'Point', 'coordinates': [2.3115, 48.8548] },
+ 'contact': {
+ 'prenom': 'Jean',
+ 'nom': 'Dupont',
+ 'fonction': 'Test',
+ 'email': 'jean.dupont@example.com',
+ 'telephone': '+33123456789'
+ },
+ 'nom': 'AGENCE NATIONALE DE LA COHESION DES TERRITOIRES',
+ 'ridet': '1234567',
+ 'nomCommune': 'Paris 7e Arrondissement',
+ 'codePostal': '75007',
+ 'codeCommune': '75107',
+ 'codeDepartement': '75',
+ 'codeRegion': '11',
+ 'codeCom': null,
+ }));
+ vi.useRealTimers();
+ });
it('quand je candidate et qu’une erreur serveur survient, alors le message d’erreur s’affiche et le captcha est rénitialisé', async () => {
// GIVEN
vi.useFakeTimers();
diff --git a/src/views/candidature-structure/CompanyFinder.jsx b/src/views/candidature-structure/CompanyFinder.jsx
index b72cb85..d140692 100644
--- a/src/views/candidature-structure/CompanyFinder.jsx
+++ b/src/views/candidature-structure/CompanyFinder.jsx
@@ -12,7 +12,7 @@ export default function CompanyFinder({ onSearch, errors }) {
handleSearch(event.target.value)}
- pattern="^(?:[0-9]{9}|[0-9]{14})$"
+ pattern="^(?:[0-9]{6,10}|[0-9]{14})$"
maxlength="14"
error={errors.siret}
>
diff --git a/src/views/candidature-structure/Engagement.jsx b/src/views/candidature-structure/Engagement.jsx
index 94167b9..3132b58 100644
--- a/src/views/candidature-structure/Engagement.jsx
+++ b/src/views/candidature-structure/Engagement.jsx
@@ -9,7 +9,6 @@ export default function Engagement() {
Assurer que le conseiller réalise des activités de montée en compétences du public (ateliers numériques, initiations au numérique), gratuites,
Qu’il consacre une partie de son temps aux rencontres locales et nationales organisées pour la communauté et la formation continue, etc,
- Qu’il revête une tenue vestimentaire dédiée fournie par l’Etat,
Tout mettre en oeuvre pour sélectionner le candidat dans un délai maximum d’un mois sur la plateforme,
Signer dans les 15 jours suivants un contrat avec ce candidat,
Laisser partir le conseiller numérique en formation initiale ou continue,
diff --git a/src/views/candidature-structure/InformationsDeStructure.jsx b/src/views/candidature-structure/InformationsDeStructure.jsx
index 1de88a8..38738a3 100644
--- a/src/views/candidature-structure/InformationsDeStructure.jsx
+++ b/src/views/candidature-structure/InformationsDeStructure.jsx
@@ -1,16 +1,48 @@
-import React from 'react';
+import React, { useEffect } from 'react';
import Input from '../../components/commun/Input';
import CompanyFinder from './CompanyFinder';
-import BoutonRadio from '../../components/commun/BoutonRadio';
import { useEntrepriseFinder } from './useEntrepriseFinder';
import PropTypes from 'prop-types';
import './CandidatureStructure.css';
+import RadioGroup from '../../components/commun/RadioGroup';
+import { checkValidity } from '../../shared/checkValidity';
const TAILLE_SIRET = 14;
const TAILLE_RIDET = [6, 7];
const TAILLES_POSSIBLES = [...TAILLE_RIDET, TAILLE_SIRET];
-export default function InformationsDeStructure({ setGeoLocation, setCodeCommune, errors }) {
+const options = [
+ {
+ id: 'COMMUNE',
+ label: 'Une commune'
+ },
+ {
+ id: 'DEPARTEMENT',
+ label: 'Un département'
+ },
+ {
+ id: 'REGION',
+ label: 'Une région'
+ },
+ {
+ id: 'EPCI',
+ label: 'Un établissement public de coopération intercommunale'
+ },
+ {
+ id: 'COLLECTIVITE',
+ label: 'Une collectivité à statut particulier'
+ },
+ {
+ id: 'GIP',
+ label: 'Un GIP'
+ },
+ {
+ id: 'PRIVATE',
+ label: 'Une structure privée (association, entreprise de l’ESS, fondations)'
+ },
+];
+
+export default function InformationsDeStructure({ setGeoLocation, setCodeCommune, errors, setErrors, formRef }) {
const {
entreprise,
search,
@@ -25,6 +57,12 @@ export default function InformationsDeStructure({ setGeoLocation, setCodeCommune
setAdresse,
} = useEntrepriseFinder(setGeoLocation, setCodeCommune);
+ useEffect(() => {
+ if (denomination) {
+ checkValidity(formRef, setErrors);
+ }
+ }, [denomination]);
+
const handleSearch = value => {
const numericValue = value.replace(/\D/g, '');
if (TAILLES_POSSIBLES.includes(numericValue.length)) {
@@ -61,7 +99,9 @@ export default function InformationsDeStructure({ setGeoLocation, setCodeCommune
value={denomination}
isLoading={loading}
ariaBusy={loading}
- onChange={event => setDenomination(event.target.value)}
+ onChange={event => {
+ setDenomination(event.target.value);
+ }}
error={errors.denomination}
>
Dénomination *
@@ -93,27 +133,7 @@ export default function InformationsDeStructure({ setGeoLocation, setCodeCommune
Votre structure est *
-
- Une commune
-
-
- Un département
-
-
- Une région
-
-
- Un établissement public de coopération intercommunale
-
-
- Une collectivité à statut particulier
-
-
- Un GIP
-
-
- Une structure privée (association, entreprise de l’ESS, fondations)
-
+
);
@@ -124,4 +144,6 @@ InformationsDeStructure.propTypes = {
setCodeCommune: PropTypes.func.isRequired,
geoLocation: PropTypes.object,
errors: PropTypes.object,
+ setErrors: PropTypes.func,
+ formRef: PropTypes.object
};
diff --git a/src/views/candidature-structure/useEntrepriseFinder.js b/src/views/candidature-structure/useEntrepriseFinder.js
index e605153..7fa5035 100644
--- a/src/views/candidature-structure/useEntrepriseFinder.js
+++ b/src/views/candidature-structure/useEntrepriseFinder.js
@@ -88,7 +88,7 @@ export const useEntrepriseFinder = (setGeoLocation, setCodeCommune) => {
const response = await fetch(urlAPI);
const result = await response.json();
const suggestions = result.features.map(feature => ({
- label: `${feature.properties.postcode} ${feature.properties.city}`,
+ label: feature.properties.label,
codeCommune: feature.properties.citycode,
geometry: feature.geometry,
}));