'use client';
import Link from 'next/link';
import { motion } from 'framer-motion';
import {
HomeIcon,
ArrowLeftIcon,
ExclamationTriangleIcon,
XCircleIcon,
ClockIcon,
ServerIcon,
WifiIcon
} from '@heroicons/react/24/outline';
export interface ErrorPageProps {
code?: number;
title?: string;
message?: string;
description?: string;
type?: '404' | '500' | '403' | 'network' | 'timeout' | 'maintenance' | 'custom';
actions?: {
primary?: {
label: string;
href?: string;
onClick?: () => void;
};
secondary?: {
label: string;
href?: string;
onClick?: () => void;
};
};
showContact?: boolean;
}
const errorConfigs = {
'404': {
icon: ,
title: '页面不见了',
message: '抱歉,我们找不到您要访问的页面。',
description: '它可能已被移动、删除,或者您输入的链接不正确。'
},
'500': {
icon: ,
title: '服务器错误',
message: '抱歉,服务器遇到了一些问题。',
description: '我们的团队正在努力解决这个问题,请稍后再试。'
},
'403': {
icon: ,
title: '访问被拒绝',
message: '抱歉,您没有权限访问此页面。',
description: '请检查您的账户权限或联系管理员。'
},
'network': {
icon: ,
title: '网络连接错误',
message: '无法连接到服务器。',
description: '请检查您的网络连接,然后重试。'
},
'timeout': {
icon: ,
title: '请求超时',
message: '请求处理时间过长。',
description: '请刷新页面或稍后再试。'
},
'maintenance': {
icon: ,
title: '系统维护中',
message: '我们正在进行系统维护。',
description: '请稍后再试,我们会尽快恢复服务。'
}
};
export function ErrorPage({
code,
title,
message,
description,
type = 'custom',
actions,
showContact = true
}: ErrorPageProps) {
const config = errorConfigs[type] || {};
const displayTitle = title || config.title || '出错了';
const displayMessage = message || config.message || '发生了一些错误';
const displayDescription = description || config.description || '';
const defaultActions = {
primary: {
label: '返回主页',
href: '/'
},
secondary: {
label: '返回上页',
onClick: () => window.history.back()
}
};
const finalActions = { ...defaultActions, ...actions };
const getIconColor = () => {
switch (type) {
case '404': return 'text-orange-500';
case '500': return 'text-red-500';
case '403': return 'text-yellow-500';
case 'network': return 'text-blue-500';
case 'timeout': return 'text-purple-500';
case 'maintenance': return 'text-gray-500';
default: return 'text-orange-500';
}
};
const getCodeColor = () => {
switch (type) {
case '404': return 'from-orange-400 via-orange-500 to-amber-500';
case '500': return 'from-red-400 via-red-500 to-pink-500';
case '403': return 'from-yellow-400 via-yellow-500 to-orange-500';
case 'network': return 'from-blue-400 via-blue-500 to-cyan-500';
case 'timeout': return 'from-purple-400 via-purple-500 to-pink-500';
case 'maintenance': return 'from-gray-400 via-gray-500 to-slate-500';
default: return 'from-orange-400 via-orange-500 to-amber-500';
}
};
return (
{/* 错误代码 */}
{code && (
{code}
)}
{/* 图标 */}
{config.icon || }
{/* 错误信息 */}
{displayTitle}
{displayMessage}
{displayDescription && (
{displayDescription}
)}
{/* 操作按钮 */}
{finalActions.primary && (
finalActions.primary.href ? (
{finalActions.primary.label}
) : (
)
)}
{finalActions.secondary && (
finalActions.secondary.href ? (
{finalActions.secondary.label}
) : (
)
)}
{/* 联系信息 */}
{showContact && (
如果问题持续存在,请
联系我们
的支持团队
)}
{/* 背景装饰 */}
);
}
// 预设的错误页面组件
export function NotFoundPage() {
return ;
}
export function ServerErrorPage() {
return ;
}
export function ForbiddenPage() {
return ;
}
export function NetworkErrorPage() {
return ;
}
export function TimeoutErrorPage() {
return ;
}
export function MaintenancePage() {
return ;
}