diff --git a/app/features/components/ErrorBoundary/index.tsx b/app/features/components/ErrorBoundary/index.tsx
new file mode 100644
index 0000000..39ae31e
--- /dev/null
+++ b/app/features/components/ErrorBoundary/index.tsx
@@ -0,0 +1,30 @@
+import React from 'react'
+import { ErrorBoundary } from 'react-error-boundary'
+
+type FallbackRenderProps = {
+ error: Error
+ resetErrorBoundary: () => void
+}
+
+const FallbackRender = ({ error }: FallbackRenderProps) => {
+ // eslint-disable-next-line no-console
+ console.error('Error description: ', error.message)
+
+ return (
+
+
+ We encountered an internal error. Please try again.
+
+
+ )
+}
+
+type CatchErrorBoundaryProps = {
+ children: React.ReactNode
+}
+
+export const CatchErrorBoundary = ({ children }: CatchErrorBoundaryProps) => {
+ return (
+ {children}
+ )
+}
diff --git a/app/features/components/index.tsx b/app/features/components/index.tsx
index 323fe65..202fc6c 100644
--- a/app/features/components/index.tsx
+++ b/app/features/components/index.tsx
@@ -8,3 +8,4 @@ export * from './Breadcrumbs'
export * from './Page'
export * from './Show'
export * from './Spinner'
+export * from './ErrorBoundary'
diff --git a/app/pages/Events/components/PastEvents/index.tsx b/app/pages/Events/components/PastEvents/index.tsx
deleted file mode 100644
index 969f073..0000000
--- a/app/pages/Events/components/PastEvents/index.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import { useAsyncValue } from '@remix-run/react'
-import { Section, H2 } from '~/features/components'
-import { EventList } from '../EventList'
-import type { LoaderData } from '../../loader'
-
-export const PastEvents = () => {
- const res = useAsyncValue() as Awaited
-
- if (res.success === false) {
- return null
- }
-
- return (
-
- )
-}
diff --git a/app/pages/Events/components/UpcomingEvents/index.tsx b/app/pages/Events/components/UpcomingEvents/index.tsx
deleted file mode 100644
index 5bd5f5e..0000000
--- a/app/pages/Events/components/UpcomingEvents/index.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import { useAsyncValue } from '@remix-run/react'
-import { Section, H2 } from '~/features/components'
-import { EventList } from '../EventList'
-import type { LoaderData } from '../../loader'
-
-export const UpcomingEvents = () => {
- const res = useAsyncValue() as Awaited
-
- if (res.success === false) {
- return null
- }
-
- return (
-
- )
-}
diff --git a/app/pages/Events/index.tsx b/app/pages/Events/index.tsx
index 588f18a..589206c 100644
--- a/app/pages/Events/index.tsx
+++ b/app/pages/Events/index.tsx
@@ -8,12 +8,13 @@ import {
Page,
Spinner
} from '~/features/components'
-import { PastEvents } from './components/PastEvents'
-import { UpcomingEvents } from './components/UpcomingEvents'
import { Suspense } from 'react'
+import { Section, H2 } from '~/features/components'
+import { EventList } from './components/EventList'
+import { CatchErrorBoundary } from '~/features/components'
const Events = () => {
- const { pastEventsPromise, upcomingEventsPromise } =
+ const { upcomingEventsPromise, pastEventsPromise } =
useLoaderData() as LoaderData
return (
@@ -28,14 +29,36 @@ const Events = () => {
Events
-
}>
-
-
-
-
-
-
-
+
+ Upcoming events
+ }>
+
+
+ {(res) => {
+ if (res.success === false) {
+ throw new Error(res.message)
+ }
+ return
+ }}
+
+
+
+
+
+ Past events
+ }>
+
+
+ {(res) => {
+ if (res.success === false) {
+ throw new Error(res.message)
+ }
+ return
+ }}
+
+
+
+
)
diff --git a/package.json b/package.json
index dc06a6b..c07a3e8 100644
--- a/package.json
+++ b/package.json
@@ -65,6 +65,7 @@
"marked": "^4.2.12",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "react-error-boundary": "^4.0.11",
"react-schemaorg": "^2.0.0",
"remix-image": "^1.4.0",
"schema-dts": "^1.1.2"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index bcd7187..814e0dd 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1,5 +1,9 @@
lockfileVersion: '6.0'
+settings:
+ autoInstallPeers: false
+ excludeLinksFromLockfile: false
+
dependencies:
'@headlessui/react':
specifier: ^1.7.12
@@ -49,6 +53,9 @@ dependencies:
react-dom:
specifier: ^18.2.0
version: 18.2.0(react@18.2.0)
+ react-error-boundary:
+ specifier: ^4.0.11
+ version: 4.0.11(react@18.2.0)
react-schemaorg:
specifier: ^2.0.0
version: 2.0.0(react@18.2.0)(schema-dts@1.1.2)(typescript@4.9.5)
@@ -1528,7 +1535,6 @@ packages:
engines: {node: '>=6.9.0'}
dependencies:
regenerator-runtime: 0.13.11
- dev: true
/@babel/template@7.20.7:
resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==}
@@ -4844,6 +4850,7 @@ packages:
/bindings@1.5.0:
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
+ requiresBuild: true
dependencies:
file-uri-to-path: 1.0.0
dev: true
@@ -6872,6 +6879,7 @@ packages:
/file-uri-to-path@1.0.0:
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
+ requiresBuild: true
dev: true
optional: true
@@ -9478,6 +9486,7 @@ packages:
/node-addon-api@1.7.2:
resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==}
+ requiresBuild: true
dev: true
optional: true
@@ -10411,6 +10420,15 @@ packages:
react: 18.2.0
scheduler: 0.23.0
+ /react-error-boundary@4.0.11(react@18.2.0):
+ resolution: {integrity: sha512-U13ul67aP5DOSPNSCWQ/eO0AQEYzEFkVljULQIjMV0KlffTAhxuDoBKdO0pb/JZ8mDhMKFZ9NZi0BmLGUiNphw==}
+ peerDependencies:
+ react: '>=16.13.1'
+ dependencies:
+ '@babel/runtime': 7.21.0
+ react: 18.2.0
+ dev: false
+
/react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
dev: true
@@ -10566,7 +10584,6 @@ packages:
/regenerator-runtime@0.13.11:
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
- dev: true
/regenerator-transform@0.15.1:
resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==}