92 lines
4.4 KiB
TypeScript
92 lines
4.4 KiB
TypeScript
import React from 'react';
|
|
import { Head, Link } from '@inertiajs/react';
|
|
|
|
interface ErrorPageProps {
|
|
status: number;
|
|
}
|
|
|
|
const messages: Record<number, { title: string; description: string }> = {
|
|
403: {
|
|
title: 'Access Denied',
|
|
description: "You don't have permission to access this resource.",
|
|
},
|
|
404: {
|
|
title: 'Page Not Found',
|
|
description: "The page you're looking for doesn't exist or has been moved.",
|
|
},
|
|
419: {
|
|
title: 'Session Expired',
|
|
description: 'Your session has expired. Please refresh and try again.',
|
|
},
|
|
500: {
|
|
title: 'Server Error',
|
|
description: 'Something went wrong on our end. Please try again later.',
|
|
},
|
|
503: {
|
|
title: 'Under Maintenance',
|
|
description: 'The system is temporarily unavailable. Please check back soon.',
|
|
},
|
|
};
|
|
|
|
export default function ErrorPage({ status }: ErrorPageProps) {
|
|
const { title, description } = messages[status] ?? {
|
|
title: 'Unexpected Error',
|
|
description: 'An unexpected error occurred.',
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-[#E3EBE8] flex items-center justify-center p-6">
|
|
<Head title={`${status} — ${title}`} />
|
|
|
|
<div className="w-full max-w-md">
|
|
<div className="bg-white rounded-3xl border border-gray-100 shadow-sm overflow-hidden">
|
|
<div className="bg-[#3D4E4B] px-8 py-10 text-center">
|
|
<div className="text-7xl font-black text-white/10 tracking-tighter leading-none select-none">
|
|
{status}
|
|
</div>
|
|
<div className="mt-2 text-xl font-bold text-white tracking-tight">{title}</div>
|
|
</div>
|
|
|
|
<div className="px-8 py-8 text-center space-y-6">
|
|
<p className="text-sm font-semibold text-gray-400 leading-relaxed">{description}</p>
|
|
|
|
<div className="flex flex-col sm:flex-row gap-3 justify-center">
|
|
{status !== 419 ? (
|
|
<Link
|
|
href="/dashboard"
|
|
className="h-10 px-6 bg-[#3D4E4B] text-white text-sm font-bold tracking-tight rounded-xl hover:bg-[#2D3A38] transition-all flex items-center justify-center gap-2"
|
|
>
|
|
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}>
|
|
<path strokeLinecap="round" strokeLinejoin="round" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
|
|
</svg>
|
|
Back to Dashboard
|
|
</Link>
|
|
) : (
|
|
<button
|
|
onClick={() => window.location.reload()}
|
|
className="h-10 px-6 bg-[#3D4E4B] text-white text-sm font-bold tracking-tight rounded-xl hover:bg-[#2D3A38] transition-all flex items-center justify-center gap-2"
|
|
>
|
|
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}>
|
|
<path strokeLinecap="round" strokeLinejoin="round" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
|
</svg>
|
|
Refresh Page
|
|
</button>
|
|
)}
|
|
<button
|
|
onClick={() => window.history.back()}
|
|
className="h-10 px-6 bg-white border border-gray-100 text-gray-500 text-sm font-bold tracking-tight rounded-xl hover:bg-gray-50 transition-all"
|
|
>
|
|
Go Back
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<p className="text-center text-xs font-bold text-gray-400 uppercase tracking-widest mt-6">
|
|
Error {status}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|