feat(dashboard, i18n): 增强玩家身份信息展示并完善多语言支持
更新仪表盘相关组件,采用新的玩家身份信息字段(Player Identity Columns),提升数据展示的清晰度与可读性。 优化奖池记录(Jackpot Records)中的玩家信息展示方式,便于快速识别玩家身份。 改进结算明细(Settlement Details)页面的玩家身份展示,提升数据追踪与核对效率。 更新玩家注单(Player Tickets)与钱包交易(Wallet Transactions)相关界面,统一使用新的玩家身份信息展示逻辑。 在英文、尼泊尔语与中文语言包中新增玩家相关术语翻译,增强多语言支持。 提升系统整体用户体验,确保各模块中的玩家信息展示更加一致、直观。
This commit is contained in:
105
src/components/admin/admin-player-identity-columns.tsx
Normal file
105
src/components/admin/admin-player-identity-columns.tsx
Normal file
@@ -0,0 +1,105 @@
|
||||
"use client";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { TableCell, TableHead } from "@/components/ui/table";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export type AdminPlayerIdentityFields = {
|
||||
site_code?: string | null;
|
||||
site_player_id?: string | null;
|
||||
username?: string | null;
|
||||
nickname?: string | null;
|
||||
};
|
||||
|
||||
export function adminPlayerDisplayName(row: AdminPlayerIdentityFields): string {
|
||||
const nickname = row.nickname?.trim() ?? "";
|
||||
const username = row.username?.trim() ?? "";
|
||||
if (nickname !== "") {
|
||||
return nickname;
|
||||
}
|
||||
if (username !== "") {
|
||||
return username;
|
||||
}
|
||||
|
||||
return "—";
|
||||
}
|
||||
|
||||
function cellText(value: string | null | undefined): string {
|
||||
const trimmed = value?.trim() ?? "";
|
||||
return trimmed !== "" ? trimmed : "—";
|
||||
}
|
||||
|
||||
type HeadProps = { className?: string };
|
||||
type CellProps = { row: AdminPlayerIdentityFields; className?: string };
|
||||
|
||||
export function AdminPlayerSiteHead({ className }: HeadProps): React.ReactElement {
|
||||
const { t } = useTranslation("common");
|
||||
return (
|
||||
<TableHead className={cn("whitespace-nowrap", className)}>
|
||||
{t("playerColumns.site")}
|
||||
</TableHead>
|
||||
);
|
||||
}
|
||||
|
||||
export function AdminPlayerDisplayHead({ className }: HeadProps): React.ReactElement {
|
||||
const { t } = useTranslation("common");
|
||||
return (
|
||||
<TableHead className={cn("whitespace-nowrap", className)}>
|
||||
{t("playerColumns.display")}
|
||||
</TableHead>
|
||||
);
|
||||
}
|
||||
|
||||
export function AdminPlayerSiteIdHead({ className }: HeadProps): React.ReactElement {
|
||||
const { t } = useTranslation("common");
|
||||
return (
|
||||
<TableHead className={cn("whitespace-nowrap", className)}>
|
||||
{t("playerColumns.sitePlayerId")}
|
||||
</TableHead>
|
||||
);
|
||||
}
|
||||
|
||||
export function AdminPlayerIdentityHeads({ className }: { className?: string }): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<AdminPlayerSiteHead className={className} />
|
||||
<AdminPlayerDisplayHead className={className} />
|
||||
<AdminPlayerSiteIdHead className={className} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function AdminPlayerSiteCell({ row, className }: CellProps): React.ReactElement {
|
||||
return (
|
||||
<TableCell className={cn("text-xs", className)}>
|
||||
<span className="font-mono text-xs">{cellText(row.site_code)}</span>
|
||||
</TableCell>
|
||||
);
|
||||
}
|
||||
|
||||
export function AdminPlayerDisplayCell({ row, className }: CellProps): React.ReactElement {
|
||||
return (
|
||||
<TableCell className={cn("text-xs", className)}>
|
||||
{adminPlayerDisplayName(row)}
|
||||
</TableCell>
|
||||
);
|
||||
}
|
||||
|
||||
export function AdminPlayerSiteIdCell({ row, className }: CellProps): React.ReactElement {
|
||||
return (
|
||||
<TableCell className={cn("text-xs", className)}>
|
||||
<span className="font-mono text-xs">{cellText(row.site_player_id)}</span>
|
||||
</TableCell>
|
||||
);
|
||||
}
|
||||
|
||||
export function AdminPlayerIdentityCells({ row, className }: CellProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<AdminPlayerSiteCell row={row} className={className} />
|
||||
<AdminPlayerDisplayCell row={row} className={className} />
|
||||
<AdminPlayerSiteIdCell row={row} className={className} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user