diff --git a/src/app/connect/error.tsx b/src/app/connect/error.tsx
new file mode 100644
index 0000000..f710bfa
--- /dev/null
+++ b/src/app/connect/error.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+export default function RouteError({
+ error,
+ reset,
+}: {
+ error: Error & { digest?: string };
+ reset: () => void;
+}) {
+ return (
+
+
{'Connection failed'}
+
+ {'Unable to complete the sign-in flow. Please try again.'}
+
+ {error.digest && (
+
Ref: {error.digest}
+ )}
+
+
+ );
+}
diff --git a/src/app/connect/loading.tsx b/src/app/connect/loading.tsx
new file mode 100644
index 0000000..f891f3a
--- /dev/null
+++ b/src/app/connect/loading.tsx
@@ -0,0 +1,19 @@
+export default function Loading() {
+ return (
+
+
+
+
+
+
Loading {'connection'}…
+
+ );
+}
diff --git a/src/app/dashboard/contributor/error.tsx b/src/app/dashboard/contributor/error.tsx
new file mode 100644
index 0000000..f659e43
--- /dev/null
+++ b/src/app/dashboard/contributor/error.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+export default function RouteError({
+ error,
+ reset,
+}: {
+ error: Error & { digest?: string };
+ reset: () => void;
+}) {
+ return (
+
+
{'Dashboard error'}
+
+ {'Your contributor dashboard failed to load. Retry below.'}
+
+ {error.digest && (
+
Ref: {error.digest}
+ )}
+
+
+ );
+}
diff --git a/src/app/dashboard/contributor/loading.tsx b/src/app/dashboard/contributor/loading.tsx
new file mode 100644
index 0000000..cef236a
--- /dev/null
+++ b/src/app/dashboard/contributor/loading.tsx
@@ -0,0 +1,19 @@
+export default function Loading() {
+ return (
+
+
+
+
+
+
Loading {'contributor dashboard'}…
+
+ );
+}
diff --git a/src/app/dashboard/maintainer/error.tsx b/src/app/dashboard/maintainer/error.tsx
new file mode 100644
index 0000000..d7c8fa7
--- /dev/null
+++ b/src/app/dashboard/maintainer/error.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+export default function RouteError({
+ error,
+ reset,
+}: {
+ error: Error & { digest?: string };
+ reset: () => void;
+}) {
+ return (
+
+
{'Dashboard error'}
+
+ {'Your maintainer dashboard failed to load. Retry below.'}
+
+ {error.digest && (
+
Ref: {error.digest}
+ )}
+
+
+ );
+}
diff --git a/src/app/dashboard/maintainer/loading.tsx b/src/app/dashboard/maintainer/loading.tsx
new file mode 100644
index 0000000..9eeefdf
--- /dev/null
+++ b/src/app/dashboard/maintainer/loading.tsx
@@ -0,0 +1,19 @@
+export default function Loading() {
+ return (
+
+
+
+
+
+
Loading {'maintainer dashboard'}…
+
+ );
+}
diff --git a/src/app/dashboard/sponsor/error.tsx b/src/app/dashboard/sponsor/error.tsx
new file mode 100644
index 0000000..b0c4149
--- /dev/null
+++ b/src/app/dashboard/sponsor/error.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+export default function RouteError({
+ error,
+ reset,
+}: {
+ error: Error & { digest?: string };
+ reset: () => void;
+}) {
+ return (
+
+
{'Dashboard error'}
+
+ {'Your sponsor dashboard failed to load. Retry below.'}
+
+ {error.digest && (
+
Ref: {error.digest}
+ )}
+
+
+ );
+}
diff --git a/src/app/dashboard/sponsor/loading.tsx b/src/app/dashboard/sponsor/loading.tsx
new file mode 100644
index 0000000..ab0a46d
--- /dev/null
+++ b/src/app/dashboard/sponsor/loading.tsx
@@ -0,0 +1,19 @@
+export default function Loading() {
+ return (
+
+
+
+
+
+
Loading {'sponsor dashboard'}…
+
+ );
+}
diff --git a/src/app/error.tsx b/src/app/error.tsx
new file mode 100644
index 0000000..9cf3322
--- /dev/null
+++ b/src/app/error.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+export default function RouteError({
+ error,
+ reset,
+}: {
+ error: Error & { digest?: string };
+ reset: () => void;
+}) {
+ return (
+
+
{'Something went wrong'}
+
+ {'The home page encountered an error. Please try again.'}
+
+ {error.digest && (
+
Ref: {error.digest}
+ )}
+
+
+ );
+}
diff --git a/src/app/global-error.tsx b/src/app/global-error.tsx
new file mode 100644
index 0000000..ddcef2b
--- /dev/null
+++ b/src/app/global-error.tsx
@@ -0,0 +1,31 @@
+"use client";
+
+export default function GlobalError({
+ error,
+ reset,
+}: {
+ error: Error & { digest?: string };
+ reset: () => void;
+}) {
+ return (
+
+
+
+
Something went wrong
+
+ An unexpected error occurred. This has been logged for investigation.
+
+ {error.digest && (
+
Error ID: {error.digest}
+ )}
+
+
+
+
+ );
+}
diff --git a/src/app/issues/[id]/error.tsx b/src/app/issues/[id]/error.tsx
new file mode 100644
index 0000000..93eb695
--- /dev/null
+++ b/src/app/issues/[id]/error.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+export default function RouteError({
+ error,
+ reset,
+}: {
+ error: Error & { digest?: string };
+ reset: () => void;
+}) {
+ return (
+
+
{'Failed to load bounty details'}
+
+ {'This bounty may have been removed or the server is unavailable.'}
+
+ {error.digest && (
+
Ref: {error.digest}
+ )}
+
+
+ );
+}
diff --git a/src/app/issues/[id]/loading.tsx b/src/app/issues/[id]/loading.tsx
new file mode 100644
index 0000000..e0b1d41
--- /dev/null
+++ b/src/app/issues/[id]/loading.tsx
@@ -0,0 +1,19 @@
+export default function Loading() {
+ return (
+
+
+
+
+
+
Loading {'bounty details'}…
+
+ );
+}
diff --git a/src/app/issues/error.tsx b/src/app/issues/error.tsx
new file mode 100644
index 0000000..e8c3bd7
--- /dev/null
+++ b/src/app/issues/error.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+export default function RouteError({
+ error,
+ reset,
+}: {
+ error: Error & { digest?: string };
+ reset: () => void;
+}) {
+ return (
+
+
{'Failed to load bounties'}
+
+ {"We couldn't fetch the bounty list. Check your connection and retry."}
+
+ {error.digest && (
+
Ref: {error.digest}
+ )}
+
+
+ );
+}
diff --git a/src/app/issues/loading.tsx b/src/app/issues/loading.tsx
new file mode 100644
index 0000000..4611600
--- /dev/null
+++ b/src/app/issues/loading.tsx
@@ -0,0 +1,19 @@
+export default function Loading() {
+ return (
+
+
+
+
+
+
Loading {'bounties'}…
+
+ );
+}
diff --git a/src/app/loading.tsx b/src/app/loading.tsx
new file mode 100644
index 0000000..d4d6b85
--- /dev/null
+++ b/src/app/loading.tsx
@@ -0,0 +1,19 @@
+export default function Loading() {
+ return (
+
+
+
+
+
+
Loading {'home'}…
+
+ );
+}
diff --git a/src/app/milestones/error.tsx b/src/app/milestones/error.tsx
new file mode 100644
index 0000000..1f6c2a8
--- /dev/null
+++ b/src/app/milestones/error.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+export default function RouteError({
+ error,
+ reset,
+}: {
+ error: Error & { digest?: string };
+ reset: () => void;
+}) {
+ return (
+
+
{'Failed to load milestones'}
+
+ {'Milestone data could not be retrieved. Please retry.'}
+
+ {error.digest && (
+
Ref: {error.digest}
+ )}
+
+
+ );
+}
diff --git a/src/app/milestones/loading.tsx b/src/app/milestones/loading.tsx
new file mode 100644
index 0000000..c446cb3
--- /dev/null
+++ b/src/app/milestones/loading.tsx
@@ -0,0 +1,19 @@
+export default function Loading() {
+ return (
+
+
+
+
+
+
Loading {'milestones'}…
+
+ );
+}
diff --git a/src/app/reputation/[handle]/error.tsx b/src/app/reputation/[handle]/error.tsx
new file mode 100644
index 0000000..bf30ac5
--- /dev/null
+++ b/src/app/reputation/[handle]/error.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+export default function RouteError({
+ error,
+ reset,
+}: {
+ error: Error & { digest?: string };
+ reset: () => void;
+}) {
+ return (
+
+
{'Profile not available'}
+
+ {'This reputation profile could not be loaded.'}
+
+ {error.digest && (
+
Ref: {error.digest}
+ )}
+
+
+ );
+}
diff --git a/src/app/reputation/[handle]/loading.tsx b/src/app/reputation/[handle]/loading.tsx
new file mode 100644
index 0000000..bbf21a8
--- /dev/null
+++ b/src/app/reputation/[handle]/loading.tsx
@@ -0,0 +1,19 @@
+export default function Loading() {
+ return (
+
+
+
+
+
+
Loading {'reputation profile'}…
+
+ );
+}