From d6a6b748fcf1c9af90818884da7abbb3751f607d Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Wed, 9 Oct 2024 12:57:01 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(frontend)=20add=20back=20the=20footer?= =?UTF-8?q?=20and=20cgu=20pages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to add back the footer and cgu pages, but we will not display the footer on the doc editor pages. --- .../e2e/__tests__/app-impress/footer.spec.ts | 77 ++++++++ .../impress/src/features/footer/Footer.tsx | 166 ++++++++++++++++++ .../features/footer/assets/external-link.svg | 5 + .../impress/src/features/footer/index.tsx | 1 + .../features/service-worker/service-worker.ts | 3 + .../apps/impress/src/layouts/MainLayout.tsx | 13 +- .../apps/impress/src/layouts/PageLayout.tsx | 17 ++ .../apps/impress/src/layouts/index.ts | 1 + .../impress/src/pages/accessibility/index.tsx | 133 ++++++++++++++ .../impress/src/pages/docs/[id]/index.tsx | 2 +- .../impress/src/pages/legal-notice/index.tsx | 72 ++++++++ .../src/pages/personal-data-cookies/index.tsx | 66 +++++++ 12 files changed, 554 insertions(+), 2 deletions(-) create mode 100644 src/frontend/apps/e2e/__tests__/app-impress/footer.spec.ts create mode 100644 src/frontend/apps/impress/src/features/footer/Footer.tsx create mode 100644 src/frontend/apps/impress/src/features/footer/assets/external-link.svg create mode 100644 src/frontend/apps/impress/src/features/footer/index.tsx create mode 100644 src/frontend/apps/impress/src/layouts/PageLayout.tsx create mode 100644 src/frontend/apps/impress/src/pages/accessibility/index.tsx create mode 100644 src/frontend/apps/impress/src/pages/legal-notice/index.tsx create mode 100644 src/frontend/apps/impress/src/pages/personal-data-cookies/index.tsx diff --git a/src/frontend/apps/e2e/__tests__/app-impress/footer.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/footer.spec.ts new file mode 100644 index 000000000..0862051f4 --- /dev/null +++ b/src/frontend/apps/e2e/__tests__/app-impress/footer.spec.ts @@ -0,0 +1,77 @@ +import { expect, test } from '@playwright/test'; + +import { goToGridDoc } from './common'; + +test.beforeEach(async ({ page }) => { + await page.goto('/'); +}); + +test.describe('Footer', () => { + test('checks all the elements are visible', async ({ page }) => { + const footer = page.locator('footer').first(); + + await expect(footer.getByAltText('Gouvernement Logo')).toBeVisible(); + + await expect( + footer.getByRole('link', { name: 'legifrance.gouv.fr' }), + ).toBeVisible(); + + await expect( + footer.getByRole('link', { name: 'info.gouv.fr' }), + ).toBeVisible(); + + await expect( + footer.getByRole('link', { name: 'service-public.fr' }), + ).toBeVisible(); + + await expect( + footer.getByRole('link', { name: 'data.gouv.fr' }), + ).toBeVisible(); + + await expect( + footer.getByRole('link', { name: 'Legal Notice' }), + ).toBeVisible(); + + await expect( + footer.getByRole('link', { name: 'Personal data and cookies' }), + ).toBeVisible(); + + await expect( + footer.getByRole('link', { name: 'Accessibility' }), + ).toBeVisible(); + + await expect( + footer.getByText( + 'Unless otherwise stated, all content on this site is under licence', + ), + ).toBeVisible(); + }); + + test('checks footer is not visible on doc editor', async ({ page }) => { + await expect(page.locator('footer')).toBeVisible(); + await goToGridDoc(page); + await expect(page.locator('footer')).toBeHidden(); + }); + + const legalPages = [ + { name: 'Legal Notice', url: '/legal-notice/' }, + { name: 'Personal data and cookies', url: '/personal-data-cookies/' }, + { name: 'Accessibility', url: '/accessibility/' }, + ]; + for (const { name, url } of legalPages) { + test(`checks ${name} page`, async ({ page }) => { + const footer = page.locator('footer').first(); + await footer.getByRole('link', { name }).click(); + + await expect( + page + .getByRole('heading', { + name, + }) + .first(), + ).toBeVisible(); + + await expect(page).toHaveURL(url); + }); + } +}); diff --git a/src/frontend/apps/impress/src/features/footer/Footer.tsx b/src/frontend/apps/impress/src/features/footer/Footer.tsx new file mode 100644 index 000000000..acc9c9704 --- /dev/null +++ b/src/frontend/apps/impress/src/features/footer/Footer.tsx @@ -0,0 +1,166 @@ +import Image from 'next/image'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import styled from 'styled-components'; + +import { Box, StyledLink, Text } from '@/components/'; +import { useCunninghamTheme } from '@/cunningham'; + +import IconLink from './assets/external-link.svg'; + +const BlueStripe = styled.div` + position: absolute; + height: 2px; + width: 100%; + background: var(--c--theme--colors--primary-600); + top: 0; +`; + +export const Footer = () => { + const { t } = useTranslation(); + const { themeTokens } = useCunninghamTheme(); + const logo = themeTokens().logo; + + return ( + + + + + + + {logo && ( + {logo.alt} + )} + + + + {[ + { + label: 'legifrance.gouv.fr', + href: 'https://legifrance.gouv.fr/', + }, + { + label: 'info.gouv.fr', + href: 'https://info.gouv.fr/', + }, + { + label: 'service-public.fr', + href: 'https://service-public.fr/', + }, + { + label: 'data.gouv.fr', + href: 'https://data.gouv.fr/', + }, + ].map(({ label, href }) => ( + + {label} + + + ))} + + + + {[ + { + label: t('Legal Notice'), + href: '/legal-notice', + }, + { + label: t('Personal data and cookies'), + href: '/personal-data-cookies', + }, + { + label: t('Accessibility'), + href: '/accessibility', + }, + ].map(({ label, href }) => ( + + + {label} + + + ))} + + + {t('Unless otherwise stated, all content on this site is under')}{' '} + + licence etalab-2.0 + + + + + + ); +}; diff --git a/src/frontend/apps/impress/src/features/footer/assets/external-link.svg b/src/frontend/apps/impress/src/features/footer/assets/external-link.svg new file mode 100644 index 000000000..25093d139 --- /dev/null +++ b/src/frontend/apps/impress/src/features/footer/assets/external-link.svg @@ -0,0 +1,5 @@ + + + diff --git a/src/frontend/apps/impress/src/features/footer/index.tsx b/src/frontend/apps/impress/src/features/footer/index.tsx new file mode 100644 index 000000000..ddcc5a9cd --- /dev/null +++ b/src/frontend/apps/impress/src/features/footer/index.tsx @@ -0,0 +1 @@ +export * from './Footer'; diff --git a/src/frontend/apps/impress/src/features/service-worker/service-worker.ts b/src/frontend/apps/impress/src/features/service-worker/service-worker.ts index 7d42d62cf..94b9c37c7 100644 --- a/src/frontend/apps/impress/src/features/service-worker/service-worker.ts +++ b/src/frontend/apps/impress/src/features/service-worker/service-worker.ts @@ -94,6 +94,9 @@ const precacheResources = [ '/', '/index.html', '/404/', + '/accessibility/', + '/legal-notice/', + '/personal-data-cookies/', FALLBACK.offline, FALLBACK.images, FALLBACK.docs, diff --git a/src/frontend/apps/impress/src/layouts/MainLayout.tsx b/src/frontend/apps/impress/src/layouts/MainLayout.tsx index 5176557e6..bdfe587cc 100644 --- a/src/frontend/apps/impress/src/layouts/MainLayout.tsx +++ b/src/frontend/apps/impress/src/layouts/MainLayout.tsx @@ -1,8 +1,18 @@ +import { PropsWithChildren } from 'react'; + import { Box } from '@/components'; import { useCunninghamTheme } from '@/cunningham'; +import { Footer } from '@/features/footer'; import { Header } from '@/features/header'; -export function MainLayout({ children }: { children: React.ReactNode }) { +interface MainLayoutProps { + withoutFooter?: boolean; +} + +export function MainLayout({ + children, + withoutFooter, +}: PropsWithChildren) { const { colorsTokens } = useCunninghamTheme(); return ( @@ -20,6 +30,7 @@ export function MainLayout({ children }: { children: React.ReactNode }) { + {!withoutFooter &&