diff --git a/.env b/.env
index f93476da..fec9ab6b 100644
--- a/.env
+++ b/.env
@@ -52,3 +52,6 @@ SANDBOX_PROC_CREATE_VECT_PYR=
# URL de l'API espace collaboratif
API_ESPACE_COLLABORATIF_URL=
+
+# URL d'abonnement à la newsletter
+NEWSLETTER_SUBSCRIBE_ACTION=
diff --git a/assets/components/Layout/AppFollow.tsx b/assets/components/Layout/AppFollow.tsx
new file mode 100644
index 00000000..3c455fa6
--- /dev/null
+++ b/assets/components/Layout/AppFollow.tsx
@@ -0,0 +1,30 @@
+import { memo } from "react";
+import Follow from "@codegouvfr/react-dsfr/Follow";
+import { routes, useRoute } from "../../router/router";
+
+const AppFollow = () => {
+ const newsletterSubscribeAction = (document.getElementById("app_env") as HTMLDivElement)?.dataset?.["newsletterSubscribeAction"] ?? null;
+ const route = useRoute();
+
+ if (newsletterSubscribeAction === null) {
+ return null;
+ }
+
+ if (typeof route.name === "string" && /^newsletter_/.test(route.name)) {
+ return null;
+ }
+
+ return (
+
+ );
+};
+
+export default memo(AppFollow);
diff --git a/assets/components/Layout/AppLayout.tsx b/assets/components/Layout/AppLayout.tsx
index b9e8101c..ca3cc9d9 100644
--- a/assets/components/Layout/AppLayout.tsx
+++ b/assets/components/Layout/AppLayout.tsx
@@ -19,6 +19,7 @@ import SessionExpiredAlert from "../Utils/SessionExpiredAlert";
import SnackbarMessage from "../Utils/SnackbarMessage";
import AppFooter from "./AppFooter";
import AppHeader from "./AppHeader";
+import AppFollow from "./AppFollow";
const HiddenElements: FC = () => {
return (
@@ -90,6 +91,7 @@ const AppLayout: FC> = ({ children, navItems,
{children}
+
>
diff --git a/assets/i18n/Breadcrumb.tsx b/assets/i18n/Breadcrumb.tsx
index e9f133a4..2ffedf90 100644
--- a/assets/i18n/Breadcrumb.tsx
+++ b/assets/i18n/Breadcrumb.tsx
@@ -15,6 +15,10 @@ export const { i18n } = declareComponentKeys<
| "join"
| "terms_of_service"
| "service_status"
+ | "newsletter_subscribe"
+ | "newsletter_confirm_email"
+ | "newsletter_success"
+ | "newsletter_error"
| "accesses_request"
| "my_account"
| "my_access_keys"
@@ -57,6 +61,10 @@ export const BreadcrumbFrTranslations: Translations<"fr">["Breadcrumb"] = {
join: "Nous rejoindre",
terms_of_service: "Conditions générales d'utilisation",
service_status: "Niveau de service",
+ newsletter_subscribe: "S’inscrire à la lettre d’information",
+ newsletter_confirm_email: "S’inscrire à la lettre d’information",
+ newsletter_success: "S’inscrire à la lettre d’information",
+ newsletter_error: "S’inscrire à la lettre d’information",
accesses_request: "Demande d'accès à un service privé",
my_account: "Mon compte",
my_access_keys: "Mes clés d'accès",
@@ -98,7 +106,11 @@ export const BreadcrumbEnTranslations: Translations<"en">["Breadcrumb"] = {
offer: "Offer",
join: "Join us",
terms_of_service: "Terms of Service",
- service_status: "TODO",
+ service_status: "Service Status",
+ newsletter_subscribe: "Newsletter subscription",
+ newsletter_confirm_email: "Newsletter subscription",
+ newsletter_success: "Newsletter subscription",
+ newsletter_error: "Newsletter subscription",
accesses_request: "Request to private resources",
my_account: "My account",
my_access_keys: "My access keys",
diff --git a/assets/modules/entrepot/breadcrumbs.ts b/assets/modules/entrepot/breadcrumbs.ts
index acd87397..ec019bbd 100644
--- a/assets/modules/entrepot/breadcrumbs.ts
+++ b/assets/modules/entrepot/breadcrumbs.ts
@@ -27,6 +27,10 @@ const getBreadcrumb = (route: Route, datastore?: Datastore): Brea
case "join":
case "terms_of_service":
case "service_status":
+ case "newsletter_subscribe":
+ case "newsletter_confirm_email":
+ case "newsletter_success":
+ case "newsletter_error":
return { ...defaultProps, currentPageLabel: t(route.name) };
case "contact_thanks":
diff --git a/assets/pages/footer/PersonalData.tsx b/assets/pages/footer/PersonalData.tsx
index cc99303e..9d1da83d 100644
--- a/assets/pages/footer/PersonalData.tsx
+++ b/assets/pages/footer/PersonalData.tsx
@@ -2,6 +2,8 @@ import { fr } from "@codegouvfr/react-dsfr";
import AppLayout from "../../components/Layout/AppLayout";
+import Summary from "@codegouvfr/react-dsfr/Summary";
+
const PersonalData = () => {
return (
@@ -9,7 +11,117 @@ const PersonalData = () => {
Données à caractère personnel
-
Inscriptions aux événements
+
+
+
+ Inscription à la lettre d’information
+
+
+
+ L’inscription à la lettre d’information cartes.gouv.fr donne lieu à la collecte, au stockage et au traitement de données à caractère
+ personnel par l’IGN, responsable de traitement. Les traitements sont référencés ci-dessous :
+
+
+
Quels sont les objectifs du recueil de ces données (finalités) ?
+
+
+ Gestion de l’envoi de la lettre d’information
+
+
Gestion des abonnements à la lettre d’information
+
Gestion des envois électroniques
+
+
+
+
+ Quelles sont les données personnelles collectées (i) ?{" "}
+
+
Catégories de données traitées :
+
+
+ Adresse email
+
+
+
Source des données :
+
+
Personnes concernées
+
Prestataire en charge de la gestion des abonnements et des envois de la lettre d’information
+
+
Caractère obligatoire du recueil des données :
+
+
Le recueil de l’adresse email est obligatoire pour l’envoi de la lettre d’information
+
+
Quelle est la base juridique du traitement ?
+
+
+ Article 6 (1) e du RGPD : ce traitement de données relève d’une mission d’intérêt public dont est investi l’IGN en application du
+ RGPD et de la loi Informatique et Libertés modifiée.
+
+
+
Quelles sont les personnes concernées ?
+
+
Le traitement de données concerne les personnes qui souhaitent s’abonner ou se désabonner de la lettre d’information.
+
+
Qui pourra prendre en connaissance (destinataires) ?
+
+
Service de l’IGN en charge de gérer la lettre d’information,
+
Le prestataire en charge de l’abonnement e des envois de la lettre d’information
+
+
Quelle est la durée de conservation des données ?
+
+
+ L’IGN conserve l’adresse email tant que la personne concernée ne se désinscrit pas (via le lien de désinscription intégré aux
+ newsletters).
+
+
+
+
+ Inscriptions aux événements
+
L’inscription aux événements (physique ou en ligne) sur le site cartes.gouv.fr donne lieu à la collecte, au stockage et au traitement de
@@ -31,7 +143,9 @@ const PersonalData = () => {
sur le site du partenaire organisateur de cet événement.
-
Accès à certaines API par un fournisseur d’identité
+
+ Accès à certaines API par un fournisseur d’identité
+
Certaines API sont accessibles et utilisables après authentification auprès de l’un des fournisseurs d’identité suivants :
@@ -41,7 +155,9 @@ const PersonalData = () => {
Nous vous invitons à lire les politiques de protection des données personnelles de ces fournisseurs d’identité.
-
Création d’un compte personnel
+
+ Création d’un compte personnel
+
Le site cartes.gouv.fr offre aux utilisateurs la possibilité de créer un compte personnel pour accéder à des fonctions particulières et
@@ -105,7 +221,9 @@ const PersonalData = () => {
2 ans à compter de la date de dernière connexion ou de la suppression du compte personnel ou du service
-
Prise de contact via le formulaire de contact
+
+ Prise de contact via le formulaire de contact
+
La prise de contact via le formulaire de contact donne lieu à la collecte, au stockage et au traitement de données à caractère personnel
@@ -147,7 +265,9 @@ const PersonalData = () => {
La durée de conservation des données à caractère personnel est fixée par l’IGN à trois ans à compter de la dernière sollicitation
-
Participation à une enquête utilisateur
+
+ Participation à une enquête utilisateur
+
La participation à une enquête utilisateur donne lieu à la collecte, au stockage et au traitement de données à caractère personnel par
@@ -194,7 +314,9 @@ const PersonalData = () => {
La durée de conservation des données est fixée à 5 ans à compter de la date de participation à une enquête utilisateur.
-
Inscription aux communautés d’utilisateurs
+
+ Inscription aux communautés d’utilisateurs
+
L’inscription aux communautés d’utilisateurs IGN donne lieu à la collecte, au stockage et au traitement de données à caractère personnel
diff --git a/assets/pages/newsletter/NewsletterConfirmEmail.tsx b/assets/pages/newsletter/NewsletterConfirmEmail.tsx
new file mode 100644
index 00000000..bba0cdf2
--- /dev/null
+++ b/assets/pages/newsletter/NewsletterConfirmEmail.tsx
@@ -0,0 +1,26 @@
+import { fr } from "@codegouvfr/react-dsfr";
+import AppLayout from "../../components/Layout/AppLayout";
+
+import { Button } from "@codegouvfr/react-dsfr/Button";
+import Translator from "../../modules/Translator";
+import { routes } from "../../router/router";
+
+const NewsletterConfirmEmail = () => {
+ return (
+
+
+
+
S’inscrire à la lettre d’information
+
+
Veuillez consultez vos emails pour confirmer votre inscription.
+
+
+
+
+
+
+
+ );
+};
+
+export default NewsletterConfirmEmail;
diff --git a/assets/pages/newsletter/NewsletterError.tsx b/assets/pages/newsletter/NewsletterError.tsx
new file mode 100644
index 00000000..225b22bb
--- /dev/null
+++ b/assets/pages/newsletter/NewsletterError.tsx
@@ -0,0 +1,27 @@
+import { fr } from "@codegouvfr/react-dsfr";
+import AppLayout from "../../components/Layout/AppLayout";
+
+import { Alert } from "@codegouvfr/react-dsfr/Alert";
+import { Button } from "@codegouvfr/react-dsfr/Button";
+import Translator from "../../modules/Translator";
+import { routes } from "../../router/router";
+
+const NewsletterError = () => {
+ return (
+
+
+
+
S’inscrire à la lettre d’information
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default NewsletterError;
diff --git a/assets/pages/newsletter/NewsletterSubscribe.tsx b/assets/pages/newsletter/NewsletterSubscribe.tsx
new file mode 100644
index 00000000..b8562492
--- /dev/null
+++ b/assets/pages/newsletter/NewsletterSubscribe.tsx
@@ -0,0 +1,48 @@
+import { fr } from "@codegouvfr/react-dsfr";
+import AppLayout from "../../components/Layout/AppLayout";
+import Button from "@codegouvfr/react-dsfr/Button";
+import Input from "@codegouvfr/react-dsfr/Input";
+import { routes } from "../../router/router";
+
+const NewsletterSubscribe = () => {
+ const newsletterSubscribeAction = (document.getElementById("app_env") as HTMLDivElement)?.dataset?.["newsletterSubscribeAction"] ?? null;
+
+ return (
+
+