All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 32s
Build & Deploy / 🚀 Deploy (push) Successful in 35s
Build & Deploy / 🧪 QA (push) Successful in 1m49s
Build & Deploy / 🏗️ Build (push) Successful in 3m27s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 1m14s
Build & Deploy / 🔔 Notify (push) Successful in 3s
162 lines
7.9 KiB
TypeScript
162 lines
7.9 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect } from 'react';
|
|
import { useTranslations } from 'next-intl';
|
|
import { Button, Heading } from '@/components/ui';
|
|
import { Terminal, Activity, AlertTriangle, RefreshCw, Home, ShieldAlert } from 'lucide-react';
|
|
import { m } from 'framer-motion';
|
|
|
|
export default function Error({
|
|
error,
|
|
reset,
|
|
}: {
|
|
error: Error & { digest?: string };
|
|
reset: () => void;
|
|
}) {
|
|
const t = useTranslations('Error');
|
|
|
|
useEffect(() => {
|
|
// Force standard solid header
|
|
document.body.setAttribute('data-header-variant', 'standard');
|
|
|
|
// Treat "Failed to find Server Action" as a deployment sync issue and reload
|
|
if (error?.message?.includes('Failed to find Server Action')) {
|
|
window.location.reload();
|
|
return;
|
|
}
|
|
|
|
console.error('Application error caught by boundary', {
|
|
message: error?.message || 'Unknown error',
|
|
stack: error?.stack,
|
|
digest: error?.digest,
|
|
});
|
|
|
|
return () => {
|
|
document.body.removeAttribute('data-header-variant');
|
|
};
|
|
}, [error]);
|
|
|
|
return (
|
|
<div className="relative min-h-screen flex flex-col items-center justify-center overflow-hidden bg-[#050B14] py-24 px-4">
|
|
{/* Industrial Blueprint Background */}
|
|
<div className="absolute inset-0 opacity-[0.03] pointer-events-none">
|
|
<div className="absolute inset-0 bg-[linear-gradient(to_right,#ffffff_1px,transparent_1px),linear-gradient(to_bottom,#ffffff_1px,transparent_1px)] bg-[size:100px_100px]" />
|
|
<div className="absolute inset-0 bg-[linear-gradient(to_right,#ffffff_1px,transparent_1px),linear-gradient(to_bottom,#ffffff_1px,transparent_1px)] bg-[size:20px_20px]" />
|
|
</div>
|
|
|
|
{/* Decorative Technical Annotations */}
|
|
<div className="absolute inset-0 pointer-events-none overflow-hidden select-none">
|
|
<div className="absolute top-40 left-10 text-[10px] font-mono text-primary/30 uppercase tracking-[0.2em] rotate-90 origin-left">
|
|
System_Core_Access :: Restricted
|
|
</div>
|
|
<div className="absolute bottom-40 right-10 text-[10px] font-mono text-primary/30 uppercase tracking-[0.2em] -rotate-90 origin-right">
|
|
Protocol_Failure :: Type_500
|
|
</div>
|
|
<div className="absolute top-1/4 right-20 w-32 h-px bg-primary/20" />
|
|
<div className="absolute top-1/4 right-20 w-px h-32 bg-primary/20" />
|
|
</div>
|
|
|
|
{/* Background Glow */}
|
|
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] bg-red-500/10 blur-[150px] rounded-full pointer-events-none animate-pulse" />
|
|
|
|
<div className="relative z-10 w-full max-w-4xl mx-auto flex flex-col items-center">
|
|
{/* The "Broken" Machine Visual */}
|
|
<div className="relative mb-12">
|
|
<m.div
|
|
initial={{ opacity: 0, scale: 0.8 }}
|
|
animate={{ opacity: 1, scale: 1 }}
|
|
className="relative"
|
|
>
|
|
<h1 className="text-[12rem] md:text-[18rem] font-heading font-black leading-none select-none">
|
|
<span className="relative inline-block text-transparent bg-clip-text bg-gradient-to-b from-white to-white/5 drop-shadow-[0_0_50px_rgba(255,255,255,0.1)]">
|
|
500
|
|
{/* Glitch Layers */}
|
|
<span className="absolute inset-0 text-red-500/30 translate-x-[2px] -translate-y-[1px] mix-blend-screen animate-pulse pointer-events-none">500</span>
|
|
<span className="absolute inset-0 text-blue-500/30 -translate-x-[2px] translate-y-[1px] mix-blend-screen animate-pulse pointer-events-none">500</span>
|
|
</span>
|
|
</h1>
|
|
|
|
{/* Warning Overlay */}
|
|
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex flex-col items-center">
|
|
<m.div
|
|
animate={{
|
|
opacity: [0.4, 1, 0.4],
|
|
scale: [0.95, 1.05, 0.95]
|
|
}}
|
|
transition={{ duration: 2, repeat: Infinity }}
|
|
className="p-4 rounded-2xl bg-red-500/20 border border-red-500/40 backdrop-blur-md shadow-[0_0_30px_rgba(239,68,68,0.3)]"
|
|
>
|
|
<ShieldAlert className="w-12 h-12 text-red-500" />
|
|
</m.div>
|
|
</div>
|
|
</m.div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-12 gap-8 w-full items-start">
|
|
{/* Main Content */}
|
|
<div className="md:col-span-7 text-center md:text-left">
|
|
<div className="inline-flex items-center gap-3 px-4 py-2 mb-6 rounded-lg bg-red-500/10 border border-red-500/20 text-[10px] font-mono uppercase tracking-widest text-red-400">
|
|
<Activity className="w-4 h-4 animate-pulse" />
|
|
CRITICAL_SYSTEM_OVERRIDE :: ACTIVE
|
|
</div>
|
|
|
|
<Heading level={1} className="text-3xl md:text-5xl font-bold mb-6 text-white leading-tight">
|
|
{t('title')}
|
|
</Heading>
|
|
|
|
<p className="text-white/50 mb-10 max-w-lg text-lg leading-relaxed">
|
|
{t('description')}
|
|
</p>
|
|
|
|
<div className="flex flex-col sm:flex-row gap-4 justify-center md:justify-start">
|
|
<Button
|
|
onClick={() => reset()}
|
|
variant="primary"
|
|
className="group h-14 px-10 shadow-[0_0_30px_rgba(var(--color-primary),0.2)] hover:shadow-primary/40 transition-all"
|
|
>
|
|
<RefreshCw className="w-5 h-5 mr-3 group-hover:rotate-180 transition-transform duration-700" />
|
|
{t('tryAgain')}
|
|
</Button>
|
|
<Button
|
|
href="/"
|
|
variant="outline"
|
|
className="h-14 px-8 border-white/10 text-white hover:bg-white/5"
|
|
>
|
|
<Home className="w-5 h-5 mr-3" />
|
|
{t('goHome')}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Technical Log Terminal */}
|
|
<div className="md:col-span-5">
|
|
<div className="bg-black/40 backdrop-blur-xl border border-white/10 rounded-2xl overflow-hidden shadow-2xl">
|
|
<div className="bg-white/5 px-4 py-2 border-b border-white/10 flex items-center justify-between">
|
|
<div className="flex gap-1.5">
|
|
<div className="w-2.5 h-2.5 rounded-full bg-red-500/50" />
|
|
<div className="w-2.5 h-2.5 rounded-full bg-yellow-500/50" />
|
|
<div className="w-2.5 h-2.5 rounded-full bg-green-500/50" />
|
|
</div>
|
|
<div className="text-[10px] font-mono text-white/30 tracking-wider">TERMINAL_OUTPUT</div>
|
|
</div>
|
|
<div className="p-6 font-mono text-xs leading-relaxed overflow-hidden h-[240px]">
|
|
<div className="text-primary/70 mb-1 animate-[fade-in_0.5s_ease-out_forwards]">[SYSTEM] Initializing recovery protocol...</div>
|
|
<div className="text-red-500/80 mb-1 animate-[fade-in_0.5s_ease-out_0.5s_forwards] opacity-0">[ERROR] Connection timeout at node 0x7F</div>
|
|
<div className="text-white/40 mb-1 animate-[fade-in_0.5s_ease-out_1s_forwards] opacity-0">[INFO] Request ID: {error?.digest || '0xDEADBEEF'}</div>
|
|
<div className="text-white/40 mb-1 animate-[fade-in_0.5s_ease-out_1.5s_forwards] opacity-0">[INFO] Timestamp: {new Date().toISOString()}</div>
|
|
<div className="text-white/40 mb-1 animate-[fade-in_0.5s_ease-out_2s_forwards] opacity-0">[INFO] Trace: {error?.message?.slice(0, 40)}...</div>
|
|
<div className="text-primary/70 mt-4 animate-[pulse_1.5s_infinite] opacity-0 animate-[fade-in_0.5s_ease-out_2.5s_forwards]">_ Waiting for user input...</div>
|
|
</div>
|
|
<div className="bg-red-500/10 p-3 flex items-center gap-3">
|
|
<Terminal className="w-4 h-4 text-red-400" />
|
|
<div className="text-[10px] font-bold text-red-400 uppercase tracking-tighter">Status: Handshake_Failed</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|