Add custom error and global-error pages matching site design
Adds app/error.tsx (client error boundary, reuses Header/Footer/Button) and app/global-error.tsx (root layout crash fallback with self-contained html/body and manually replicated styling), both bilingual (ES/EN) and matching the brand's colors, fonts, and tone. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
cacc52ec24
commit
09bfb17f03
@@ -0,0 +1,54 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import Link from 'next/link';
|
||||
import Header from '@/components/layout/Header';
|
||||
import Footer from '@/components/layout/Footer';
|
||||
import Button from '@/components/ui/Button';
|
||||
|
||||
export default function Error({
|
||||
error,
|
||||
reset,
|
||||
}: {
|
||||
error: Error & { digest?: string };
|
||||
reset: () => void;
|
||||
}) {
|
||||
useEffect(() => {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.error(error);
|
||||
}
|
||||
}, [error]);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex flex-col">
|
||||
<Header />
|
||||
<main className="flex-1 flex items-center justify-center bg-secondary-gray px-4 py-16">
|
||||
<div className="text-center max-w-md mx-auto">
|
||||
<div className="text-6xl mb-4">😅</div>
|
||||
<h1 className="text-3xl font-semibold text-primary-dark mb-2">
|
||||
¡Ups! Algo salió mal
|
||||
</h1>
|
||||
<p className="text-lg text-gray-700 mb-6">
|
||||
Oops, something went wrong
|
||||
</p>
|
||||
<p className="text-gray-600 mb-8">
|
||||
No fue tu culpa, fue un error de nuestro lado. Prueba de nuevo o vuelve al inicio mientras lo revisamos.
|
||||
<br />
|
||||
It was not your fault, something broke on our end. Try again or head back home while we take a look.
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<Button onClick={reset} size="lg">
|
||||
Intentar de nuevo · Try again
|
||||
</Button>
|
||||
<Link href="/">
|
||||
<Button variant="outline" size="lg" className="w-full sm:w-auto">
|
||||
Ir al inicio · Go home
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { Poppins } from 'next/font/google';
|
||||
import './globals.css';
|
||||
|
||||
const poppins = Poppins({
|
||||
subsets: ['latin'],
|
||||
display: 'swap',
|
||||
variable: '--font-poppins',
|
||||
weight: ['400', '500', '600', '700'],
|
||||
});
|
||||
|
||||
export default function GlobalError({
|
||||
error,
|
||||
reset,
|
||||
}: {
|
||||
error: Error & { digest?: string };
|
||||
reset: () => void;
|
||||
}) {
|
||||
useEffect(() => {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.error(error);
|
||||
}
|
||||
}, [error]);
|
||||
|
||||
return (
|
||||
<html lang="en" className={poppins.variable}>
|
||||
<body className={poppins.className}>
|
||||
<div className="min-h-screen flex flex-col bg-secondary-gray">
|
||||
<header className="bg-white shadow-sm">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center">
|
||||
<span className="text-xl font-semibold" style={{ color: '#002F44' }}>
|
||||
Spanglish
|
||||
</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="flex-1 flex items-center justify-center px-4 py-16">
|
||||
<div className="text-center max-w-md mx-auto bg-white rounded-card shadow-card p-8">
|
||||
<div className="text-6xl mb-4">😵</div>
|
||||
<h1 className="text-2xl font-semibold text-primary-dark mb-2">
|
||||
¡Ups! Algo salió mal
|
||||
</h1>
|
||||
<p className="text-lg text-gray-700 mb-4">
|
||||
Oops, something went wrong
|
||||
</p>
|
||||
<p className="text-gray-600 mb-8">
|
||||
Toda la página tuvo un problema al cargar. Prueba de nuevo o vuelve al inicio.
|
||||
<br />
|
||||
The whole page had trouble loading. Try again or head back home.
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<button
|
||||
onClick={reset}
|
||||
className="inline-flex items-center justify-center px-7 py-3 text-lg font-medium rounded-btn bg-primary-yellow text-primary-dark hover:bg-yellow-400 transition-colors"
|
||||
>
|
||||
Intentar de nuevo · Try again
|
||||
</button>
|
||||
<a
|
||||
href="/"
|
||||
className="inline-flex items-center justify-center px-7 py-3 text-lg font-medium rounded-btn border-2 border-primary-dark text-primary-dark hover:bg-gray-50 transition-colors"
|
||||
>
|
||||
Ir al inicio · Go home
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer className="border-t border-secondary-light-gray py-6">
|
||||
<p className="text-center text-sm" style={{ color: '#002F44' }}>
|
||||
© {new Date().getFullYear()} Spanglish
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user