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:
2026-04-11 17:43:59 +00:00
parent fb1f73fa25
commit cbe9d60901
9 changed files with 375 additions and 55 deletions

View 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>
);
}