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 00000000..5aa6d546 --- /dev/null +++ b/src/frontend/apps/e2e/__tests__/app-impress/footer.spec.ts @@ -0,0 +1,42 @@ +import { expect, test } from '@playwright/test'; + +import { keyCloakSignIn } from './common'; + +test.beforeEach(async ({ page, browserName }) => { + await page.goto('/'); + await keyCloakSignIn(page, browserName); +}); + +test.describe('Footer', () => { + test('checks all the elements are visible', async ({ page }) => { + const footer = page.locator('footer').first(); + + await expect(footer.getByAltText('Marianne Logo')).toBeVisible(); + + await expect( + footer.getByAltText('Freedom Equality Fraternity 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.getByText( + 'Unless otherwise stated, all content on this site is under licence', + ), + ).toBeVisible(); + }); +}); diff --git a/src/frontend/apps/impress/src/features/header/assets/icon-gouv.svg b/src/frontend/apps/impress/src/assets/icons/icon-gouv.svg similarity index 100% rename from src/frontend/apps/impress/src/features/header/assets/icon-gouv.svg rename to src/frontend/apps/impress/src/assets/icons/icon-gouv.svg diff --git a/src/frontend/apps/impress/src/features/header/assets/icon-marianne.svg b/src/frontend/apps/impress/src/assets/icons/icon-marianne.svg similarity index 100% rename from src/frontend/apps/impress/src/features/header/assets/icon-marianne.svg rename to src/frontend/apps/impress/src/assets/icons/icon-marianne.svg diff --git a/src/frontend/apps/impress/src/components/Box.tsx b/src/frontend/apps/impress/src/components/Box.tsx index 44ef3cf0..0191d77f 100644 --- a/src/frontend/apps/impress/src/components/Box.tsx +++ b/src/frontend/apps/impress/src/components/Box.tsx @@ -33,6 +33,7 @@ export interface BoxProps { $radius?: CSSProperties['borderRadius']; $transition?: CSSProperties['transition']; $width?: CSSProperties['width']; + $zIndex?: CSSProperties['zIndex']; } export type BoxType = ComponentPropsWithRef; @@ -61,6 +62,7 @@ export const Box = styled('div')` ${({ $transition }) => $transition && `transition: ${$transition};`} ${({ $width }) => $width && `width: ${$width};`} ${({ $css }) => $css && `${$css};`} + ${({ $zIndex }) => $zIndex && `z-index: ${$zIndex};`} ${({ $effect }) => { let effect; switch ($effect) { diff --git a/src/frontend/apps/impress/src/components/Link.tsx b/src/frontend/apps/impress/src/components/Link.tsx index 8081db2c..b84de0d5 100644 --- a/src/frontend/apps/impress/src/components/Link.tsx +++ b/src/frontend/apps/impress/src/components/Link.tsx @@ -1,11 +1,16 @@ import Link from 'next/link'; import styled from 'styled-components'; -export const StyledLink = styled(Link)` +export interface LinkProps { + $css?: string; +} + +export const StyledLink = styled(Link)` text-decoration: none; color: #ffffff33; &[aria-current='page'] { color: #ffffff; } display: flex; + ${({ $css }) => $css && `${$css};`} `; 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 00000000..fa18db7e --- /dev/null +++ b/src/frontend/apps/impress/src/features/footer/Footer.tsx @@ -0,0 +1,119 @@ +import Image from 'next/image'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import styled from 'styled-components'; + +import { default as IconGouv } from '@/assets/icons/icon-gouv.svg?url'; +import { default as IconMarianne } from '@/assets/icons/icon-marianne.svg?url'; +import { Box, StyledLink, Text } from '@/components/'; + +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(); + + return ( + + + + + {t('Marianne + + + + + {t('Freedom + + + + {[ + { + 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} + + + ))} + + + + {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 00000000..25093d13 --- /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/header/Header.tsx b/src/frontend/apps/impress/src/features/header/Header.tsx index 7d36c5fd..dfec7b8c 100644 --- a/src/frontend/apps/impress/src/features/header/Header.tsx +++ b/src/frontend/apps/impress/src/features/header/Header.tsx @@ -3,13 +3,13 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; +import { default as IconGouv } from '@/assets/icons/icon-gouv.svg?url'; +import { default as IconMarianne } from '@/assets/icons/icon-marianne.svg?url'; import { Box, Text } from '@/components/'; import { LanguagePicker } from '../language/'; -import { default as IconGouv } from './assets/icon-gouv.svg?url'; import { default as IconImpress } from './assets/icon-impress.svg?url'; -import { default as IconMarianne } from './assets/icon-marianne.svg?url'; import IconMyAccount from './assets/icon-my-account.png'; export const HEADER_HEIGHT = '100px'; diff --git a/src/frontend/apps/impress/src/layouts/MainLayout.tsx b/src/frontend/apps/impress/src/layouts/MainLayout.tsx index cd39d211..a28d504f 100644 --- a/src/frontend/apps/impress/src/layouts/MainLayout.tsx +++ b/src/frontend/apps/impress/src/layouts/MainLayout.tsx @@ -1,15 +1,23 @@ import { Box } from '@/components'; +import { Footer } from '@/features/footer/Footer'; import { HEADER_HEIGHT, Header } from '@/features/header'; export function MainLayout({ children }: { children: React.ReactNode }) { return ( - -
- - - {children} + + +
+ + + {children} + +