"use client"; import type { TFunction } from "i18next"; import { AlertCircle, AlertTriangle, CheckCircle2, Globe, Loader2, RefreshCw, ShieldCheck, } from "lucide-react"; import Image from "next/image"; import { useTranslation } from "react-i18next"; import { LanguageSwitcher } from "@/components/language-switcher"; import { Button, buttonVariants } from "@/components/ui/button"; import { cn } from "@/lib/utils"; export type DesktopEntryStepStatus = "pending" | "in-progress" | "done" | "error"; type DesktopEntryStep = { id: "token" | "account" | "hall"; status: DesktopEntryStepStatus; }; type DesktopFailureRow = { code?: string; detailKey?: string; fallbackMessage?: string; }; type PlayerEntryDesktopProps = { phase: "loading" | "success" | "failed"; waitingForToken: boolean; progress: number; steps: DesktopEntryStep[]; failureDetails: DesktopFailureRow[]; t: TFunction<"entry">; tc: TFunction<"common">; mainSiteUrl: string; onRetry: () => void; }; /** PC Token 入场校验,视觉与账号密码登录保持一致。 */ export function PlayerEntryDesktop({ phase, waitingForToken, progress, steps, failureDetails, t, tc, mainSiteUrl, onRetry, }: PlayerEntryDesktopProps) { const isLoading = phase === "loading" || waitingForToken; return (
{t("header.backgroundAlt")}
{isLoading ? ( ) : null} {phase === "failed" ? ( ) : null}
{t("footer.secure")}
); } function EntryProgress({ progress, steps, t, }: Pick) { return ( <>

{t("loading.title")}

{t("loading.progress")}

{t("loading.progress")} {progress}%
{steps.map((step) => (
{t(`steps.${step.id}.title`)}

{t(`steps.${step.id}.description`)}

))}
); } function EntryFailure({ details, mainSiteUrl, onRetry, t, tc, }: Pick & { details: DesktopFailureRow[]; }) { return (

{t("failure.title")}

{t("failure.subtitle")}

{details.length > 0 ? (
{t("failure.detailsTitle")}
{details.map((detail, index) => (
{index + 1} {detail.code ?? tc("errors.general")} {detail.detailKey ? t(detail.detailKey) : (detail.fallbackMessage ?? t("errors.unknown"))}
))}
) : null}
{mainSiteUrl ? ( {t("failure.backToMainSite")} ) : null}
); } function StepIcon({ status }: { status: DesktopEntryStepStatus }) { const className = cn( "flex size-8 shrink-0 items-center justify-center rounded-full border-2", status === "done" && "border-emerald-500 bg-emerald-500 text-white", status === "in-progress" && "border-blue-600 bg-blue-600 text-white", status === "pending" && "border-slate-200 bg-slate-50 text-slate-400", status === "error" && "border-red-500 bg-red-500 text-white", ); return (
{status === "done" ? : null} {status === "in-progress" ? : null} {status === "pending" ?
: null} {status === "error" ? : null}
); } function StepBadge({ status }: { status: DesktopEntryStepStatus }) { const { t } = useTranslation("common"); const className = cn( "shrink-0 rounded px-2 py-0.5 text-xs font-medium", status === "done" && "bg-emerald-50 text-emerald-700", status === "in-progress" && "bg-blue-50 text-blue-700", status === "pending" && "bg-slate-100 text-slate-500", status === "error" && "bg-red-50 text-red-700", ); const label = { done: t("status.done"), "in-progress": t("status.inProgress"), pending: t("status.pending"), error: t("status.failed"), }[status]; return {label}; }