Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2295 - Ajout des meta manquantes #2297

Merged
merged 2 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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 (
<HelmetProvider>
<Helmet>
<title>
{contents
? `${contents.title} - PMSMP: Immersion Facile`
: defaultMetaContents.title}
</title>
<meta
name="description"
content={
contents ? contents.description : defaultMetaContents.description
}
/>
</Helmet>
</HelmetProvider>
<Helmet>
<title>
{contents
? `${contents.title} - PMSMP: Immersion Facile`
: defaultMetaContents.title}
</title>
<meta
name="description"
content={
contents ? contents.description : defaultMetaContents.description
}
/>
</Helmet>
);
};

Expand All @@ -48,6 +46,6 @@ const getMetaContents = (
if (route.name === "admin") {
return adminMetaContent[route.params.tab];
}
return metaContents[route.name];
return defaultPageMetaContents[route.name];
}
};
53 changes: 52 additions & 1 deletion front/src/app/contents/meta/metaContents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ export const defaultMetaContents: MetaContentType = {
description: "Faciliter la réalisation des immersions professionnelles.",
};

export const metaContents: Partial<Record<FrontRouteKeys, MetaContentType>> = {
export const defaultPageMetaContents: Partial<
Record<FrontRouteKeys, MetaContentType>
> = {
addAgency: {
title: "Formulaire d'ajout d'un prescripteur",
description: "Devenir prescripteur de PMSMP et immersions professionnelles",
Expand Down Expand Up @@ -112,6 +114,55 @@ export const metaContents: Partial<Record<FrontRouteKeys, MetaContentType>> = {
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<StandardPageSlugs, MetaContentType> = {
Expand Down
13 changes: 8 additions & 5 deletions front/src/app/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand All @@ -31,10 +32,12 @@ createRoot(rootContainer).render(
<ErrorBoundary
fallbackRender={({ error }) => <MinimalErrorPage error={error} />}
>
<RouteProvider>
<MetaContent />
<App />
</RouteProvider>
<HelmetProvider>
<RouteProvider>
<DefaultMetaContent />
<App />
</RouteProvider>
</HelmetProvider>
</ErrorBoundary>
</Provider>
</React.StrictMode>,
Expand Down
42 changes: 42 additions & 0 deletions front/src/app/pages/search/SearchResultPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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";
Expand Down Expand Up @@ -50,13 +53,42 @@ const SearchResultSection = ({
</div>
);

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
>;
const currentSearchResult = useAppSelector(
searchSelectors.currentSearchResult,
);
const defaultMetaContents = defaultPageMetaContents.searchResult;
const feedback = useAppSelector(searchSelectors.feedback);
const isLoading = useAppSelector(searchSelectors.isLoading);
const formContactRef = useRef<ElementRef<"div">>(null);
Expand Down Expand Up @@ -99,6 +131,16 @@ export const SearchResultPage = () => {

return (
<HeaderFooterLayout>
<Helmet>
<title>
{getMetaForSearchResult(currentSearchResult).title} :{" "}
{defaultMetaContents?.title}
</title>
<meta
name="description"
content={getMetaForSearchResult(currentSearchResult).description}
/>
</Helmet>
<MainWrapper layout="boxed">
<>
{isLoading && <Loader />}
Expand Down
Loading