Skip to content

Commit ebdcb4b

Browse files
committed
✨(frontend) add back the footer and cgu pages
We need to add back the footer and cgu pages, but we will not display the footer on the doc editor pages.
1 parent 3a0dff5 commit ebdcb4b

File tree

13 files changed

+555
-2
lines changed

13 files changed

+555
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ and this project adheres to
2424
- 💄(frontend) error alert closeable on editor #284
2525
- ♻️(backend) Change email content #283
2626
- 🛂(frontend) viewers and editors can access share modal #302
27+
- ♻️(frontend) remove footer on doc editor #313
2728

2829
## Fixed
2930

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { expect, test } from '@playwright/test';
2+
3+
import { goToGridDoc } from './common';
4+
5+
test.beforeEach(async ({ page }) => {
6+
await page.goto('/');
7+
});
8+
9+
test.describe('Footer', () => {
10+
test('checks all the elements are visible', async ({ page }) => {
11+
const footer = page.locator('footer').first();
12+
13+
await expect(footer.getByAltText('Gouvernement Logo')).toBeVisible();
14+
15+
await expect(
16+
footer.getByRole('link', { name: 'legifrance.gouv.fr' }),
17+
).toBeVisible();
18+
19+
await expect(
20+
footer.getByRole('link', { name: 'info.gouv.fr' }),
21+
).toBeVisible();
22+
23+
await expect(
24+
footer.getByRole('link', { name: 'service-public.fr' }),
25+
).toBeVisible();
26+
27+
await expect(
28+
footer.getByRole('link', { name: 'data.gouv.fr' }),
29+
).toBeVisible();
30+
31+
await expect(
32+
footer.getByRole('link', { name: 'Legal Notice' }),
33+
).toBeVisible();
34+
35+
await expect(
36+
footer.getByRole('link', { name: 'Personal data and cookies' }),
37+
).toBeVisible();
38+
39+
await expect(
40+
footer.getByRole('link', { name: 'Accessibility' }),
41+
).toBeVisible();
42+
43+
await expect(
44+
footer.getByText(
45+
'Unless otherwise stated, all content on this site is under licence',
46+
),
47+
).toBeVisible();
48+
});
49+
50+
test('checks footer is not visible on doc editor', async ({ page }) => {
51+
await expect(page.locator('footer')).toBeVisible();
52+
await goToGridDoc(page);
53+
await expect(page.locator('footer')).toBeHidden();
54+
});
55+
56+
const legalPages = [
57+
{ name: 'Legal Notice', url: '/legal-notice/' },
58+
{ name: 'Personal data and cookies', url: '/personal-data-cookies/' },
59+
{ name: 'Accessibility', url: '/accessibility/' },
60+
];
61+
for (const { name, url } of legalPages) {
62+
test(`checks ${name} page`, async ({ page }) => {
63+
const footer = page.locator('footer').first();
64+
await footer.getByRole('link', { name }).click();
65+
66+
await expect(
67+
page
68+
.getByRole('heading', {
69+
name,
70+
})
71+
.first(),
72+
).toBeVisible();
73+
74+
await expect(page).toHaveURL(url);
75+
});
76+
}
77+
});
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import Image from 'next/image';
2+
import React from 'react';
3+
import { useTranslation } from 'react-i18next';
4+
import styled from 'styled-components';
5+
6+
import { Box, StyledLink, Text } from '@/components/';
7+
import { useCunninghamTheme } from '@/cunningham';
8+
9+
import IconLink from './assets/external-link.svg';
10+
11+
const BlueStripe = styled.div`
12+
position: absolute;
13+
height: 2px;
14+
width: 100%;
15+
background: var(--c--theme--colors--primary-600);
16+
top: 0;
17+
`;
18+
19+
export const Footer = () => {
20+
const { t } = useTranslation();
21+
const { themeTokens } = useCunninghamTheme();
22+
const logo = themeTokens().logo;
23+
24+
return (
25+
<Box $position="relative" as="footer">
26+
<BlueStripe />
27+
<Box $padding={{ top: 'large', horizontal: 'big', bottom: 'small' }}>
28+
<Box
29+
$direction="row"
30+
$gap="1.5rem"
31+
$align="center"
32+
$justify="space-between"
33+
$css="flex-wrap: wrap;"
34+
>
35+
<Box>
36+
<Box $align="center" $gap="6rem" $direction="row">
37+
{logo && (
38+
<Image
39+
priority
40+
src={logo.src}
41+
alt={logo.alt}
42+
width={0}
43+
height={0}
44+
style={{ width: logo.widthFooter, height: 'auto' }}
45+
/>
46+
)}
47+
</Box>
48+
</Box>
49+
<Box
50+
$direction="row"
51+
$css={`
52+
column-gap: 1.5rem;
53+
row-gap: .5rem;
54+
flex-wrap: wrap;
55+
`}
56+
>
57+
{[
58+
{
59+
label: 'legifrance.gouv.fr',
60+
href: 'https://legifrance.gouv.fr/',
61+
},
62+
{
63+
label: 'info.gouv.fr',
64+
href: 'https://info.gouv.fr/',
65+
},
66+
{
67+
label: 'service-public.fr',
68+
href: 'https://service-public.fr/',
69+
},
70+
{
71+
label: 'data.gouv.fr',
72+
href: 'https://data.gouv.fr/',
73+
},
74+
].map(({ label, href }) => (
75+
<StyledLink
76+
key={label}
77+
href={href}
78+
target="__blank"
79+
$css={`
80+
gap:0.2rem;
81+
transition: box-shadow 0.3s;
82+
&:hover {
83+
box-shadow: 0px 2px 0 0 var(--c--theme--colors--greyscale-text);
84+
}
85+
`}
86+
>
87+
<Text $weight="bold">{label}</Text>
88+
<IconLink width={18} />
89+
</StyledLink>
90+
))}
91+
</Box>
92+
</Box>
93+
<Box
94+
$direction="row"
95+
$margin={{ top: 'big' }}
96+
$padding={{ top: 'tiny' }}
97+
$css={`
98+
flex-wrap: wrap;
99+
border-top: 1px solid var(--c--theme--colors--greyscale-200);
100+
column-gap: 1rem;
101+
row-gap: .5rem;
102+
`}
103+
>
104+
{[
105+
{
106+
label: t('Legal Notice'),
107+
href: '/legal-notice',
108+
},
109+
{
110+
label: t('Personal data and cookies'),
111+
href: '/personal-data-cookies',
112+
},
113+
{
114+
label: t('Accessibility'),
115+
href: '/accessibility',
116+
},
117+
].map(({ label, href }) => (
118+
<StyledLink
119+
key={label}
120+
href={href}
121+
$css={`
122+
padding-right: 1rem;
123+
&:not(:last-child) {
124+
box-shadow: inset -1px 0px 0px 0px var(--c--theme--colors--greyscale-200);
125+
}
126+
`}
127+
>
128+
<Text
129+
$variation="600"
130+
$size="m"
131+
$transition="box-shadow 0.3s"
132+
$css={`
133+
&:hover {
134+
box-shadow: 0px 2px 0 0 var(--c--theme--colors--greyscale-text);
135+
}
136+
`}
137+
>
138+
{label}
139+
</Text>
140+
</StyledLink>
141+
))}
142+
</Box>
143+
<Text
144+
as="p"
145+
$size="m"
146+
$margin={{ top: 'big' }}
147+
$variation="600"
148+
$display="inline"
149+
>
150+
{t('Unless otherwise stated, all content on this site is under')}{' '}
151+
<StyledLink
152+
href="https://github.com/etalab/licence-ouverte/blob/master/LO.md"
153+
target="__blank"
154+
$css={`
155+
display:inline-flex;
156+
box-shadow: 0px 1px 0 0 var(--c--theme--colors--greyscale-text);
157+
`}
158+
>
159+
<Text $variation="600">licence etalab-2.0</Text>
160+
<IconLink width={18} />
161+
</StyledLink>
162+
</Text>
163+
</Box>
164+
</Box>
165+
);
166+
};
Lines changed: 5 additions & 0 deletions
Loading
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './Footer';

src/frontend/apps/impress/src/features/service-worker/service-worker.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ const precacheResources = [
9494
'/',
9595
'/index.html',
9696
'/404/',
97+
'/accessibility/',
98+
'/legal-notice/',
99+
'/personal-data-cookies/',
97100
FALLBACK.offline,
98101
FALLBACK.images,
99102
FALLBACK.docs,

src/frontend/apps/impress/src/layouts/MainLayout.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1+
import { PropsWithChildren } from 'react';
2+
13
import { Box } from '@/components';
24
import { useCunninghamTheme } from '@/cunningham';
5+
import { Footer } from '@/features/footer';
36
import { Header } from '@/features/header';
47

5-
export function MainLayout({ children }: { children: React.ReactNode }) {
8+
interface MainLayoutProps {
9+
withoutFooter?: boolean;
10+
}
11+
12+
export function MainLayout({
13+
children,
14+
withoutFooter,
15+
}: PropsWithChildren<MainLayoutProps>) {
616
const { colorsTokens } = useCunninghamTheme();
717

818
return (
@@ -20,6 +30,7 @@ export function MainLayout({ children }: { children: React.ReactNode }) {
2030
</Box>
2131
</Box>
2232
</Box>
33+
{!withoutFooter && <Footer />}
2334
</Box>
2435
);
2536
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { PropsWithChildren } from 'react';
2+
3+
import { Box } from '@/components';
4+
import { Footer } from '@/features/footer';
5+
import { Header } from '@/features/header';
6+
7+
export function PageLayout({ children }: PropsWithChildren) {
8+
return (
9+
<Box $minHeight="100vh">
10+
<Header />
11+
<Box as="main" $width="100%" $css="flex-grow:1;">
12+
{children}
13+
</Box>
14+
<Footer />
15+
</Box>
16+
);
17+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './MainLayout';
2+
export * from './PageLayout';

0 commit comments

Comments
 (0)