From f0b633a9763fbbc8663d13dc9a5a4e45f983241c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Rialland?= Date: Thu, 28 Sep 2023 12:55:10 +0200 Subject: [PATCH] Refacto error page --- site/source/components/App.tsx | 104 +++++++++----------- site/source/components/ErrorPage.tsx | 141 +++++++++++++++++++++++++++ site/source/components/Provider.tsx | 131 +------------------------ site/source/pages/Offline.tsx | 59 ++++++----- 4 files changed, 226 insertions(+), 209 deletions(-) create mode 100644 site/source/components/ErrorPage.tsx diff --git a/site/source/components/App.tsx b/site/source/components/App.tsx index dc8df2d7b..12af7f888 100644 --- a/site/source/components/App.tsx +++ b/site/source/components/App.tsx @@ -1,7 +1,6 @@ import { ErrorBoundary } from '@sentry/react' -import { FallbackRender } from '@sentry/react/types/errorboundary' import rules from 'modele-social' -import { ComponentProps, StrictMode, useMemo } from 'react' +import { StrictMode, useMemo } from 'react' import { useTranslation } from 'react-i18next' import { Route, Routes } from 'react-router-dom' import { css, styled } from 'styled-components' @@ -30,7 +29,7 @@ import Documentation from '@/pages/Documentation' import Iframes from '@/pages/iframes' import Integration from '@/pages/integration/index' import Nouveautés from '@/pages/nouveautés/index' -import Offline from '@/pages/Offline' +import { CatchOffline } from '@/pages/Offline' import Plan from '@/pages/Plan' import Simulateurs from '@/pages/simulateurs' import SimulateursEtAssistants from '@/pages/simulateurs-et-assistants' @@ -65,7 +64,9 @@ export default function Root({ - + + + @@ -86,14 +87,6 @@ const Router = () => { ) } -const CatchOffline = ({ error }: ComponentProps) => { - if (error.message.includes('dynamically imported module')) { - return - } else { - throw error - } -} - const App = () => { const { relativeSitePaths } = useSitePaths() @@ -133,56 +126,51 @@ const App = () => { {t('Aller directement au pied de page')} - - - } /> + + } /> - } - /> - } - /> - } - /> - - } - /> - } - /> - } - /> - } /> - } /> - } - /> + } + /> + } + /> + } + /> + + } + /> + } + /> + } + /> + } /> + } /> + } + /> - } - /> + } /> - } /> + } /> - } /> - - + } /> + diff --git a/site/source/components/ErrorPage.tsx b/site/source/components/ErrorPage.tsx new file mode 100644 index 000000000..cd21a8857 --- /dev/null +++ b/site/source/components/ErrorPage.tsx @@ -0,0 +1,141 @@ +import { ReactNode } from 'react' +import { Trans, useTranslation } from 'react-i18next' +import { styled } from 'styled-components' + +import FeedbackForm from '@/components/Feedback/FeedbackForm' +import { Container, Grid } from '@/design-system/layout' +import { H1, H4 } from '@/design-system/typography/heading' +import { Link } from '@/design-system/typography/link' +import { Body, Intro } from '@/design-system/typography/paragraphs' + +import { Message } from '../design-system' +import { Logo } from './Logo' + +const StyledLogo = styled.div` + height: 3rem; + + @media (max-width: ${({ theme }) => theme.breakpointsWidth.sm}) { + height: 2.5rem; + } +` + +export const ErrorLayout = ({ children }: { children: ReactNode }) => { + const { t } = useTranslation() + + return ( +
+ + + + + + + +

+ Une erreur est survenue +

+ + {children} +
+
+ ) +} + +export const ErrorFallback = (props: { + error: Error + componentStack: string | null + eventId: string | null + resetError(): void + showFeedbackForm?: boolean +}) => { + const { t } = useTranslation() + + const additionalData = JSON.stringify( + { + name: props.error.name, + message: props.error.message, + stack: props.error.stack, + componentStack: props.componentStack, + }, + null, + 2 + ) + + return ( + + + + L'équipe technique mon-entreprise a été prévenue automatiquement, + veuillez nous excuser pour la gêne occasionnée. + + + + + {props.showFeedbackForm ? ( + + + Si vous souhaitez nous aider à corriger ce problème, vous + pouvez décrire les actions ont conduit à cette erreur via le + formulaire ci-dessous ou à l'adresse :{' '} + + contact@mon-entreprise.beta.gouv.fr + + . + + + } + description={ + + Décrivez les actions qui ont conduit à cette erreur : + + } + placeholder={t( + 'error.placeholder', + `Bonjour, j'ai rencontré une erreur après avoir cliqué sur...` + )} + tags={['error']} + additionalData={additionalData} + /> + ) : ( + + + Si vous souhaitez nous aider à corriger ce problème, vous pouvez + décrire les actions ont conduit à cette erreur à l'adresse :{' '} + + contact@mon-entreprise.beta.gouv.fr + + . + + + )} + + + + +

Cause de l'erreur :

+ + {props.error.name} : {props.error.message} + +
+
+
+
+ ) +} diff --git a/site/source/components/Provider.tsx b/site/source/components/Provider.tsx index f220bf6ee..9d46ab02d 100644 --- a/site/source/components/Provider.tsx +++ b/site/source/components/Provider.tsx @@ -3,26 +3,20 @@ import { ErrorBoundary } from '@sentry/react' import i18next from 'i18next' import { createContext, ReactNode } from 'react' import { HelmetProvider } from 'react-helmet-async' -import { I18nextProvider, Trans, useTranslation } from 'react-i18next' +import { I18nextProvider } from 'react-i18next' import { Provider as ReduxProvider } from 'react-redux' import { BrowserRouter } from 'react-router-dom' -import logo from '@/assets/images/logo-monentreprise.svg' -import FeedbackForm from '@/components/Feedback/FeedbackForm' import { ThemeColorsProvider } from '@/components/utils/colors' import { DisableAnimationOnPrintProvider } from '@/components/utils/DisableAnimationContext' -import { Container, Grid } from '@/design-system/layout' import DesignSystemThemeProvider from '@/design-system/root' -import { H1, H4 } from '@/design-system/typography/heading' -import { Link } from '@/design-system/typography/link' -import { Body, Intro } from '@/design-system/typography/paragraphs' import { EmbededContextProvider } from '@/hooks/useIsEmbedded' -import { Message } from '../design-system' import * as safeLocalStorage from '../storage/safeLocalStorage' import { store } from '../store/store' import { TrackingContext } from './ATInternetTracking' import { createTracker } from './ATInternetTracking/Tracker' +import { ErrorFallback } from './ErrorPage' import { IframeResizer } from './IframeResizer' import { ServiceWorker } from './ServiceWorker' import BrowserOnly from './utils/BrowserOnly' @@ -45,10 +39,7 @@ export default function Provider({ - } - > + @@ -84,122 +75,6 @@ export default function Provider({ ) } -const ErrorFallback = (props: { - error: Error - componentStack: string | null - eventId: string | null - resetError(): void - showFeedbackForm?: boolean -}) => { - const { t } = useTranslation() - - const additionalData = JSON.stringify( - { - name: props.error.name, - message: props.error.message, - stack: props.error.stack, - componentStack: props.componentStack, - }, - null, - 2 - ) - - return ( -
- - - Logo mon-entreprise - -

- Une erreur est survenue -

- - - L'équipe technique mon-entreprise a été prévenue automatiquement, - veuillez nous excuser pour la gêne occasionnée. - - - - - {props.showFeedbackForm ? ( - - - Si vous souhaitez nous aider à corriger ce problème, vous - pouvez décrire les actions ont conduit à cette erreur via - le formulaire ci-dessous ou à l'adresse :{' '} - - contact@mon-entreprise.beta.gouv.fr - - . - - - } - description={ - - Décrivez les actions qui ont conduit à cette erreur : - - } - placeholder={t( - 'error.placeholder', - `Bonjour, j'ai rencontré une erreur après avoir cliqué sur...` - )} - tags={['error']} - additionalData={additionalData} - /> - ) : ( - - - Si vous souhaitez nous aider à corriger ce problème, vous - pouvez décrire les actions ont conduit à cette erreur à - l'adresse :{' '} - - contact@mon-entreprise.beta.gouv.fr - - . - - - )} - - - - -

Cause de l'erreur :

- - {props.error.name} : {props.error.message} - -
-
-
-
-
- ) -} - function BrowserRouterProvider({ children, basename, diff --git a/site/source/pages/Offline.tsx b/site/source/pages/Offline.tsx index 6e115e22c..1a7260a26 100644 --- a/site/source/pages/Offline.tsx +++ b/site/source/pages/Offline.tsx @@ -1,36 +1,49 @@ +import { FallbackRender } from '@sentry/react' +import { ComponentProps } from 'react' import { useTranslation } from 'react-i18next' +import { ErrorLayout } from '@/components/ErrorPage' import Meta from '@/components/utils/Meta' import { Message } from '@/design-system' import { Grid } from '@/design-system/layout' import { Body, Intro } from '@/design-system/typography/paragraphs' -export default function Offline() { +export const CatchOffline = ({ error }: ComponentProps) => { + if (error.message.includes('dynamically imported module')) { + return + } else { + throw error + } +} + +function Offline() { const { t } = useTranslation() return ( - - - - - Vous êtes actuellement hors ligne. - - Cette page n'a pas encore été téléchargée et n'est donc pas - disponible sans internet, pour y accéder vérifiez votre connexion - puis rechargez la page. - - + + + + + + Vous êtes actuellement hors ligne. + + Cette page n'a pas encore été téléchargée et n'est donc pas + disponible sans internet, pour y accéder vérifiez votre connexion + puis rechargez la page. + + + - + ) }