mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-06 15:22:12 +03:00
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.
87 lines
2.9 KiB
TypeScript
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>
|
|
);
|
|
}
|