diff --git a/frontend/src/components/error-state.tsx b/frontend/src/components/error-state.tsx new file mode 100644 index 0000000..a078c02 --- /dev/null +++ b/frontend/src/components/error-state.tsx @@ -0,0 +1,25 @@ +import { AlertTriangle } from 'lucide-react' +import { Alert, AlertDescription, AlertTitle } from '~/components/ui/alert' +import { Button } from '~/components/ui/button' + +type Props = { + error: Error + reset?: () => void +} + +export function ErrorState({ error, reset }: Props) { + return ( + +
+ + Something went wrong + {error.message} + {reset && ( + + )} +
+
+ ) +} diff --git a/frontend/src/components/not-found.tsx b/frontend/src/components/not-found.tsx new file mode 100644 index 0000000..92cc70d --- /dev/null +++ b/frontend/src/components/not-found.tsx @@ -0,0 +1,14 @@ +import { Frown } from 'lucide-react' +import { Alert, AlertDescription, AlertTitle } from '~/components/ui/alert' + +export function NotFound({ title = '404: Page Not Found', message = 'Try going back or something …' }) { + return ( + +
+ + {title} + {message} +
+
+ ) +} diff --git a/frontend/src/routes/$slug.tsx b/frontend/src/routes/$slug.tsx index 29a4709..af08999 100644 --- a/frontend/src/routes/$slug.tsx +++ b/frontend/src/routes/$slug.tsx @@ -1,6 +1,7 @@ import { useSuspenseQuery } from '@tanstack/react-query' import { createFileRoute, notFound } from '@tanstack/react-router' import { Helmet } from 'react-helmet-async' +import { NotFound } from '~/components/not-found' import { PageView } from '~/components/page-view' import { pageBySlugQuery } from '~/lib/queries' @@ -10,6 +11,7 @@ export const Route = createFileRoute('/$slug')({ if (!page) throw notFound() }, component: CmsPage, + notFoundComponent: () => , }) function CmsPage() { diff --git a/frontend/src/routes/__root.tsx b/frontend/src/routes/__root.tsx index 4d3f49f..6b0bcc9 100644 --- a/frontend/src/routes/__root.tsx +++ b/frontend/src/routes/__root.tsx @@ -3,7 +3,9 @@ import { useSuspenseQuery } from '@tanstack/react-query' import { createRootRouteWithContext, Outlet } from '@tanstack/react-router' import { lazy, Suspense } from 'react' import { Helmet } from 'react-helmet-async' +import { ErrorState } from '~/components/error-state' import { Shell } from '~/components/layout/shell' +import { NotFound } from '~/components/not-found' import { globalsQuery, menusQuery } from '~/lib/queries' const TanStackRouterDevtools = import.meta.env.PROD @@ -19,6 +21,16 @@ export const Route = createRootRouteWithContext<{ queryClient: QueryClient }>()( await Promise.all([queryClient.ensureQueryData(globalsQuery), queryClient.ensureQueryData(menusQuery)]) }, component: RootComponent, + notFoundComponent: () => ( + + + + ), + errorComponent: ({ error, reset }) => ( + + + + ), }) function RootComponent() {