refactor: 重构奖池配置页面,移除冗余组件,优化加载体验与国际化支持
This commit is contained in:
43
src/modules/jackpot/jackpot-config-screen.tsx
Normal file
43
src/modules/jackpot/jackpot-config-screen.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { ConfigDocPage } from "@/modules/config/config-doc-page";
|
||||
import { ConfigSection } from "@/modules/config/config-section";
|
||||
import { JackpotPoolsConsole } from "@/modules/jackpot/jackpot-pools-console";
|
||||
import { JackpotRecordsConsole } from "@/modules/jackpot/jackpot-records-console";
|
||||
|
||||
/**
|
||||
* 奖池:仅保留「侧栏 + 运营配置顶栏」两层导航;池参数与流水在同一页用分区展示。
|
||||
*/
|
||||
export function JackpotConfigScreen() {
|
||||
const { t } = useTranslation("jackpot");
|
||||
|
||||
useEffect(() => {
|
||||
const scrollToRecords = () => {
|
||||
if (window.location.hash !== "#records") {
|
||||
return;
|
||||
}
|
||||
document.getElementById("jackpot-records")?.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
};
|
||||
scrollToRecords();
|
||||
window.addEventListener("hashchange", scrollToRecords);
|
||||
return () => window.removeEventListener("hashchange", scrollToRecords);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ConfigDocPage title={t("configTitle")} description={t("pageDescription")}>
|
||||
<ConfigSection title={t("poolsSectionTitle")} description={t("poolsSectionDescription")}>
|
||||
<JackpotPoolsConsole embedded />
|
||||
</ConfigSection>
|
||||
<ConfigSection
|
||||
id="jackpot-records"
|
||||
title={t("recordsSectionTitle")}
|
||||
description={t("recordsSectionDescription")}
|
||||
>
|
||||
<JackpotRecordsConsole embedded />
|
||||
</ConfigSection>
|
||||
</ConfigDocPage>
|
||||
);
|
||||
}
|
||||
@@ -53,7 +53,12 @@ function toDraft(p: AdminJackpotPoolRow): Draft {
|
||||
};
|
||||
}
|
||||
|
||||
export function JackpotPoolsConsole() {
|
||||
type JackpotPoolsConsoleProps = {
|
||||
/** 嵌入运营配置单页时去掉外层脚手架与重复标题 */
|
||||
embedded?: boolean;
|
||||
};
|
||||
|
||||
export function JackpotPoolsConsole({ embedded = false }: JackpotPoolsConsoleProps) {
|
||||
const { t } = useTranslation(["jackpot", "common"]);
|
||||
const [items, setItems] = useState<AdminJackpotPoolRow[]>([]);
|
||||
const [drafts, setDrafts] = useState<Record<number, Draft>>({});
|
||||
@@ -146,13 +151,14 @@ export function JackpotPoolsConsole() {
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ModuleScaffold>
|
||||
<Card>
|
||||
const body = (
|
||||
<Card className={embedded ? "border-border/60 shadow-none" : undefined}>
|
||||
{!embedded ? (
|
||||
<CardHeader>
|
||||
<CardTitle className="text-base">{t("configTitle")}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-8">
|
||||
) : null}
|
||||
<CardContent className="space-y-8">
|
||||
{loading ? <p className="text-muted-foreground text-sm">{t("states.loading", { ns: "common" })}</p> : null}
|
||||
{!loading && items.length === 0 ? (
|
||||
<p className="text-muted-foreground text-sm">{t("noPoolData")}</p>
|
||||
@@ -288,8 +294,13 @@ export function JackpotPoolsConsole() {
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</ModuleScaffold>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
|
||||
if (embedded) {
|
||||
return body;
|
||||
}
|
||||
|
||||
return <ModuleScaffold>{body}</ModuleScaffold>;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,11 @@ import type {
|
||||
AdminJackpotPayoutLogsData,
|
||||
} from "@/types/api/admin-jackpot";
|
||||
|
||||
export function JackpotRecordsConsole() {
|
||||
type JackpotRecordsConsoleProps = {
|
||||
embedded?: boolean;
|
||||
};
|
||||
|
||||
export function JackpotRecordsConsole({ embedded = false }: JackpotRecordsConsoleProps) {
|
||||
const { t } = useTranslation(["jackpot", "common"]);
|
||||
const formatDt = useAdminDateTimeFormatter();
|
||||
const [drawNo, setDrawNo] = useState("");
|
||||
@@ -101,13 +105,8 @@ export function JackpotRecordsConsole() {
|
||||
return translated === key ? value : translated;
|
||||
};
|
||||
|
||||
return (
|
||||
<ModuleScaffold>
|
||||
<div className="mb-6">
|
||||
<h1 className="text-lg font-semibold tracking-tight">{t("recordsPage.title")}</h1>
|
||||
<p className="mt-1 text-sm text-muted-foreground">{t("recordsPage.description")}</p>
|
||||
</div>
|
||||
|
||||
const content = (
|
||||
<>
|
||||
<Card className="mb-6">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-base">{t("filter")}</CardTitle>
|
||||
@@ -260,6 +259,12 @@ export function JackpotRecordsConsole() {
|
||||
) : null}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</ModuleScaffold>
|
||||
</>
|
||||
);
|
||||
|
||||
if (embedded) {
|
||||
return content;
|
||||
}
|
||||
|
||||
return <ModuleScaffold>{content}</ModuleScaffold>;
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const LINKS: { href: string; label: string }[] = [
|
||||
{ href: "/admin/config/jackpot", label: "subnavPools" },
|
||||
{ href: "/admin/config/jackpot/records", label: "subnavRecords" },
|
||||
];
|
||||
|
||||
export function JackpotSubNav() {
|
||||
const { t } = useTranslation("jackpot");
|
||||
const pathname = usePathname();
|
||||
|
||||
return (
|
||||
<nav className="mb-6 flex flex-wrap gap-2 border-b border-border pb-3" aria-label={t("subnavLabel")}>
|
||||
{LINKS.map(({ href, label }) => {
|
||||
const active = pathname === href || pathname.startsWith(`${href}/`);
|
||||
return (
|
||||
<Link
|
||||
key={href}
|
||||
href={href}
|
||||
className={cn(
|
||||
"rounded-md px-3 py-1.5 text-sm transition-colors",
|
||||
active
|
||||
? "bg-primary text-primary-foreground"
|
||||
: "bg-muted/60 text-muted-foreground hover:bg-muted hover:text-foreground",
|
||||
)}
|
||||
>
|
||||
{t(label)}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
export const jackpotModuleMeta = {
|
||||
title: "奖池记录",
|
||||
title: "奖池配置",
|
||||
description: "",
|
||||
} as const;
|
||||
|
||||
Reference in New Issue
Block a user