Phase 6: polish — error boundaries, a11y, smoke test doc
Close out the read-only surface before cutover with three families of small fixes that the previous phases left unfinished: - Error boundaries: add src/app/error.tsx (route-segment), global-error.tsx (root crash fallback with its own minimal html/body — no Providers dependency since those may be the thing that crashed), and not-found.tsx for a Hebrew 404 instead of the default Next page. - Accessibility: wire usePathname() into AppShell so the current nav item gets aria-current="page" and a gold underline. Add aria-label + aria-hidden on the icon-only buttons that Phase 5 left text-less (corpus trash, parties-field Plus). Nav gets an aria-label of its own. - Metadata template: title on each route now reads "X · עוזר משפטי" via the layout.tsx title.template. Description localized to Jerusalem. - README: full E2E smoke test checklist covering all 9 screens, plus a backend contract table so future phases know which hook wraps which endpoint. Documents the known Gitea→Coolify webhook issue. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
60
web-ui/src/app/global-error.tsx
Normal file
60
web-ui/src/app/global-error.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
"use client";
|
||||
|
||||
/*
|
||||
* Root-level error boundary. Renders only when the root layout itself
|
||||
* crashes, so it must include its own <html> / <body>. No AppShell here —
|
||||
* the Providers that wrap AppShell are also above the crash boundary and
|
||||
* may themselves be the thing that failed.
|
||||
*/
|
||||
export default function GlobalError({
|
||||
error,
|
||||
reset,
|
||||
}: {
|
||||
error: Error & { digest?: string };
|
||||
reset: () => void;
|
||||
}) {
|
||||
return (
|
||||
<html lang="he" dir="rtl">
|
||||
<body
|
||||
style={{
|
||||
fontFamily: "system-ui, sans-serif",
|
||||
background: "#f5f1e8",
|
||||
color: "#1a1a2e",
|
||||
minHeight: "100vh",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
padding: "2rem",
|
||||
}}
|
||||
>
|
||||
<div style={{ maxWidth: 520, textAlign: "center" }}>
|
||||
<h1 style={{ color: "#0f172a", fontSize: "2rem", marginBottom: 8 }}>
|
||||
שגיאה חמורה
|
||||
</h1>
|
||||
<p style={{ color: "#6b7280", lineHeight: 1.6, marginBottom: 16 }}>
|
||||
האפליקציה נכשלה לטעון. נסה לרענן את הדף.
|
||||
</p>
|
||||
{error.digest && (
|
||||
<p style={{ fontSize: 12, color: "#9ca3af", marginBottom: 16 }}>
|
||||
error id: {error.digest}
|
||||
</p>
|
||||
)}
|
||||
<button
|
||||
onClick={reset}
|
||||
style={{
|
||||
background: "#0f172a",
|
||||
color: "#fbf8f0",
|
||||
border: 0,
|
||||
padding: "0.6rem 1.25rem",
|
||||
borderRadius: 6,
|
||||
cursor: "pointer",
|
||||
fontSize: "0.95rem",
|
||||
}}
|
||||
>
|
||||
נסה שוב
|
||||
</button>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user