feat: enhance API error handling and UI improvements
Some checks failed
lotteryfront CI / build (push) Has been cancelled
Some checks failed
lotteryfront CI / build (push) Has been cancelled
- Updated `getPublicCurrencies` and `getPlayerAuthCaptcha` functions to include `skipGlobalServerError` option, improving error handling for API requests. - Refactored the NotFoundPage component to enhance mobile responsiveness and UI consistency, integrating `PlayerMobileViewport`. - Improved the NetworkStatusBanner and OfflineBanner components by adding player banner height reference for better layout management. - Updated Wallet components to utilize `PlayerMoneyDisplay` for consistent currency representation and added credit mode handling in various screens. - Enhanced the WalletScreen and Transfer screens with loading panels and credit guard logic for better user experience during wallet operations.
This commit is contained in:
@@ -4,87 +4,70 @@ import Link from "next/link";
|
||||
import { FileQuestion, Home } from "lucide-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { ERROR_COLORS } from "@/stores/error-store";
|
||||
import { PlayerMobileViewport } from "@/components/layout/player-mobile-viewport";
|
||||
import { playerViewportColumnClass } from "@/lib/player-viewport";
|
||||
import { cn } from "@/lib/utils";
|
||||
import "@/i18n";
|
||||
|
||||
/**
|
||||
* 全局 404 页面
|
||||
* 当访问不存在的路由时显示
|
||||
* 消息:"页面不存在"
|
||||
* 包含 "返回首页" 按钮
|
||||
* 使用中性颜色 #d9d9d9 作为背景/插图
|
||||
*/
|
||||
export default function NotFoundPage(): React.ReactElement {
|
||||
const { t } = useTranslation("player");
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex min-h-screen flex-col items-center justify-center p-4"
|
||||
style={{ backgroundColor: ERROR_COLORS.neutral }}
|
||||
>
|
||||
<div className="w-full max-w-md rounded-2xl bg-white p-8 shadow-lg">
|
||||
<div className="flex flex-col items-center text-center">
|
||||
{/* 404 数字 */}
|
||||
<div
|
||||
className="mb-6 text-8xl font-bold tracking-tighter"
|
||||
style={{ color: ERROR_COLORS.neutral }}
|
||||
>
|
||||
404
|
||||
</div>
|
||||
<PlayerMobileViewport>
|
||||
<div
|
||||
className={cn(
|
||||
"flex min-h-dvh flex-col items-center justify-center bg-white px-4 py-8 text-slate-900",
|
||||
playerViewportColumnClass,
|
||||
)}
|
||||
>
|
||||
<div className="w-full rounded-2xl border border-[#e4eaf4] bg-white p-8 shadow-[0_10px_28px_rgba(15,23,42,0.08)]">
|
||||
<div className="flex flex-col items-center text-center">
|
||||
<div className="mb-4 flex size-16 items-center justify-center rounded-full bg-[#fff1f3]">
|
||||
<FileQuestion className="size-8 text-[#e5002c]" aria-hidden />
|
||||
</div>
|
||||
|
||||
{/* 图标 */}
|
||||
<div
|
||||
className="mb-6 flex size-20 items-center justify-center rounded-full"
|
||||
style={{ backgroundColor: `${ERROR_COLORS.neutral}40` }}
|
||||
>
|
||||
<FileQuestion
|
||||
className="size-10"
|
||||
style={{ color: "#666" }}
|
||||
aria-hidden
|
||||
/>
|
||||
</div>
|
||||
<p className="text-6xl font-black tracking-tight text-[#0b3f96]/20">404</p>
|
||||
|
||||
{/* 标题 */}
|
||||
<h1 className="mb-3 text-2xl font-bold text-gray-800">
|
||||
{t("notFound.title")}
|
||||
</h1>
|
||||
<h1 className="mt-2 text-xl font-black text-[#0b3f96]">
|
||||
{t("notFound.title")}
|
||||
</h1>
|
||||
|
||||
{/* 描述 */}
|
||||
<p className="mb-8 text-base text-gray-500">
|
||||
{t("notFound.description")}
|
||||
</p>
|
||||
<p className="mt-2 text-sm leading-relaxed text-slate-500">
|
||||
{t("notFound.description")}
|
||||
</p>
|
||||
|
||||
{/* 返回首页按钮 */}
|
||||
<Link
|
||||
href="/hall"
|
||||
className="inline-flex items-center justify-center gap-2 rounded-lg px-8 py-3 text-base font-medium text-white"
|
||||
style={{ backgroundColor: "#333" }}
|
||||
>
|
||||
<Home className="size-5" />
|
||||
{t("notFound.home")}
|
||||
</Link>
|
||||
|
||||
{/* 帮助链接 */}
|
||||
<div className="mt-8 flex gap-4 text-sm text-gray-400">
|
||||
<Link href="/hall" className="hover:text-gray-600 hover:underline">
|
||||
{t("notFound.hall")}
|
||||
</Link>
|
||||
<span>|</span>
|
||||
<Link href="/results" className="hover:text-gray-600 hover:underline">
|
||||
{t("notFound.results")}
|
||||
</Link>
|
||||
<span>|</span>
|
||||
<Link href="/wallet" className="hover:text-gray-600 hover:underline">
|
||||
{t("notFound.wallet")}
|
||||
<Link
|
||||
href="/hall"
|
||||
className="mt-6 inline-flex h-11 w-full items-center justify-center gap-2 rounded-xl bg-[#e5002c] text-sm font-bold text-white shadow-[0_8px_20px_rgba(229,0,44,0.22)] hover:bg-[#d10028]"
|
||||
>
|
||||
<Home className="size-4" aria-hidden />
|
||||
{t("notFound.home")}
|
||||
</Link>
|
||||
|
||||
<div className="mt-6 flex flex-wrap items-center justify-center gap-x-3 gap-y-1 text-xs font-semibold text-[#32518d]">
|
||||
<Link href="/hall" className="hover:text-[#0b3f96] hover:underline">
|
||||
{t("notFound.hall")}
|
||||
</Link>
|
||||
<span className="text-slate-300" aria-hidden>
|
||||
|
|
||||
</span>
|
||||
<Link href="/results" className="hover:text-[#0b3f96] hover:underline">
|
||||
{t("notFound.results")}
|
||||
</Link>
|
||||
<span className="text-slate-300" aria-hidden>
|
||||
|
|
||||
</span>
|
||||
<Link href="/wallet" className="hover:text-[#0b3f96] hover:underline">
|
||||
{t("notFound.funds")}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 品牌信息 */}
|
||||
<p className="mt-8 text-sm text-gray-500">
|
||||
Lottery © {new Date().getFullYear()}
|
||||
</p>
|
||||
</div>
|
||||
<p className="mt-8 text-xs text-slate-400">
|
||||
Lottery © {new Date().getFullYear()}
|
||||
</p>
|
||||
</div>
|
||||
</PlayerMobileViewport>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user