From c6a77ebd2cdc80eb041471fbeb7a9a4b373b5413 Mon Sep 17 00:00:00 2001 From: Gauthier Fiorentino Date: Thu, 5 Dec 2024 15:29:20 +0100 Subject: [PATCH 1/8] =?UTF-8?q?wip:=20Transmet=20la=20date=20de=20mise=20?= =?UTF-8?q?=C3=A0=20jour=20des=20actus=20jusqu'au=20front?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/index.page.tsx | 21 ++++++++++++++++--- src/server/actualites/domain/actualite.ts | 1 + .../infra/strapiActualites.mapper.ts | 1 + .../infra/strapiActualites.repository.test.ts | 8 +++++-- src/server/articles/infra/strapiArticle.ts | 3 ++- src/shared/ISODateTime.d.ts | 11 ++++++++++ 6 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 src/shared/ISODateTime.d.ts diff --git a/src/pages/index.page.tsx b/src/pages/index.page.tsx index 4cee0a255b..6a9b80aa7c 100644 --- a/src/pages/index.page.tsx +++ b/src/pages/index.page.tsx @@ -15,6 +15,7 @@ import styles from '~/pages/index.module.scss'; import { Actualite } from '~/server/actualites/domain/actualite'; import { isFailure } from '~/server/errors/either'; import { dependencies } from '~/server/start'; +import { ISODateTime } from '~/shared/ISODateTime'; interface CardContent { @@ -25,11 +26,25 @@ interface CardContent { title: string } +type SerializedActualite = Omit & { + dateMiseAJour: ISODateTime +} interface AccueilPageProps { - actualites: Array + actualites: Array +} +function deserialize(actualites: Array): Array { + return actualites.map((actualite) => ({ + ...actualite, + dateMiseAJour: new Date(actualite.dateMiseAJour), + })); +} +function serialize(cartesActualitesResponse: Array): Array { + return JSON.parse(JSON.stringify(cartesActualitesResponse)); } export default function Accueil(accueilProps: AccueilPageProps) { + const actualites = deserialize(accueilProps.actualites); + useAnalytics(analytics); const isJobEteCardVisible = process.env.NEXT_PUBLIC_JOB_ETE_FEATURE === '1'; @@ -50,7 +65,7 @@ export default function Accueil(accueilProps: AccueilPageProps) { const isCampagneHandicapVisible = process.env.NEXT_PUBLIC_CAMPAGNE_HANDICAP === '1'; - const actualitesCardListContent: CardContent[] = accueilProps.actualites.map((carte: Actualite): CardContent => { + const actualitesCardListContent: CardContent[] = actualites.map((carte: Actualite): CardContent => { return { children:

{carte.extraitContenu}

, imageUrl: carte.bannière?.src || '', @@ -486,7 +501,7 @@ export async function getStaticProps(): Promise { @@ -74,6 +76,7 @@ describe('strapiActualitesRepository', () => { src: 'https://image.example.com/', }, contenu: 'Contenu', + dateMiseAJour: new Date('2024-01-01T00:00:00.000Z'), extraitContenu: 'Contenu', link: '/articles/titre-article', titre: 'Titre', @@ -143,7 +146,8 @@ describe('strapiActualitesRepository', () => { const result = await strapiActualites.getActualitesEchantillonList(); // Then - expect(result).toStrictEqual(createSuccess(anActualiteLongList().slice(0,3))); + expect(isSuccess(result)).toBe(true); + expect((result as Success).result).toHaveLength(3); }); it('lorsque le mapping est en échec, appelle le service de gestion d’erreur avec l’erreur et le contexte', async () => { // Given diff --git a/src/server/articles/infra/strapiArticle.ts b/src/server/articles/infra/strapiArticle.ts index 65290b76c8..99653cda8a 100644 --- a/src/server/articles/infra/strapiArticle.ts +++ b/src/server/articles/infra/strapiArticle.ts @@ -1,9 +1,10 @@ import { Strapi } from '~/server/cms/infra/repositories/strapi.response'; +import { ISODateTime } from '~/shared/ISODateTime'; export interface StrapiArticle { contenu: string; banniere: Strapi.SingleRelation; slug: string; titre: string; - updatedAt: string; + updatedAt: ISODateTime; } diff --git a/src/shared/ISODateTime.d.ts b/src/shared/ISODateTime.d.ts new file mode 100644 index 0000000000..5c8ec9cec3 --- /dev/null +++ b/src/shared/ISODateTime.d.ts @@ -0,0 +1,11 @@ +type Year = string; +type Month = string; +type Day = string; +type Hour = string; +type Minute = string; +type Second = string; +type Millisecond = string; +type Timezone = string; +type ISODate = `${Year}-${Month}-${Day}` +type ISOTime = `${Hour}:${Minute}:${Second}.${Millisecond}` +export type ISODateTime = `${ISODate}T${ISOTime}${Timezone}` From 7c75e753cb567ac4c6407a002fc06ba0db456d98 Mon Sep 17 00:00:00 2001 From: Gauthier Fiorentino Date: Wed, 11 Dec 2024 16:03:34 +0100 Subject: [PATCH 2/8] =?UTF-8?q?wip:=20D=C3=A9serialise=20la=20date=20de=20?= =?UTF-8?q?mise=20=C3=A0=20jour=20dans=20le=20front?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/index.page.test.tsx | 2 +- src/pages/index.page.tsx | 16 +++++++++++----- .../infra/strapiActualites.repository.test.ts | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/pages/index.page.test.tsx b/src/pages/index.page.test.tsx index 6bdbf39323..51d11e412a 100644 --- a/src/pages/index.page.test.tsx +++ b/src/pages/index.page.test.tsx @@ -14,7 +14,7 @@ import { mockScrollIntoView, mockSmallScreen } from '~/client/components/window. import { DependenciesProvider } from '~/client/context/dependenciesContainer.context'; import { ManualAnalyticsService } from '~/client/services/analytics/analytics.service'; import { aManualAnalyticsService } from '~/client/services/analytics/analytics.service.fixture'; -import Accueil, { getStaticProps } from '~/pages/index.page'; +import { Accueil, getStaticProps } from '~/pages/index.page'; import { Actualite } from '~/server/actualites/domain/actualite'; import { anActualiteList, anActualiteLongList } from '~/server/actualites/domain/actualite.fixture'; import { createFailure, createSuccess } from '~/server/errors/either'; diff --git a/src/pages/index.page.tsx b/src/pages/index.page.tsx index 6a9b80aa7c..3ff23eae4a 100644 --- a/src/pages/index.page.tsx +++ b/src/pages/index.page.tsx @@ -29,9 +29,12 @@ interface CardContent { type SerializedActualite = Omit & { dateMiseAJour: ISODateTime } -interface AccueilPageProps { +interface SerializedAccueilPageProps { actualites: Array } +interface AccueilPageProps { + actualites: Array +} function deserialize(actualites: Array): Array { return actualites.map((actualite) => ({ ...actualite, @@ -42,9 +45,12 @@ function serialize(cartesActualitesResponse: Array): Array; +} +export function Accueil({ actualites }: AccueilPageProps) { useAnalytics(analytics); const isJobEteCardVisible = process.env.NEXT_PUBLIC_JOB_ETE_FEATURE === '1'; @@ -484,9 +490,9 @@ export default function Accueil(accueilProps: AccueilPageProps) { ); -}; +} -export async function getStaticProps(): Promise> { +export async function getStaticProps(): Promise> { const isEspaceJeuneVisible = process.env.NEXT_PUBLIC_OLD_ESPACE_JEUNE_FEATURE === '0'; if (!isEspaceJeuneVisible) { return { diff --git a/src/server/actualites/infra/strapiActualites.repository.test.ts b/src/server/actualites/infra/strapiActualites.repository.test.ts index aa13228f79..4a19f38c86 100644 --- a/src/server/actualites/infra/strapiActualites.repository.test.ts +++ b/src/server/actualites/infra/strapiActualites.repository.test.ts @@ -1,4 +1,4 @@ -import { anActualite, anActualiteLongList } from '~/server/actualites/domain/actualite.fixture'; +import { anActualite } from '~/server/actualites/domain/actualite.fixture'; import { aStrapiActualite, aStrapiListeActualites, From f3b247e95be6406225c9cc6392044d33eb23bf9b Mon Sep 17 00:00:00 2001 From: Gauthier Fiorentino Date: Tue, 17 Dec 2024 10:53:36 +0100 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20Ajoute=20la=20date=20sur=20les=20ca?= =?UTF-8?q?rds=20d'actualit=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Actualites/ActualiteCard.module.scss | 12 +++--- .../Actualites/ActualiteCard.stories.tsx | 15 ++++++- .../features/Actualites/ActualiteCard.tsx | 42 +++++++++++-------- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/src/client/components/features/Actualites/ActualiteCard.module.scss b/src/client/components/features/Actualites/ActualiteCard.module.scss index 2e6ffc4a35..7a1ac4300a 100644 --- a/src/client/components/features/Actualites/ActualiteCard.module.scss +++ b/src/client/components/features/Actualites/ActualiteCard.module.scss @@ -5,7 +5,6 @@ } .card .content { @include utilities.text-medium; - // FIXME (GAFI 11-12-2024): Idéalement .content est sur

plutôt que parent du titre & p { @include utilities.line-clamp(3, 1.2); } @@ -33,16 +32,19 @@ object-fit: cover; } - .content { - padding-block: 1.25rem; + & .content { + padding-bottom: 1.25rem; + padding-top: .5rem; padding-inline: 1.5rem; display: flex; + gap: .5rem; flex: 1; flex-direction: column; } - .title { - margin-bottom: 0.5rem; + & time { + align-self: flex-end; + @include utilities.text-small; } & a { diff --git a/src/client/components/features/Actualites/ActualiteCard.stories.tsx b/src/client/components/features/Actualites/ActualiteCard.stories.tsx index bda6969d40..7a53910e20 100644 --- a/src/client/components/features/Actualites/ActualiteCard.stories.tsx +++ b/src/client/components/features/Actualites/ActualiteCard.stories.tsx @@ -1,7 +1,10 @@ import { Meta, StoryObj } from '@storybook/react'; import React from 'react'; -import { anActualite } from '../../../../server/actualites/domain/actualite.fixture'; +import { DependenciesProvider } from '~/client/context/dependenciesContainer.context'; +import { JsDateService } from '~/client/services/date/js/js.date.service'; +import { anActualite } from '~/server/actualites/domain/actualite.fixture'; + import ActualiteCard from './ActualiteCard'; const meta: Meta = { @@ -14,6 +17,11 @@ const meta: Meta = { actualite: anActualite(), }, component: ActualiteCard, + render: (args) => ( + + + + ), title: 'Components/Cards/ActualiteCard', }; @@ -34,3 +42,8 @@ export const ContenuCourt: Story = { }), }, }; +export const avecDateMiseAJour: Story = { + args: { + actualite: anActualite({ dateMiseAJour: new Date('2024-01-01') }), + }, +}; diff --git a/src/client/components/features/Actualites/ActualiteCard.tsx b/src/client/components/features/Actualites/ActualiteCard.tsx index 324e490840..91797fbe9a 100644 --- a/src/client/components/features/Actualites/ActualiteCard.tsx +++ b/src/client/components/features/Actualites/ActualiteCard.tsx @@ -3,6 +3,8 @@ import React from 'react'; import { Card } from '~/client/components/ui/Card/Card'; import { Link } from '~/client/components/ui/Link/Link'; +import { useDependency } from '~/client/context/dependenciesContainer.context'; +import { DateService } from '~/client/services/date/date.service'; import { Actualite } from '~/server/actualites/domain/actualite'; import { getExtraitContenu } from '~/server/cms/infra/repositories/strapi.utils'; @@ -16,6 +18,8 @@ type ActualiteCardProps = Omit, 'layout }; export default function ActualiteCard({ actualite, headingLevel = 'h2', className, ...rest }: ActualiteCardProps) { + const dateService = useDependency('dateService'); + // FIXME (GAFI 14-11-2024): Passer plutôt par actualite.lien, actualite.article n'est pas utilisé dans le composant // ou bien utiliser actualite.article.slug dans le composant const isExternalLink = actualite.article == null; @@ -23,23 +27,25 @@ export default function ActualiteCard({ actualite, headingLevel = 'h2', classNam const extrait = getExtraitContenu(actualite.contenu); return ( - - {actualite.bannière && ( - - )} - - {actualite.titre} -

{extrait}

- - {isExternalLink ? 'En savoir plus' : "Lire l'article"} - - - - +
+ + {actualite.bannière && ( + + )} + + {actualite.dateMiseAJour && } + {actualite.titre} +

{extrait}

+ + {isExternalLink ? 'En savoir plus' : 'Lire l\'article'} + + +
+
+
); } From 22985658e9c8f5171a7cab18d3937fe56d315fe5 Mon Sep 17 00:00:00 2001 From: Gauthier Fiorentino Date: Tue, 17 Dec 2024 11:16:48 +0100 Subject: [PATCH 4/8] refactor: Extrait la date dans un composant --- .../features/Actualites/ActualiteCard.tsx | 7 ++-- .../components/ui/Date/index.stories.tsx | 30 ++++++++++++++++ src/client/components/ui/Date/index.test.tsx | 35 +++++++++++++++++++ src/client/components/ui/Date/index.tsx | 16 +++++++++ 4 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 src/client/components/ui/Date/index.stories.tsx create mode 100644 src/client/components/ui/Date/index.test.tsx create mode 100644 src/client/components/ui/Date/index.tsx diff --git a/src/client/components/features/Actualites/ActualiteCard.tsx b/src/client/components/features/Actualites/ActualiteCard.tsx index 91797fbe9a..997525bb58 100644 --- a/src/client/components/features/Actualites/ActualiteCard.tsx +++ b/src/client/components/features/Actualites/ActualiteCard.tsx @@ -2,9 +2,8 @@ import classNames from 'classnames'; import React from 'react'; import { Card } from '~/client/components/ui/Card/Card'; +import Date from '~/client/components/ui/Date'; import { Link } from '~/client/components/ui/Link/Link'; -import { useDependency } from '~/client/context/dependenciesContainer.context'; -import { DateService } from '~/client/services/date/date.service'; import { Actualite } from '~/server/actualites/domain/actualite'; import { getExtraitContenu } from '~/server/cms/infra/repositories/strapi.utils'; @@ -18,8 +17,6 @@ type ActualiteCardProps = Omit, 'layout }; export default function ActualiteCard({ actualite, headingLevel = 'h2', className, ...rest }: ActualiteCardProps) { - const dateService = useDependency('dateService'); - // FIXME (GAFI 14-11-2024): Passer plutôt par actualite.lien, actualite.article n'est pas utilisé dans le composant // ou bien utiliser actualite.article.slug dans le composant const isExternalLink = actualite.article == null; @@ -37,7 +34,7 @@ export default function ActualiteCard({ actualite, headingLevel = 'h2', classNam height={180} /> )} - {actualite.dateMiseAJour && } + {actualite.dateMiseAJour && } {actualite.titre}

{extrait}

diff --git a/src/client/components/ui/Date/index.stories.tsx b/src/client/components/ui/Date/index.stories.tsx new file mode 100644 index 0000000000..932fcc8adf --- /dev/null +++ b/src/client/components/ui/Date/index.stories.tsx @@ -0,0 +1,30 @@ +import { Meta, StoryObj } from '@storybook/react'; +import React from 'react'; + +import { DependenciesProvider } from '~/client/context/dependenciesContainer.context'; +import { JsDateService } from '~/client/services/date/js/js.date.service'; + +import DateComponent from '.'; + +const meta: Meta = { + argTypes: { + date: { + control: 'date', + }, + }, + args: { + date: new Date(), + }, + component: DateComponent, + render: ({ date, ...args }) => ( + + + + ), + title: 'Components/Date', +}; + +export default meta; + +type Story = StoryObj>; +export const Default: Story = {}; diff --git a/src/client/components/ui/Date/index.test.tsx b/src/client/components/ui/Date/index.test.tsx new file mode 100644 index 0000000000..8c9b496904 --- /dev/null +++ b/src/client/components/ui/Date/index.test.tsx @@ -0,0 +1,35 @@ +/** + * @jest-environment jsdom + */ + +import { render, screen } from '@testing-library/react'; + +import { DependenciesProvider } from '~/client/context/dependenciesContainer.context'; +import { JsDateService } from '~/client/services/date/js/js.date.service'; + +import DateComponent from '.'; + +describe('', () => { + it('affiche la date dans un format compréhensible', () => { + const date = new Date('2024-01-01'); + + render( + + + , + ); + + expect(screen.getByRole('time')).toHaveTextContent('1 janvier 2024'); + }); + it('indique la date programmatiquement au format ISO', () => { + const date = new Date('2024-01-01'); + + render( + + + , + ); + + expect(screen.getByRole('time')).toHaveAttribute('datetime', '2024-01-01T00:00:00.000Z'); + }); +}); diff --git a/src/client/components/ui/Date/index.tsx b/src/client/components/ui/Date/index.tsx new file mode 100644 index 0000000000..fc751f3851 --- /dev/null +++ b/src/client/components/ui/Date/index.tsx @@ -0,0 +1,16 @@ +import React from 'react'; + +import { useDependency } from '~/client/context/dependenciesContainer.context'; +import { DateService } from '~/client/services/date/date.service'; + +type DateProps = React.ComponentPropsWithoutRef<'time'> & { + date: Date, +} + +export default function Date({ date, ...props }: DateProps) { + const dateService = useDependency('dateService'); + + return ( + + ); +}; From 26d60024ce66d3e0ae4b9b73bd909461845b93de Mon Sep 17 00:00:00 2001 From: Gauthier Fiorentino Date: Tue, 17 Dec 2024 14:36:30 +0100 Subject: [PATCH 5/8] wip: Ajoute du padding quand pas de date --- .../components/features/Actualites/ActualiteCard.module.scss | 5 +++++ src/client/components/features/Actualites/ActualiteCard.tsx | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/client/components/features/Actualites/ActualiteCard.module.scss b/src/client/components/features/Actualites/ActualiteCard.module.scss index 7a1ac4300a..9ce6370ec8 100644 --- a/src/client/components/features/Actualites/ActualiteCard.module.scss +++ b/src/client/components/features/Actualites/ActualiteCard.module.scss @@ -46,6 +46,11 @@ align-self: flex-end; @include utilities.text-small; } + & time:empty { + visibility: hidden; + // NOTE (GAFI 17-12-2024): equivalent à 1lh dans ce cas précis mais meilleur support + height: 1.2em; + } & a { margin-top: 1.25rem; diff --git a/src/client/components/features/Actualites/ActualiteCard.tsx b/src/client/components/features/Actualites/ActualiteCard.tsx index 997525bb58..7acd87d469 100644 --- a/src/client/components/features/Actualites/ActualiteCard.tsx +++ b/src/client/components/features/Actualites/ActualiteCard.tsx @@ -34,7 +34,7 @@ export default function ActualiteCard({ actualite, headingLevel = 'h2', classNam height={180} /> )} - {actualite.dateMiseAJour && } + {actualite.dateMiseAJour ? : } {actualite.titre}

{extrait}

From cd33da18116713b52e47c4eed5403596631fda2a Mon Sep 17 00:00:00 2001 From: Gauthier Fiorentino Date: Tue, 17 Dec 2024 16:30:26 +0100 Subject: [PATCH 6/8] =?UTF-8?q?wip:=20Ajoute=20la=20des=C3=A9rialisation?= =?UTF-8?q?=20des=20actus=20sur=20les=20pages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/actualites/index.page.test.tsx | 2 +- src/pages/actualites/index.page.tsx | 28 ++++++++++++++++-- src/pages/espace-jeune/index.page.test.tsx | 2 +- src/pages/espace-jeune/index.page.tsx | 34 ++++++++++++++++++---- src/pages/index.page.tsx | 4 +-- 5 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/pages/actualites/index.page.test.tsx b/src/pages/actualites/index.page.test.tsx index 02406237da..289760c8d3 100644 --- a/src/pages/actualites/index.page.test.tsx +++ b/src/pages/actualites/index.page.test.tsx @@ -9,7 +9,7 @@ import { mockUseRouter } from '~/client/components/useRouter.mock'; import { mockScrollIntoView, mockSmallScreen } from '~/client/components/window.mock'; import { DependenciesProvider } from '~/client/context/dependenciesContainer.context'; import { aManualAnalyticsService } from '~/client/services/analytics/analytics.service.fixture'; -import ActualitesPage, { getStaticProps } from '~/pages/actualites/index.page'; +import { ActualitesPage, getStaticProps } from '~/pages/actualites/index.page'; import { anActualite, anActualiteList } from '~/server/actualites/domain/actualite.fixture'; import { createFailure, createSuccess } from '~/server/errors/either'; import { ErreurMetier } from '~/server/errors/erreurMetier.types'; diff --git a/src/pages/actualites/index.page.tsx b/src/pages/actualites/index.page.tsx index e71393829f..2d5b73ef59 100644 --- a/src/pages/actualites/index.page.tsx +++ b/src/pages/actualites/index.page.tsx @@ -10,16 +10,38 @@ import useAnalytics from '~/client/hooks/useAnalytics'; import { Actualite } from '~/server/actualites/domain/actualite'; import { isFailure } from '~/server/errors/either'; import { dependencies } from '~/server/start'; +import { ISODateTime } from '~/shared/ISODateTime'; import analytics from './index.analytics'; import styles from './index.module.scss'; +type SerializedActualite = Omit & { + dateMiseAJour?: ISODateTime +} +interface SerializedActualitesPageProps { + cartesActualites: Array +} interface ActualitesPageProps { cartesActualites: Array } const MAX_VISIBLE_ACTUALITES = 3; -export default function ActualitesPage({ cartesActualites }: ActualitesPageProps) { + +function deserialize(actualites: Array): Array { + return actualites.map((actualite) => ({ + ...actualite, + dateMiseAJour: actualite.dateMiseAJour ? new Date(actualite.dateMiseAJour) : undefined, + })); +} +function serialize(cartesActualitesResponse: Array): Array { + return JSON.parse(JSON.stringify(cartesActualitesResponse)); +} + +export default function Deserialize(props: SerializedActualitesPageProps) { + const deserializedActus = deserialize(props.cartesActualites); + return ; +} +export function ActualitesPage({ cartesActualites }: ActualitesPageProps) { useAnalytics(analytics); const articleCardList = useMemo(() => { @@ -54,7 +76,7 @@ export default function ActualitesPage({ cartesActualites }: ActualitesPageProps ); } -export async function getStaticProps(): Promise> { +export async function getStaticProps(): Promise> { const isEspaceJeuneVisible = process.env.NEXT_PUBLIC_OLD_ESPACE_JEUNE_FEATURE === '0'; if (!isEspaceJeuneVisible) { return { notFound: true }; @@ -68,7 +90,7 @@ export async function getStaticProps(): Promise serviceJeuneList: Array } +type SerializedActualite = Omit & { + dateMiseAJour?: ISODateTime +} +type SerializedEspaceJeunePageProps = { + cartesActualites: Array + serviceJeuneList: Array +} + const MAX_VISIBLE_ACTUALITES_LENGTH = 3; +function deserialize(actualites: Array): Array { + return actualites.map((actualite) => ({ + ...actualite, + dateMiseAJour: actualite.dateMiseAJour ? new Date(actualite.dateMiseAJour) : undefined, + })); +} +function serialize(cartesActualitesResponse: unknown): Record { + return JSON.parse(JSON.stringify(cartesActualitesResponse)); +} + +export default function Deserialize(props: SerializedEspaceJeunePageProps) { + const deserializedActus = deserialize(props.cartesActualites); + return ; +} -export default function EspaceJeunePage({ cartesActualites, serviceJeuneList }: EspaceJeunePageProps) { +export function EspaceJeunePage({ cartesActualites, serviceJeuneList }: EspaceJeunePageProps) { useAnalytics(analytics); const articleCardList: React.ReactNode[] = useMemo(() => { @@ -87,8 +111,8 @@ export async function getStaticProps(): Promise & { - dateMiseAJour: ISODateTime + dateMiseAJour?: ISODateTime } interface SerializedAccueilPageProps { actualites: Array @@ -38,7 +38,7 @@ interface AccueilPageProps { function deserialize(actualites: Array): Array { return actualites.map((actualite) => ({ ...actualite, - dateMiseAJour: new Date(actualite.dateMiseAJour), + dateMiseAJour: actualite.dateMiseAJour ? new Date(actualite.dateMiseAJour) : undefined, })); } function serialize(cartesActualitesResponse: Array): Array { From 6f9479560718c27a019c123459673566d5242541 Mon Sep 17 00:00:00 2001 From: Gauthier Fiorentino Date: Tue, 17 Dec 2024 16:30:52 +0100 Subject: [PATCH 7/8] =?UTF-8?q?refactor:=20Utilise=20le=20lien=20pour=20d?= =?UTF-8?q?=C3=A9finir=20le=20type=20de=20redirection?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/features/Actualites/ActualiteCard.tsx | 7 +++---- src/pages/espace-jeune/index.page.tsx | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/client/components/features/Actualites/ActualiteCard.tsx b/src/client/components/features/Actualites/ActualiteCard.tsx index 7acd87d469..a109d59d8a 100644 --- a/src/client/components/features/Actualites/ActualiteCard.tsx +++ b/src/client/components/features/Actualites/ActualiteCard.tsx @@ -4,6 +4,7 @@ import React from 'react'; import { Card } from '~/client/components/ui/Card/Card'; import Date from '~/client/components/ui/Date'; import { Link } from '~/client/components/ui/Link/Link'; +import { useIsInternalLink } from '~/client/hooks/useIsInternalLink'; import { Actualite } from '~/server/actualites/domain/actualite'; import { getExtraitContenu } from '~/server/cms/infra/repositories/strapi.utils'; @@ -17,9 +18,7 @@ type ActualiteCardProps = Omit, 'layout }; export default function ActualiteCard({ actualite, headingLevel = 'h2', className, ...rest }: ActualiteCardProps) { - // FIXME (GAFI 14-11-2024): Passer plutôt par actualite.lien, actualite.article n'est pas utilisé dans le composant - // ou bien utiliser actualite.article.slug dans le composant - const isExternalLink = actualite.article == null; + const isInternalLink = useIsInternalLink(actualite.link); const extrait = getExtraitContenu(actualite.contenu); @@ -38,7 +37,7 @@ export default function ActualiteCard({ actualite, headingLevel = 'h2', classNam {actualite.titre}

{extrait}

- {isExternalLink ? 'En savoir plus' : 'Lire l\'article'} + {isInternalLink ? 'Lire l\'article' : 'En savoir plus'}
diff --git a/src/pages/espace-jeune/index.page.tsx b/src/pages/espace-jeune/index.page.tsx index 777adbf36f..9bd58a9d5f 100644 --- a/src/pages/espace-jeune/index.page.tsx +++ b/src/pages/espace-jeune/index.page.tsx @@ -39,7 +39,7 @@ function deserialize(actualites: Array): Array { dateMiseAJour: actualite.dateMiseAJour ? new Date(actualite.dateMiseAJour) : undefined, })); } -function serialize(cartesActualitesResponse: unknown): Record { +function serialize(cartesActualitesResponse: InitialType): SerializedType { return JSON.parse(JSON.stringify(cartesActualitesResponse)); } @@ -96,7 +96,7 @@ export function EspaceJeunePage({ cartesActualites, serviceJeuneList }: EspaceJe ); } -export async function getStaticProps(): Promise> { +export async function getStaticProps(): Promise> { const isEspaceJeuneVisible = process.env.NEXT_PUBLIC_OLD_ESPACE_JEUNE_FEATURE === '1'; if (!isEspaceJeuneVisible) { return { notFound: true }; From 55bacc6b391bb18c4b86f09ecd44828130849954 Mon Sep 17 00:00:00 2001 From: Gauthier Fiorentino Date: Wed, 18 Dec 2024 18:55:32 +0100 Subject: [PATCH 8/8] refactor: Review --- src/pages/actualites/index.page.tsx | 40 ++++++++-------- src/pages/espace-jeune/index.page.tsx | 43 ++++++++--------- src/pages/index.page.tsx | 67 +++++++++++++-------------- src/shared/ISODateTime.d.ts | 4 +- 4 files changed, 74 insertions(+), 80 deletions(-) diff --git a/src/pages/actualites/index.page.tsx b/src/pages/actualites/index.page.tsx index 2d5b73ef59..89742c63b4 100644 --- a/src/pages/actualites/index.page.tsx +++ b/src/pages/actualites/index.page.tsx @@ -15,32 +15,11 @@ import { ISODateTime } from '~/shared/ISODateTime'; import analytics from './index.analytics'; import styles from './index.module.scss'; -type SerializedActualite = Omit & { - dateMiseAJour?: ISODateTime -} -interface SerializedActualitesPageProps { - cartesActualites: Array -} interface ActualitesPageProps { cartesActualites: Array } - const MAX_VISIBLE_ACTUALITES = 3; -function deserialize(actualites: Array): Array { - return actualites.map((actualite) => ({ - ...actualite, - dateMiseAJour: actualite.dateMiseAJour ? new Date(actualite.dateMiseAJour) : undefined, - })); -} -function serialize(cartesActualitesResponse: Array): Array { - return JSON.parse(JSON.stringify(cartesActualitesResponse)); -} - -export default function Deserialize(props: SerializedActualitesPageProps) { - const deserializedActus = deserialize(props.cartesActualites); - return ; -} export function ActualitesPage({ cartesActualites }: ActualitesPageProps) { useAnalytics(analytics); @@ -76,6 +55,25 @@ export function ActualitesPage({ cartesActualites }: ActualitesPageProps) { ); } +type SerializedActualite = Omit & { + dateMiseAJour?: ISODateTime +} +interface SerializedActualitesPageProps { + cartesActualites: Array +} +function deserialize(actualites: Array): Array { + return actualites.map((actualite) => ({ + ...actualite, + dateMiseAJour: actualite.dateMiseAJour ? new Date(actualite.dateMiseAJour) : undefined, + })); +} +function serialize(cartesActualitesResponse: Array): Array { + return JSON.parse(JSON.stringify(cartesActualitesResponse)); +} +export default function Deserialize(props: SerializedActualitesPageProps) { + const deserializedActus = deserialize(props.cartesActualites); + return ; +} export async function getStaticProps(): Promise> { const isEspaceJeuneVisible = process.env.NEXT_PUBLIC_OLD_ESPACE_JEUNE_FEATURE === '0'; if (!isEspaceJeuneVisible) { diff --git a/src/pages/espace-jeune/index.page.tsx b/src/pages/espace-jeune/index.page.tsx index 9bd58a9d5f..6f48a5643b 100644 --- a/src/pages/espace-jeune/index.page.tsx +++ b/src/pages/espace-jeune/index.page.tsx @@ -23,30 +23,7 @@ type EspaceJeunePageProps = { cartesActualites: Array serviceJeuneList: Array } -type SerializedActualite = Omit & { - dateMiseAJour?: ISODateTime -} -type SerializedEspaceJeunePageProps = { - cartesActualites: Array - serviceJeuneList: Array -} - - const MAX_VISIBLE_ACTUALITES_LENGTH = 3; -function deserialize(actualites: Array): Array { - return actualites.map((actualite) => ({ - ...actualite, - dateMiseAJour: actualite.dateMiseAJour ? new Date(actualite.dateMiseAJour) : undefined, - })); -} -function serialize(cartesActualitesResponse: InitialType): SerializedType { - return JSON.parse(JSON.stringify(cartesActualitesResponse)); -} - -export default function Deserialize(props: SerializedEspaceJeunePageProps) { - const deserializedActus = deserialize(props.cartesActualites); - return ; -} export function EspaceJeunePage({ cartesActualites, serviceJeuneList }: EspaceJeunePageProps) { useAnalytics(analytics); @@ -96,6 +73,26 @@ export function EspaceJeunePage({ cartesActualites, serviceJeuneList }: EspaceJe ); } +type SerializedActualite = Omit & { + dateMiseAJour?: ISODateTime +} +type SerializedEspaceJeunePageProps = { + cartesActualites: Array + serviceJeuneList: Array +} +function deserialize(actualites: Array): Array { + return actualites.map((actualite) => ({ + ...actualite, + dateMiseAJour: actualite.dateMiseAJour ? new Date(actualite.dateMiseAJour) : undefined, + })); +} +function serialize(cartesActualitesResponse: InitialType): SerializedType { + return JSON.parse(JSON.stringify(cartesActualitesResponse)); +} +export default function Deserialize(props: SerializedEspaceJeunePageProps) { + const deserializedActus = deserialize(props.cartesActualites); + return ; +} export async function getStaticProps(): Promise> { const isEspaceJeuneVisible = process.env.NEXT_PUBLIC_OLD_ESPACE_JEUNE_FEATURE === '1'; if (!isEspaceJeuneVisible) { diff --git a/src/pages/index.page.tsx b/src/pages/index.page.tsx index e128ab4537..64faeb145f 100644 --- a/src/pages/index.page.tsx +++ b/src/pages/index.page.tsx @@ -26,30 +26,9 @@ interface CardContent { title: string } -type SerializedActualite = Omit & { - dateMiseAJour?: ISODateTime -} -interface SerializedAccueilPageProps { - actualites: Array -} interface AccueilPageProps { actualites: Array } -function deserialize(actualites: Array): Array { - return actualites.map((actualite) => ({ - ...actualite, - dateMiseAJour: actualite.dateMiseAJour ? new Date(actualite.dateMiseAJour) : undefined, - })); -} -function serialize(cartesActualitesResponse: Array): Array { - return JSON.parse(JSON.stringify(cartesActualitesResponse)); -} - -export default function Deserialize(props: SerializedAccueilPageProps) { - const deserializedActus = deserialize(props.actualites); - return ; -} - export function Accueil({ actualites }: AccueilPageProps) { useAnalytics(analytics); @@ -297,20 +276,20 @@ export function Accueil({ actualites }: AccueilPageProps) { {isBanniereStagesSecondeVisible && ( + className={classNames(styles.hero, styles.stageSecondeBanner)}> {isBanniereStagesSecondePourCampagneDu25Mars ? ( <>

- Un stage du 17 au 28 juin 2024 + Un stage du 17 au 28 juin 2024

- pour permettre aux élèves de seconde générale et technologique de diversifier leur connaissance des - métiers. + pour permettre aux élèves de seconde générale et technologique de diversifier leur connaissance des + métiers. - Proposer un stage ou candidater + Proposer un stage ou candidater @@ -318,14 +297,14 @@ export function Accueil({ actualites }: AccueilPageProps) { <>

- Accueillez des élèves en stages de seconde générale et technologique. + Accueillez des élèves en stages de seconde générale et technologique.

- Inspirez, transmettez, faites découvrir vos métiers. + Inspirez, transmettez, faites découvrir vos métiers. - Déposer votre offre de stage + Déposer votre offre de stage @@ -339,14 +318,14 @@ export function Accueil({ actualites }: AccueilPageProps) {

- WorldSkills Lyon 2024, la Compétition Mondiale des Métiers. + WorldSkills Lyon 2024, la Compétition Mondiale des Métiers.

- 1jeune1solution s’engage en faveur de la jeunesse, venez nous rencontrer du 10 au 15 septembre lors de la compétition WorldSkills Lyon 2024. + 1jeune1solution s’engage en faveur de la jeunesse, venez nous rencontrer du 10 au 15 septembre lors de la compétition WorldSkills Lyon 2024. - Plus d’infos + Plus d’infos
@@ -393,7 +372,7 @@ export function Accueil({ actualites }: AccueilPageProps) {

- Actualités + Actualités

    @@ -402,7 +381,7 @@ export function Accueil({ actualites }: AccueilPageProps) { )}
- Voir toutes les actualités + Voir toutes les actualités
@@ -492,6 +471,26 @@ export function Accueil({ actualites }: AccueilPageProps) { ); } +type SerializedActualite = Omit & { + dateMiseAJour?: ISODateTime +} +interface SerializedAccueilPageProps { + actualites: Array +} +function deserialize(actualites: Array): Array { + return actualites.map((actualite) => ({ + ...actualite, + dateMiseAJour: actualite.dateMiseAJour ? new Date(actualite.dateMiseAJour) : undefined, + })); +} +function serialize(cartesActualitesResponse: Array): Array { + return JSON.parse(JSON.stringify(cartesActualitesResponse)); +} +export default function Deserialize(props: SerializedAccueilPageProps) { + const deserializedActus = deserialize(props.actualites); + return ; +} + export async function getStaticProps(): Promise> { const isEspaceJeuneVisible = process.env.NEXT_PUBLIC_OLD_ESPACE_JEUNE_FEATURE === '0'; if (!isEspaceJeuneVisible) { diff --git a/src/shared/ISODateTime.d.ts b/src/shared/ISODateTime.d.ts index 5c8ec9cec3..b9a9522350 100644 --- a/src/shared/ISODateTime.d.ts +++ b/src/shared/ISODateTime.d.ts @@ -5,7 +5,7 @@ type Hour = string; type Minute = string; type Second = string; type Millisecond = string; -type Timezone = string; +type Offset = string; type ISODate = `${Year}-${Month}-${Day}` type ISOTime = `${Hour}:${Minute}:${Second}.${Millisecond}` -export type ISODateTime = `${ISODate}T${ISOTime}${Timezone}` +export type ISODateTime = `${ISODate}T${ISOTime}${Offset}`