almeira-web/dripzone-app/src/app/error.tsx

88 lines
3.4 KiB
TypeScript

'use client';
import React, { useEffect } from 'react';
import Link from 'next/link';
import { RefreshCw, Home, ShoppingBag, Sparkles } from 'lucide-react';
export default function GlobalAppError({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
useEffect(() => {
console.error('[AppError Boundary]:', error);
const isChunkError =
error.message?.includes('Loading chunk') ||
error.message?.includes('ChunkLoadError') ||
error.message?.includes('Failed to fetch dynamically imported module');
if (isChunkError) {
const lastReload = sessionStorage.getItem('dripzone_root_error_reload');
const now = Date.now();
if (!lastReload || now - parseInt(lastReload, 10) > 10000) {
sessionStorage.setItem('dripzone_root_error_reload', now.toString());
window.location.reload();
}
}
}, [error]);
const handleHardReload = () => {
try {
sessionStorage.removeItem('dripzone_root_error_reload');
window.location.href = window.location.pathname + '?v=' + Date.now();
} catch (_) {
window.location.reload();
}
};
return (
<div className="min-h-screen bg-neutral-950 text-white flex flex-col items-center justify-center p-4">
<div className="max-w-md w-full bg-neutral-900/90 border border-purple-500/30 rounded-3xl p-8 text-center space-y-6 shadow-2xl backdrop-blur-xl relative overflow-hidden">
<div className="absolute top-0 right-0 w-48 h-48 bg-purple-600/10 rounded-full blur-3xl pointer-events-none" />
<div className="w-16 h-16 rounded-2xl bg-purple-500/15 border border-purple-500/40 text-purple-400 flex items-center justify-center mx-auto shadow-inner">
<Sparkles className="w-8 h-8 text-purple-400 animate-pulse" />
</div>
<div className="space-y-2">
<h2 className="text-xl font-black tracking-tight text-white">DripZone Luxury Store</h2>
<p className="text-xs text-neutral-400 leading-relaxed">
Hemos actualizado la vitrina con nuevos lanzamientos exclusivos.
Recarga para ver la versión más reciente del catálogo.
</p>
</div>
<div className="space-y-2.5 pt-2">
<button
onClick={handleHardReload}
className="w-full bg-gradient-to-r from-purple-600 to-fuchsia-600 hover:from-purple-500 hover:to-fuchsia-500 text-white font-black text-xs py-3.5 px-4 rounded-xl flex items-center justify-center gap-2 shadow-lg shadow-purple-900/40 cursor-pointer transition-all active:scale-98"
>
<RefreshCw className="w-4 h-4" />
<span>Recargar Catálogo</span>
</button>
<div className="grid grid-cols-2 gap-2">
<button
onClick={() => reset()}
className="bg-neutral-800 hover:bg-neutral-700 text-neutral-200 font-bold text-xs py-2.5 px-3 rounded-xl flex items-center justify-center gap-1.5 cursor-pointer transition-all"
>
<span>Reintentar</span>
</button>
<Link
href="/"
className="bg-neutral-800 hover:bg-neutral-700 text-neutral-200 font-bold text-xs py-2.5 px-3 rounded-xl flex items-center justify-center gap-1.5 cursor-pointer transition-all"
>
<Home className="w-3.5 h-3.5 text-neutral-400" />
<span>Inicio</span>
</Link>
</div>
</div>
</div>
</div>
);
}