Files
no-whatever/src/app/error.tsx
T
kurihada 4ce6ea469c feat: 添加全局 Error Boundary 和餐厅图片加载失败 fallback
- error.tsx: 路由级错误边界,提供重试和返回首页操作
- global-error.tsx: 根布局级兜底,纯内联样式避免依赖加载
- RestaurantImage: 可复用图片组件,加载失败显示餐具占位图标
- 替换 RestaurantCard、MatchResult、profile 中所有餐厅图片
2026-02-26 15:22:29 +08:00

59 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useEffect } from "react";
import { motion } from "framer-motion";
import { AlertTriangle, RotateCcw, Home } from "lucide-react";
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
useEffect(() => {
console.error("[ErrorBoundary]", error);
}, [error]);
return (
<div className="flex min-h-dvh flex-col items-center justify-center bg-background px-6">
<motion.div
className="flex flex-col items-center text-center"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
>
<motion.div
className="relative flex h-20 w-20 items-center justify-center"
animate={{ y: [0, -4, 0] }}
transition={{ duration: 2.5, repeat: Infinity, ease: "easeInOut" }}
>
<div className="absolute inset-0 rounded-2xl bg-rose-500/15 blur-lg" />
<AlertTriangle size={36} className="relative text-rose-400/80" strokeWidth={1.5} />
</motion.div>
<h1 className="mt-6 text-xl font-bold text-heading"></h1>
<p className="mt-2 max-w-xs text-sm text-muted">
</p>
<div className="mt-8 flex gap-3">
<button
onClick={reset}
className="flex items-center gap-1.5 rounded-xl bg-rose-600 px-5 py-2.5 text-sm font-semibold text-white transition-colors hover:bg-rose-500"
>
<RotateCcw size={15} />
</button>
<a
href="/"
className="flex items-center gap-1.5 rounded-xl bg-surface px-5 py-2.5 text-sm font-semibold text-secondary ring-1 ring-border transition-colors hover:bg-elevated"
>
<Home size={15} />
</a>
</div>
</motion.div>
</div>
);
}