Refacto error page
parent
1d435353c0
commit
f0b633a976
|
@ -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({
|
|||
<EngineProvider value={engine}>
|
||||
<Provider basename={basename}>
|
||||
<Redirections>
|
||||
<Router />
|
||||
<ErrorBoundary fallback={CatchOffline}>
|
||||
<Router />
|
||||
</ErrorBoundary>
|
||||
</Redirections>
|
||||
</Provider>
|
||||
</EngineProvider>
|
||||
|
@ -86,14 +87,6 @@ const Router = () => {
|
|||
)
|
||||
}
|
||||
|
||||
const CatchOffline = ({ error }: ComponentProps<FallbackRender>) => {
|
||||
if (error.message.includes('dynamically imported module')) {
|
||||
return <Offline />
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
const App = () => {
|
||||
const { relativeSitePaths } = useSitePaths()
|
||||
|
||||
|
@ -133,56 +126,51 @@ const App = () => {
|
|||
{t('Aller directement au pied de page')}
|
||||
</a>
|
||||
<Container>
|
||||
<ErrorBoundary fallback={CatchOffline}>
|
||||
<Routes>
|
||||
<Route index element={<Landing />} />
|
||||
<Routes>
|
||||
<Route index element={<Landing />} />
|
||||
|
||||
<Route
|
||||
path={relativeSitePaths.assistants.index + '/*'}
|
||||
element={<Assistants />}
|
||||
/>
|
||||
<Route
|
||||
path={relativeSitePaths.simulateurs.index + '/*'}
|
||||
element={<Simulateurs />}
|
||||
/>
|
||||
<Route
|
||||
path={relativeSitePaths.simulateursEtAssistants + '/*'}
|
||||
element={<SimulateursEtAssistants />}
|
||||
/>
|
||||
<Route
|
||||
path={relativeSitePaths.documentation.index + '/*'}
|
||||
element={
|
||||
<Documentation
|
||||
documentationPath={documentationPath}
|
||||
engine={engine}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path={relativeSitePaths.développeur.index + '/*'}
|
||||
element={<Integration />}
|
||||
/>
|
||||
<Route
|
||||
path={relativeSitePaths.nouveautés.index + '/*'}
|
||||
element={<Nouveautés />}
|
||||
/>
|
||||
<Route path={relativeSitePaths.stats} element={<Stats />} />
|
||||
<Route path={relativeSitePaths.budget} element={<Budget />} />
|
||||
<Route
|
||||
path={relativeSitePaths.accessibilité}
|
||||
element={<Accessibilité />}
|
||||
/>
|
||||
<Route
|
||||
path={relativeSitePaths.assistants.index + '/*'}
|
||||
element={<Assistants />}
|
||||
/>
|
||||
<Route
|
||||
path={relativeSitePaths.simulateurs.index + '/*'}
|
||||
element={<Simulateurs />}
|
||||
/>
|
||||
<Route
|
||||
path={relativeSitePaths.simulateursEtAssistants + '/*'}
|
||||
element={<SimulateursEtAssistants />}
|
||||
/>
|
||||
<Route
|
||||
path={relativeSitePaths.documentation.index + '/*'}
|
||||
element={
|
||||
<Documentation
|
||||
documentationPath={documentationPath}
|
||||
engine={engine}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path={relativeSitePaths.développeur.index + '/*'}
|
||||
element={<Integration />}
|
||||
/>
|
||||
<Route
|
||||
path={relativeSitePaths.nouveautés.index + '/*'}
|
||||
element={<Nouveautés />}
|
||||
/>
|
||||
<Route path={relativeSitePaths.stats} element={<Stats />} />
|
||||
<Route path={relativeSitePaths.budget} element={<Budget />} />
|
||||
<Route
|
||||
path={relativeSitePaths.accessibilité}
|
||||
element={<Accessibilité />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/dev/integration-test"
|
||||
element={<IntegrationTest />}
|
||||
/>
|
||||
<Route path="/dev/integration-test" element={<IntegrationTest />} />
|
||||
|
||||
<Route path={relativeSitePaths.plan} element={<Plan />} />
|
||||
<Route path={relativeSitePaths.plan} element={<Plan />} />
|
||||
|
||||
<Route path="*" element={<Page404 />} />
|
||||
</Routes>
|
||||
</ErrorBoundary>
|
||||
<Route path="*" element={<Page404 />} />
|
||||
</Routes>
|
||||
</Container>
|
||||
</main>
|
||||
|
||||
|
|
|
@ -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 (
|
||||
<main style={{ height: '100vh' }}>
|
||||
<Container>
|
||||
<Link
|
||||
href="/"
|
||||
aria-label={t('error.back', "Retourner à la page d'accueil")}
|
||||
>
|
||||
<StyledLogo>
|
||||
<Logo />
|
||||
</StyledLogo>
|
||||
</Link>
|
||||
|
||||
<H1>
|
||||
<Trans i18nKey="error.title">Une erreur est survenue</Trans>
|
||||
</H1>
|
||||
|
||||
{children}
|
||||
</Container>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
||||
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 (
|
||||
<ErrorLayout>
|
||||
<Intro>
|
||||
<Trans i18nKey="error.intro">
|
||||
L'équipe technique mon-entreprise a été prévenue automatiquement,
|
||||
veuillez nous excuser pour la gêne occasionnée.
|
||||
</Trans>
|
||||
</Intro>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12} lg={8}>
|
||||
{props.showFeedbackForm ? (
|
||||
<FeedbackForm
|
||||
infoSlot={
|
||||
<Trans i18nKey="error.body0">
|
||||
<Body>
|
||||
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 :{' '}
|
||||
<Link
|
||||
href="mailto:contact@mon-entreprise.beta.gouv.fr"
|
||||
aria-label={t(
|
||||
'error.contact',
|
||||
'Envoyer un courriel à contact@mon-entreprise.beta.gouv.fr, nouvelle fenêtre'
|
||||
)}
|
||||
>
|
||||
contact@mon-entreprise.beta.gouv.fr
|
||||
</Link>
|
||||
.
|
||||
</Body>
|
||||
</Trans>
|
||||
}
|
||||
description={
|
||||
<Trans i18nKey="error.description">
|
||||
Décrivez les actions qui ont conduit à cette erreur :
|
||||
</Trans>
|
||||
}
|
||||
placeholder={t(
|
||||
'error.placeholder',
|
||||
`Bonjour, j'ai rencontré une erreur après avoir cliqué sur...`
|
||||
)}
|
||||
tags={['error']}
|
||||
additionalData={additionalData}
|
||||
/>
|
||||
) : (
|
||||
<Trans i18nKey="error.body1">
|
||||
<Body>
|
||||
Si vous souhaitez nous aider à corriger ce problème, vous pouvez
|
||||
décrire les actions ont conduit à cette erreur à l'adresse :{' '}
|
||||
<Link
|
||||
href="mailto:contact@mon-entreprise.beta.gouv.fr"
|
||||
aria-label={t(
|
||||
'error.contact',
|
||||
'Envoyer un courriel à contact@mon-entreprise.beta.gouv.fr, nouvelle fenêtre'
|
||||
)}
|
||||
>
|
||||
contact@mon-entreprise.beta.gouv.fr
|
||||
</Link>
|
||||
.
|
||||
</Body>
|
||||
</Trans>
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12} lg={8}>
|
||||
<Message type="info">
|
||||
<H4>Cause de l'erreur :</H4>
|
||||
<Body>
|
||||
{props.error.name} : {props.error.message}
|
||||
</Body>
|
||||
</Message>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ErrorLayout>
|
||||
)
|
||||
}
|
|
@ -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({
|
|||
<EmbededContextProvider>
|
||||
<DarkModeProvider>
|
||||
<DesignSystemThemeProvider>
|
||||
<ErrorBoundary
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
fallback={(errorData) => <ErrorFallback {...errorData} />}
|
||||
>
|
||||
<ErrorBoundary fallback={ErrorFallback}>
|
||||
<I18nextProvider i18n={i18next}>
|
||||
<ReduxProvider store={store}>
|
||||
<BrowserRouterProvider basename={basename}>
|
||||
|
@ -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 (
|
||||
<main style={{ height: '100vh' }}>
|
||||
<Container>
|
||||
<Link
|
||||
href="/"
|
||||
aria-label={t('error.back', "Retourner à la page d'accueil")}
|
||||
>
|
||||
<img
|
||||
src={logo}
|
||||
alt="Logo mon-entreprise"
|
||||
style={{
|
||||
maxWidth: '200px',
|
||||
width: '100%',
|
||||
marginTop: '1rem',
|
||||
}}
|
||||
></img>
|
||||
</Link>
|
||||
<H1>
|
||||
<Trans i18nKey="error.title">Une erreur est survenue</Trans>
|
||||
</H1>
|
||||
<Intro>
|
||||
<Trans i18nKey="error.intro">
|
||||
L'équipe technique mon-entreprise a été prévenue automatiquement,
|
||||
veuillez nous excuser pour la gêne occasionnée.
|
||||
</Trans>
|
||||
</Intro>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12} lg={8}>
|
||||
{props.showFeedbackForm ? (
|
||||
<FeedbackForm
|
||||
infoSlot={
|
||||
<Trans i18nKey="error.body0">
|
||||
<Body>
|
||||
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 :{' '}
|
||||
<Link
|
||||
href="mailto:contact@mon-entreprise.beta.gouv.fr"
|
||||
aria-label={t(
|
||||
'error.contact',
|
||||
'Envoyer un courriel à contact@mon-entreprise.beta.gouv.fr, nouvelle fenêtre'
|
||||
)}
|
||||
>
|
||||
contact@mon-entreprise.beta.gouv.fr
|
||||
</Link>
|
||||
.
|
||||
</Body>
|
||||
</Trans>
|
||||
}
|
||||
description={
|
||||
<Trans i18nKey="error.description">
|
||||
Décrivez les actions qui ont conduit à cette erreur :
|
||||
</Trans>
|
||||
}
|
||||
placeholder={t(
|
||||
'error.placeholder',
|
||||
`Bonjour, j'ai rencontré une erreur après avoir cliqué sur...`
|
||||
)}
|
||||
tags={['error']}
|
||||
additionalData={additionalData}
|
||||
/>
|
||||
) : (
|
||||
<Trans i18nKey="error.body1">
|
||||
<Body>
|
||||
Si vous souhaitez nous aider à corriger ce problème, vous
|
||||
pouvez décrire les actions ont conduit à cette erreur à
|
||||
l'adresse :{' '}
|
||||
<Link
|
||||
href="mailto:contact@mon-entreprise.beta.gouv.fr"
|
||||
aria-label={t(
|
||||
'error.contact',
|
||||
'Envoyer un courriel à contact@mon-entreprise.beta.gouv.fr, nouvelle fenêtre'
|
||||
)}
|
||||
>
|
||||
contact@mon-entreprise.beta.gouv.fr
|
||||
</Link>
|
||||
.
|
||||
</Body>
|
||||
</Trans>
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12} lg={8}>
|
||||
<Message type="info">
|
||||
<H4>Cause de l'erreur :</H4>
|
||||
<Body>
|
||||
{props.error.name} : {props.error.message}
|
||||
</Body>
|
||||
</Message>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Container>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
||||
function BrowserRouterProvider({
|
||||
children,
|
||||
basename,
|
||||
|
|
|
@ -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<FallbackRender>) => {
|
||||
if (error.message.includes('dynamically imported module')) {
|
||||
return <Offline />
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
function Offline() {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
style={{ justifyContent: 'center', margin: '10rem 0' }}
|
||||
role="main"
|
||||
>
|
||||
<Grid item md={8} sm={12}>
|
||||
<Meta
|
||||
title={t('pages.offline.title', 'Hors ligne')}
|
||||
description={t(
|
||||
'pages.offline.description',
|
||||
'Vous êtes actuellement hors ligne.'
|
||||
)}
|
||||
/>
|
||||
<Message type="info" style={{ margin: '1rem 0' }}>
|
||||
<Intro>Vous êtes actuellement hors ligne.</Intro>
|
||||
<Body>
|
||||
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.
|
||||
</Body>
|
||||
</Message>
|
||||
<ErrorLayout>
|
||||
<Grid
|
||||
container
|
||||
style={{ justifyContent: 'center', margin: '10rem 0' }}
|
||||
role="main"
|
||||
>
|
||||
<Grid item md={8} sm={12}>
|
||||
<Meta
|
||||
title={t('pages.offline.title', 'Hors ligne')}
|
||||
description={t(
|
||||
'pages.offline.description',
|
||||
'Vous êtes actuellement hors ligne.'
|
||||
)}
|
||||
/>
|
||||
<Message type="info" style={{ margin: '1rem 0' }}>
|
||||
<Intro>Vous êtes actuellement hors ligne.</Intro>
|
||||
<Body>
|
||||
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.
|
||||
</Body>
|
||||
</Message>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ErrorLayout>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue