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>
58 lines
1.9 KiB
TypeScript
58 lines
1.9 KiB
TypeScript
"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>
|
||
);
|
||
}
|