diff --git a/front/src/app/components/layout/MetaContent.tsx b/front/src/app/components/layout/DefaultMetaContent.tsx
similarity index 61%
rename from front/src/app/components/layout/MetaContent.tsx
rename to front/src/app/components/layout/DefaultMetaContent.tsx
index 831b45a630..d05f1bf912 100644
--- a/front/src/app/components/layout/MetaContent.tsx
+++ b/front/src/app/components/layout/DefaultMetaContent.tsx
@@ -1,37 +1,35 @@
import React from "react";
-import { Helmet, HelmetProvider } from "react-helmet-async";
+import { Helmet } from "react-helmet-async";
import {
MetaContentType,
adminMetaContent,
defaultMetaContents,
+ defaultPageMetaContents,
groupMetaContent,
- metaContents,
standardMetaContent,
} from "src/app/contents/meta/metaContents";
import { StandardPageSlugs } from "src/app/routes/routeParams/standardPage";
import { routes, useRoute } from "src/app/routes/routes";
import { Route } from "type-route";
-export const MetaContent = (): JSX.Element => {
+export const DefaultMetaContent = (): JSX.Element => {
const route = useRoute();
const contents = getMetaContents(route);
return (
-
-
-
- {contents
- ? `${contents.title} - PMSMP: Immersion Facile`
- : defaultMetaContents.title}
-
-
-
-
+
+
+ {contents
+ ? `${contents.title} - PMSMP: Immersion Facile`
+ : defaultMetaContents.title}
+
+
+
);
};
@@ -48,6 +46,6 @@ const getMetaContents = (
if (route.name === "admin") {
return adminMetaContent[route.params.tab];
}
- return metaContents[route.name];
+ return defaultPageMetaContents[route.name];
}
};
diff --git a/front/src/app/contents/meta/metaContents.ts b/front/src/app/contents/meta/metaContents.ts
index 1120ed5e41..f308a8649c 100644
--- a/front/src/app/contents/meta/metaContents.ts
+++ b/front/src/app/contents/meta/metaContents.ts
@@ -12,7 +12,9 @@ export const defaultMetaContents: MetaContentType = {
description: "Faciliter la réalisation des immersions professionnelles.",
};
-export const metaContents: Partial> = {
+export const defaultPageMetaContents: Partial<
+ Record
+> = {
addAgency: {
title: "Formulaire d'ajout d'un prescripteur",
description: "Devenir prescripteur de PMSMP et immersions professionnelles",
@@ -112,6 +114,55 @@ export const metaContents: Partial> = {
description:
"Utilisez notre moteur de recherche pour trouver une entreprise accueillante d'Immersions Professionnelles ou PMSMP",
},
+ agencyDashboard: {
+ title: "Tableau de bord agence",
+ description: "Retrouvez vos conventions en cours et passées",
+ },
+ beneficiaryDashboard: {
+ title: "Tableau de bord bénéficiaire",
+ description: "Bientôt disponible",
+ },
+ establishmentDashboard: {
+ title: "Tableau de bord entreprise",
+ description:
+ "Retrouvez vos conventions en cours et passées, les candidatures faites à votre entreprise",
+ },
+ initiateConvention: {
+ title: "Initier une convention",
+ description:
+ "Initier une convention pour une Immersion Professionnelle (PMSMP)",
+ },
+ openApiDoc: {
+ title: "Documentation API",
+ description: "Documentation de l'API de l'application Immersion Facilitée",
+ },
+ conventionConfirmation: {
+ title: "Confirmation de la convention",
+ description:
+ "Confirmation de la convention d'immersion professionnelle (PMSMP)",
+ },
+ searchResult: {
+ title: "Offre d'immersion (PMSMP)",
+ description: "Fiche présentant une offre d'immersion (PMSMP)",
+ },
+ searchResultExternal: {
+ title: "Offre d'immersion (PMSMP)",
+ description: "Fiche présentant une offre d'immersion (PMSMP)",
+ },
+ searchDiagoriente: {
+ title:
+ "Rechercher une entreprise pour réaliser une immersion professionnelle",
+ description:
+ "Utilisez notre moteur de recherche pour trouver une entreprise accueillante d'Immersions Professionnelles ou PMSMP",
+ },
+ conventionDocument: {
+ title: "Document de convention d'immersion (PMSMP) finalisé",
+ description: "Document de convention d'immersion (PMSMP) finalisé",
+ },
+ group: {
+ title: "Page de regroupement d'immersions",
+ description: "Page de regroupement d'immersions",
+ },
};
export const standardMetaContent: Record = {
diff --git a/front/src/app/main.tsx b/front/src/app/main.tsx
index dfb27df88c..8f52f6bf87 100644
--- a/front/src/app/main.tsx
+++ b/front/src/app/main.tsx
@@ -3,12 +3,13 @@ import * as Sentry from "@sentry/browser";
import React from "react";
import { createRoot } from "react-dom/client";
import { ErrorBoundary } from "react-error-boundary";
+import { HelmetProvider } from "react-helmet-async";
import { Provider } from "react-redux";
import { App } from "src/app/App";
import { MinimalErrorPage } from "src/app/pages/error/MinimalErrorPage";
import { store } from "src/config/dependencies";
import { ENV } from "src/config/environmentVariables";
-import { MetaContent } from "./components/layout/MetaContent";
+import { DefaultMetaContent } from "./components/layout/DefaultMetaContent";
import { RouteProvider } from "./routes/routes";
Sentry.init({
@@ -31,10 +32,12 @@ createRoot(rootContainer).render(
}
>
-
-
-
-
+
+
+
+
+
+
,
diff --git a/front/src/app/pages/search/SearchResultPage.tsx b/front/src/app/pages/search/SearchResultPage.tsx
index 2ebaa6c6db..c4fd5d29ab 100644
--- a/front/src/app/pages/search/SearchResultPage.tsx
+++ b/front/src/app/pages/search/SearchResultPage.tsx
@@ -4,10 +4,12 @@ import Button from "@codegouvfr/react-dsfr/Button";
import ButtonsGroup from "@codegouvfr/react-dsfr/ButtonsGroup";
import React, { ElementRef, useEffect, useRef, useState } from "react";
import { Loader, MainWrapper } from "react-design-system";
+import { Helmet } from "react-helmet-async";
import { useDispatch } from "react-redux";
import {
AppellationDto,
ContactMethod,
+ SearchResultDto,
getMapsLink,
makeAppellationInformationUrl,
makeNafClassInformationUrl,
@@ -18,6 +20,7 @@ import { ContactByPhone } from "src/app/components/immersion-offer/ContactByPhon
import { ContactInPerson } from "src/app/components/immersion-offer/ContactInPerson";
import { HeaderFooterLayout } from "src/app/components/layout/HeaderFooterLayout";
import { SearchResultLabels } from "src/app/components/search/SearchResultLabels";
+import { defaultPageMetaContents } from "src/app/contents/meta/metaContents";
import { useAppSelector } from "src/app/hooks/reduxHooks";
import { routes, useRoute } from "src/app/routes/routes";
import { searchSelectors } from "src/core-logic/domain/search/search.selectors";
@@ -50,6 +53,34 @@ const SearchResultSection = ({
);
+const getMetaForSearchResult = (
+ currentSearchResult: SearchResultDto | null,
+): {
+ title: string;
+ description: string;
+} => {
+ if (!currentSearchResult) return { title: "", description: "" };
+ const hasAppellations = currentSearchResult.appellations?.length;
+ return {
+ title: `${currentSearchResult.name}${
+ hasAppellations
+ ? ` - ${currentSearchResult.appellations
+ .map((appellation) => `${appellation.appellationLabel}`)
+ .join(", ")}`
+ : ""
+ }`,
+ description: `Fiche présentant l'immersion proposée par l'entreprise ${
+ currentSearchResult?.name
+ }${
+ hasAppellations
+ ? `en tant que ${currentSearchResult.appellations.map(
+ (appellation) => appellation.appellationLabel,
+ )}`
+ : ""
+ }`,
+ };
+};
+
export const SearchResultPage = () => {
const route = useRoute() as Route<
typeof routes.searchResult | typeof routes.searchResultExternal
@@ -57,6 +88,7 @@ export const SearchResultPage = () => {
const currentSearchResult = useAppSelector(
searchSelectors.currentSearchResult,
);
+ const defaultMetaContents = defaultPageMetaContents.searchResult;
const feedback = useAppSelector(searchSelectors.feedback);
const isLoading = useAppSelector(searchSelectors.isLoading);
const formContactRef = useRef>(null);
@@ -99,6 +131,16 @@ export const SearchResultPage = () => {
return (
+
+
+ {getMetaForSearchResult(currentSearchResult).title} :{" "}
+ {defaultMetaContents?.title}
+
+
+
<>
{isLoading && }