From 05b60fd084fd575e10f90c45726893cc5f70fd91 Mon Sep 17 00:00:00 2001 From: Cyril Date: Wed, 15 Jul 2026 14:27:08 +0200 Subject: [PATCH 01/11] =?UTF-8?q?=F0=9F=8E=A8(frontend)=20add=20SVG=20asse?= =?UTF-8?q?ts=20for=20errors=20and=20email=20confirmation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add SVGs for 404, 500, 503, access denied, and email confirmation pages. --- .../src/assets/icons/email-confirmation.svg | 85 ++++++++++ .../impress/src/assets/icons/error-404.svg | 154 ++++++++++++++++++ .../impress/src/assets/icons/error-500.svg | 142 ++++++++++++++++ .../impress/src/assets/icons/error-503.svg | 90 ++++++++++ .../src/assets/icons/error-access-denied.svg | 102 ++++++++++++ .../apps/impress/src/assets/icons/retry.svg | 3 + 6 files changed, 576 insertions(+) create mode 100644 src/frontend/apps/impress/src/assets/icons/email-confirmation.svg create mode 100644 src/frontend/apps/impress/src/assets/icons/error-404.svg create mode 100644 src/frontend/apps/impress/src/assets/icons/error-500.svg create mode 100644 src/frontend/apps/impress/src/assets/icons/error-503.svg create mode 100644 src/frontend/apps/impress/src/assets/icons/error-access-denied.svg create mode 100644 src/frontend/apps/impress/src/assets/icons/retry.svg diff --git a/src/frontend/apps/impress/src/assets/icons/email-confirmation.svg b/src/frontend/apps/impress/src/assets/icons/email-confirmation.svg new file mode 100644 index 0000000000..0a4276e7d6 --- /dev/null +++ b/src/frontend/apps/impress/src/assets/icons/email-confirmation.svg @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/frontend/apps/impress/src/assets/icons/error-404.svg b/src/frontend/apps/impress/src/assets/icons/error-404.svg new file mode 100644 index 0000000000..17597f6af5 --- /dev/null +++ b/src/frontend/apps/impress/src/assets/icons/error-404.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/frontend/apps/impress/src/assets/icons/error-500.svg b/src/frontend/apps/impress/src/assets/icons/error-500.svg new file mode 100644 index 0000000000..74acfd8497 --- /dev/null +++ b/src/frontend/apps/impress/src/assets/icons/error-500.svg @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/frontend/apps/impress/src/assets/icons/error-503.svg b/src/frontend/apps/impress/src/assets/icons/error-503.svg new file mode 100644 index 0000000000..f2f7d52139 --- /dev/null +++ b/src/frontend/apps/impress/src/assets/icons/error-503.svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/frontend/apps/impress/src/assets/icons/error-access-denied.svg b/src/frontend/apps/impress/src/assets/icons/error-access-denied.svg new file mode 100644 index 0000000000..5733580180 --- /dev/null +++ b/src/frontend/apps/impress/src/assets/icons/error-access-denied.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/frontend/apps/impress/src/assets/icons/retry.svg b/src/frontend/apps/impress/src/assets/icons/retry.svg new file mode 100644 index 0000000000..e866c7ad89 --- /dev/null +++ b/src/frontend/apps/impress/src/assets/icons/retry.svg @@ -0,0 +1,3 @@ + + + From ec7f565bf22b3b928e717262e240b22916d5ad3f Mon Sep 17 00:00:00 2001 From: Cyril Date: Wed, 15 Jul 2026 14:28:41 +0200 Subject: [PATCH 02/11] =?UTF-8?q?=E2=99=BB=EF=B8=8F(frontend)=20refactor?= =?UTF-8?q?=20ErrorPage=20to=20match=20new=20error=20UI=20design?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use SVG icons, 102x72 layout, 12px description and text-link actions. --- .../apps/impress/src/components/ErrorPage.tsx | 180 +++++++++++------- 1 file changed, 116 insertions(+), 64 deletions(-) diff --git a/src/frontend/apps/impress/src/components/ErrorPage.tsx b/src/frontend/apps/impress/src/components/ErrorPage.tsx index baf380345b..b9fe8e4667 100644 --- a/src/frontend/apps/impress/src/components/ErrorPage.tsx +++ b/src/frontend/apps/impress/src/components/ErrorPage.tsx @@ -1,20 +1,58 @@ -import { Button } from '@gouvfr-lasuite/cunningham-react'; import Head from 'next/head'; -import Image, { StaticImageData } from 'next/image'; +import Link from 'next/link'; +import { ComponentType, ReactNode, SVGProps } from 'react'; import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; -import { Box, Icon, StyledLink, Text } from '@/components'; +import { Box, Icon, Text } from '@/components'; +import HomeSvg from '@/icons/house-rounded.svg'; -const StyledButton = styled(Button)` - width: fit-content; +const errorActionStyles = ` + display: flex; + height: var(--md, 24px); + padding: 0 var(--xxxs, 4px); + justify-content: center; + align-items: center; + gap: var(--xxxs, 4px); + color: var(--c--contextuals--content--semantic--neutral--tertiary); + background: none; + border: none; + cursor: pointer; + font-family: inherit; + font-size: 12px; + font-weight: 400; + line-height: var(--line-height-xs, 16px); + text-decoration: none; + + svg { + text-decoration: none; + } + + .--docs--error-action-label { + text-decoration: none; + } + + &:hover:not(:disabled) .--docs--error-action-label { + text-decoration: underline; + } +`; + +const ErrorActionLink = styled.button` + ${errorActionStyles} +`; + +const ErrorActionLinkStyled = styled(Link)` + ${errorActionStyles} `; interface ErrorPageProps { - image: StaticImageData; + icon: ComponentType>; + title: string; description: string; refreshTarget?: string; showReload?: boolean; + showHome?: boolean; + actions?: ReactNode; } const getSafeRefreshUrl = (target?: string): string | undefined => { @@ -40,94 +78,108 @@ const getSafeRefreshUrl = (target?: string): string | undefined => { }; export const ErrorPage = ({ - image, + icon: IconComponent, + title, description, refreshTarget, showReload, + showHome = true, + actions, }: ErrorPageProps) => { const { t } = useTranslation(); - const errorTitle = t('An unexpected error occurred.'); const safeTarget = getSafeRefreshUrl(refreshTarget); return ( <> - {errorTitle} - {t('Docs')} + {title} - {t('Docs')} - {errorTitle} - {t('Docs')} + {title} - {t('Docs')} - + ); From fe37ecaea150d5ecb9a1a6df4b7ea988db2fe881 Mon Sep 17 00:00:00 2001 From: Cyril Date: Wed, 15 Jul 2026 16:13:32 +0200 Subject: [PATCH 03/11] =?UTF-8?q?=F0=9F=8E=A8(frontend)=20update=20404,=20?= =?UTF-8?q?500=20and=20generic=20error=20pages=20to=20new=20error=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wire new SVG icons and show Home plus Refresh actions on error pages. --- .../assets/icons/{error-404.svg => 404.svg} | 152 ++++++++--------- .../apps/impress/src/assets/icons/500.svg | 157 ++++++++++++++++++ .../impress/src/assets/icons/error-500.svg | 142 ---------------- src/frontend/apps/impress/src/pages/404.tsx | 80 ++------- src/frontend/apps/impress/src/pages/500.tsx | 6 +- .../apps/impress/src/pages/_error.tsx | 5 +- 6 files changed, 250 insertions(+), 292 deletions(-) rename src/frontend/apps/impress/src/assets/icons/{error-404.svg => 404.svg} (51%) create mode 100644 src/frontend/apps/impress/src/assets/icons/500.svg delete mode 100644 src/frontend/apps/impress/src/assets/icons/error-500.svg diff --git a/src/frontend/apps/impress/src/assets/icons/error-404.svg b/src/frontend/apps/impress/src/assets/icons/404.svg similarity index 51% rename from src/frontend/apps/impress/src/assets/icons/error-404.svg rename to src/frontend/apps/impress/src/assets/icons/404.svg index 17597f6af5..d923a0e05b 100644 --- a/src/frontend/apps/impress/src/assets/icons/error-404.svg +++ b/src/frontend/apps/impress/src/assets/icons/404.svg @@ -1,57 +1,57 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - - - - - - - - - + + + + + + + + + + + - - - + + + - + - + @@ -60,95 +60,95 @@ - + - - + + - - + + - + - - + + - - + + - + - - + + - + - - + + - + - + - + - + - + - + - + - + - + - + - + - - + + - - + + diff --git a/src/frontend/apps/impress/src/assets/icons/500.svg b/src/frontend/apps/impress/src/assets/icons/500.svg new file mode 100644 index 0000000000..aee910b78b --- /dev/null +++ b/src/frontend/apps/impress/src/assets/icons/500.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/frontend/apps/impress/src/assets/icons/error-500.svg b/src/frontend/apps/impress/src/assets/icons/error-500.svg deleted file mode 100644 index 74acfd8497..0000000000 --- a/src/frontend/apps/impress/src/assets/icons/error-500.svg +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/frontend/apps/impress/src/pages/404.tsx b/src/frontend/apps/impress/src/pages/404.tsx index ade6ec72d4..f4d8077283 100644 --- a/src/frontend/apps/impress/src/pages/404.tsx +++ b/src/frontend/apps/impress/src/pages/404.tsx @@ -1,83 +1,23 @@ -import { Button } from '@gouvfr-lasuite/cunningham-react'; -import Head from 'next/head'; -import Image from 'next/image'; import { ReactElement } from 'react'; import { useTranslation } from 'react-i18next'; -import styled from 'styled-components'; -import error_img from '@/assets/icons/error-planetes.png'; -import { Box, Icon, StyledLink, Text } from '@/components'; +import Error404Svg from '@/assets/icons/404.svg'; +import { ErrorPage } from '@/components'; import { PageLayout } from '@/layouts'; import { NextPageWithLayout } from '@/types/next'; -const StyledButton = styled(Button)` - width: fit-content; -`; - const Page: NextPageWithLayout = () => { const { t } = useTranslation(); return ( - <> - - - {t('Page Not Found - Error 404')} - {t('Docs')} - - - - - - {t('Page Not Found - Error 404')} - {t('Docs')} - - - - - {t( - 'It seems that the page you are looking for does not exist or cannot be displayed correctly.', - )} - - - - - - } - > - {t('Home')} - - - - - + ); }; diff --git a/src/frontend/apps/impress/src/pages/500.tsx b/src/frontend/apps/impress/src/pages/500.tsx index f69f2ede19..e81a005460 100644 --- a/src/frontend/apps/impress/src/pages/500.tsx +++ b/src/frontend/apps/impress/src/pages/500.tsx @@ -2,7 +2,7 @@ import { useRouter } from 'next/router'; import { ReactElement } from 'react'; import { useTranslation } from 'react-i18next'; -import error_img from '@/assets/icons/error-coffee.png'; +import Error500Svg from '@/assets/icons/500.svg'; import { ErrorPage } from '@/components'; import { PageLayout } from '@/layouts'; import { NextPageWithLayout } from '@/types/next'; @@ -16,11 +16,13 @@ const Page: NextPageWithLayout = () => { return ( ); }; diff --git a/src/frontend/apps/impress/src/pages/_error.tsx b/src/frontend/apps/impress/src/pages/_error.tsx index e06bfc3240..4689e61e5f 100644 --- a/src/frontend/apps/impress/src/pages/_error.tsx +++ b/src/frontend/apps/impress/src/pages/_error.tsx @@ -4,7 +4,7 @@ import NextError from 'next/error'; import { ReactElement } from 'react'; import { useTranslation } from 'react-i18next'; -import error_img from '@/assets/icons/error-planetes.png'; +import Error500Svg from '@/assets/icons/500.svg'; import { ErrorPage } from '@/components'; import { PageLayout } from '@/layouts'; @@ -13,7 +13,8 @@ const Error = () => { return ( From c239548a0fbbb9e9e1659ab76b3ad92a71b56bc0 Mon Sep 17 00:00:00 2001 From: Cyril Date: Thu, 16 Jul 2026 09:43:15 +0200 Subject: [PATCH 04/11] =?UTF-8?q?=F0=9F=8E=A8(frontend)=20update=20401=20a?= =?UTF-8?q?nd=20403=20access=20denied=20pages=20to=20new=20error=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply new illustration, typography and text-link actions for access errors. --- .../impress/src/assets/icons/Docs Locked.svg | 102 ++++++++++++ .../src/assets/icons/error-access-denied.svg | 102 ------------ .../doc-management/components/DocPage403.tsx | 150 +++++++++++++----- src/frontend/apps/impress/src/pages/401.tsx | 58 ++++--- 4 files changed, 245 insertions(+), 167 deletions(-) create mode 100644 src/frontend/apps/impress/src/assets/icons/Docs Locked.svg delete mode 100644 src/frontend/apps/impress/src/assets/icons/error-access-denied.svg diff --git a/src/frontend/apps/impress/src/assets/icons/Docs Locked.svg b/src/frontend/apps/impress/src/assets/icons/Docs Locked.svg new file mode 100644 index 0000000000..e910ada1d2 --- /dev/null +++ b/src/frontend/apps/impress/src/assets/icons/Docs Locked.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/frontend/apps/impress/src/assets/icons/error-access-denied.svg b/src/frontend/apps/impress/src/assets/icons/error-access-denied.svg deleted file mode 100644 index 5733580180..0000000000 --- a/src/frontend/apps/impress/src/assets/icons/error-access-denied.svg +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/components/DocPage403.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/components/DocPage403.tsx index 17bc67954d..9dbaf7c18a 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-management/components/DocPage403.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/components/DocPage403.tsx @@ -1,18 +1,61 @@ -import { Button } from '@gouvfr-lasuite/cunningham-react'; import Head from 'next/head'; -import Image from 'next/image'; +import Link from 'next/link'; import { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; -import img403 from '@/assets/icons/icon-403.png'; -import { Box, Icon, Loading, StyledLink, Text } from '@/components'; -import { ButtonAccessRequest } from '@/docs/doc-share'; -import { useDocAccessRequests } from '@/docs/doc-share/api/useDocAccessRequest'; +import ErrorAccessDeniedSvg from '@/assets/icons/Docs Locked.svg'; +import BubbleTextSvg from '@/icons/bubble-text.svg'; +import { Box, Loading, Text } from '@/components'; +import { Role } from '@/docs/doc-management'; +import { + useCreateDocAccessRequest, + useDocAccessRequests, +} from '@/docs/doc-share/api/useDocAccessRequest'; +import HomeSvg from '@/icons/house-rounded.svg'; import { useSkeletonStore } from '@/features/skeletons'; -const StyledButton = styled(Button)` - width: fit-content; +const errorActionStyles = ` + display: flex; + height: var(--md, 24px); + padding: 0 var(--xxxs, 4px); + justify-content: center; + align-items: center; + gap: var(--xxxs, 4px); + color: var(--c--contextuals--content--semantic--neutral--tertiary); + background: none; + border: none; + cursor: pointer; + font-family: inherit; + font-size: 12px; + font-weight: 500; + line-height: var(--line-height-xs, 16px); + text-decoration: none; + + svg { + text-decoration: none; + } + + .--docs--error-action-label { + text-decoration: none; + } + + &:hover:not(:disabled) .--docs--error-action-label { + text-decoration: underline; + } +`; + +const ErrorActionLinkStyled = styled(Link)` + ${errorActionStyles} +`; + +const RequestAccessButton = styled.button` + ${errorActionStyles} + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } `; interface DocProps { @@ -24,7 +67,6 @@ export const DocPage403 = ({ id }: DocProps) => { const { setIsSkeletonVisible } = useSkeletonStore(); useEffect(() => { - // Ensure the skeleton overlay is hidden on 403 page setIsSkeletonVisible(false); }, [setIsSkeletonVisible]); @@ -37,6 +79,8 @@ export const DocPage403 = ({ id }: DocProps) => { page: 1, }); + const { mutate: createRequest } = useCreateDocAccessRequest(); + const hasRequested = !!requests?.results.find( (request) => request.document === id, ); @@ -50,33 +94,41 @@ export const DocPage403 = ({ id }: DocProps) => { - {t('Access Denied - Error 403')} - {t('Docs')} + {t('Access denied')} - {t('Docs')} - {t('Image + ); if (isError) { render = ( - - + +