Files
OmniRoute/src/shared/components/ErrorPageScaffold.tsx
diegosouzapw 052eb8d330 refactor: replace any types with generics and add Zod validation schemas
Eliminate `any` usage across the codebase by introducing proper generics,
typed interfaces (StatementLike, DbLike, PromptRow, etc.), and helper
conversion functions (toNumber, toString, parseVariables). Add
comprehensive Zod validation schemas for API endpoint inputs to enforce
runtime type safety alongside compile-time checks.
2026-03-04 18:59:27 -03:00

87 lines
2.9 KiB
TypeScript

import Link from "next/link";
interface PageAction {
href: string;
label: string;
}
interface ErrorPageScaffoldProps {
code: string;
title: string;
description: string;
icon?: string;
suggestions?: string[];
primaryAction?: PageAction;
secondaryAction?: PageAction;
}
export default function ErrorPageScaffold({
code,
title,
description,
icon = "error",
suggestions = [],
primaryAction = { href: "/dashboard", label: "Go to Dashboard" },
secondaryAction = { href: "/status", label: "Check System Status" },
}: ErrorPageScaffoldProps) {
return (
<main
className="min-h-screen bg-bg text-text-main flex items-center justify-center px-6 py-12"
role="main"
aria-labelledby="error-page-title"
>
<section className="w-full max-w-2xl rounded-2xl border border-border bg-surface p-8 sm:p-10 shadow-soft">
<header className="text-center">
<span className="material-symbols-outlined text-4xl text-primary mb-3" aria-hidden="true">
{icon}
</span>
<p
className="text-6xl sm:text-7xl font-bold leading-none bg-gradient-to-br from-primary to-primary-hover bg-clip-text text-transparent"
aria-hidden="true"
>
{code}
</p>
<h1 id="error-page-title" className="mt-4 text-2xl sm:text-3xl font-semibold">
{title}
</h1>
<p className="mt-3 text-text-muted leading-relaxed">{description}</p>
</header>
{suggestions.length > 0 && (
<ul
className="mt-8 rounded-xl border border-border bg-bg-alt p-5 space-y-2 text-sm text-text-muted"
aria-label="Recommended actions"
>
{suggestions.map((item) => (
<li key={item} className="flex items-start gap-2">
<span
className="material-symbols-outlined text-base text-primary mt-0.5"
aria-hidden="true"
>
check_circle
</span>
<span>{item}</span>
</li>
))}
</ul>
)}
<div className="mt-8 flex flex-col sm:flex-row gap-3">
<Link
href={primaryAction.href}
className="inline-flex items-center justify-center px-6 py-3 rounded-lg text-white text-sm font-semibold bg-gradient-to-br from-primary to-primary-hover hover:shadow-elevated transition-all duration-200 motion-reduce:transition-none"
>
{primaryAction.label}
</Link>
<Link
href={secondaryAction.href}
className="inline-flex items-center justify-center px-6 py-3 rounded-lg text-sm font-semibold border border-border hover:bg-bg-alt transition-colors duration-200 motion-reduce:transition-none"
>
{secondaryAction.label}
</Link>
</div>
</section>
</main>
);
}