Files
legal-ai/web-ui/src/app/error.tsx
Chaim cbe9d60901 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>
2026-04-11 17:43:59 +00:00

58 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useEffect } from "react";
import Link from "next/link";
import { AlertTriangle } from "lucide-react";
import { Button } from "@/components/ui/button";
/*
* Route-segment error boundary. Next 16 App Router convention: this file
* catches render-time errors thrown below the root layout. `reset` clears
* the error and re-renders the segment; we keep the user's nav in place
* (no AppShell here — the shell re-renders from the layout above us).
*/
export default function ErrorPage({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
useEffect(() => {
console.error("Route error:", error);
}, [error]);
return (
<main className="flex-1 w-full max-w-[1400px] mx-auto px-10 py-10">
<div className="max-w-xl mx-auto text-center space-y-5 py-16">
<AlertTriangle className="w-12 h-12 text-danger mx-auto" aria-hidden="true" />
<div className="space-y-2">
<h1 className="text-navy">משהו השתבש</h1>
<p className="text-ink-muted leading-relaxed">
נכשלה טעינת המסך. זה עשוי להיות כשל זמני ברשת או באחד מה-endpoints
של FastAPI.
</p>
{error.digest && (
<p className="text-[0.72rem] text-ink-light tabular-nums">
error id: {error.digest}
</p>
)}
{error.message && (
<code className="text-[0.78rem] text-ink-soft bg-rule-soft/60 rounded px-3 py-1 inline-block mt-2">
{error.message}
</code>
)}
</div>
<div className="flex items-center justify-center gap-3">
<Button onClick={reset} className="bg-navy hover:bg-navy-soft text-parchment">
נסה שוב
</Button>
<Button variant="outline" asChild>
<Link href="/">חזרה לבית</Link>
</Button>
</div>
</div>
</main>
);
}