feat(agents, i18n): enhance agent management and settlement features with new translations and UI updates

Added new translations for agent management and settlement features in English, Nepali, and Chinese, improving multi-language support. Updated the agents console to reflect changes in funding modes and player details, enhancing user experience. Refactored the admin permission gate to include new logic for handling bound line agents, ensuring better permission management. Additionally, streamlined the UI for agent-related pages and improved navigation to the settlement center, consolidating related functionalities for better accessibility.
This commit is contained in:
2026-06-04 18:01:05 +08:00
parent c2eac2fafc
commit 65eaeecf8c
139 changed files with 8852 additions and 1435 deletions

View File

@@ -28,6 +28,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { AdminTableNoResourceRow } from "@/components/admin/admin-no-resource-state";
import { AdminLoadingState, AdminLoadingInline, AdminTableLoadingRow } from "@/components/admin/admin-loading-state";
import {
Select,
@@ -51,7 +52,9 @@ import { useAdminCurrencyCatalog } from "@/hooks/use-admin-currency-catalog";
import { useAdminDateTimeFormatter } from "@/hooks/use-admin-datetime-formatter";
import { useConfirmAction } from "@/hooks/use-confirm-action";
import { useExportLabels } from "@/hooks/use-export-labels";
import { PlayerLedgerSourceBadge } from "@/components/admin/player-funding-badges";
import { formatAdminMinorUnits } from "@/lib/money";
import { creditLedgerReasonLabel } from "@/modules/settlement/settlement-status-label";
import { cn } from "@/lib/utils";
import { LotteryApiBizError } from "@/types/api/errors";
import type {
@@ -560,11 +563,7 @@ export function TransferOrdersPanel(): React.ReactElement {
{loading && !data ? (
<AdminTableLoadingRow colSpan={13} />
) : !data || data.items.length === 0 ? (
<TableRow>
<TableCell colSpan={13} className="text-muted-foreground">
{t("states.noData", { ns: "common" })}
</TableCell>
</TableRow>
<AdminTableNoResourceRow colSpan={13} />
) : (
data.items.map((row) => (
<TableRow key={row.id}>
@@ -637,6 +636,7 @@ export function TransferOrdersPanel(): React.ReactElement {
export function WalletTxnsPanel(): React.ReactElement {
const { t } = useTranslation(["wallet", "common"]);
const { t: tSettlement } = useTranslation("settlementCenter");
const tRef = useTranslationRef(["wallet", "common"]);
const exportLabels = useExportLabels("walletTransactions");
const formatTs = useAdminDateTimeFormatter();
@@ -863,6 +863,7 @@ export function WalletTxnsPanel(): React.ReactElement {
<TableHead className="min-w-0 max-w-[12rem]">{t("externalRefNo")}</TableHead>
<AdminAgentIdentityHeads />
<AdminPlayerIdentityHeads />
<TableHead className="whitespace-nowrap">{t("ledgerChannel", { defaultValue: "账本" })}</TableHead>
<TableHead className="whitespace-nowrap">{t("type")}</TableHead>
<TableHead className="whitespace-nowrap">{t("amount")}</TableHead>
<TableHead className="whitespace-nowrap">{t("status")}</TableHead>
@@ -872,13 +873,9 @@ export function WalletTxnsPanel(): React.ReactElement {
</TableHeader>
<TableBody>
{loading && !data ? (
<AdminTableLoadingRow colSpan={11} />
<AdminTableLoadingRow colSpan={12} />
) : !data || data.items.length === 0 ? (
<TableRow>
<TableCell colSpan={11} className="text-muted-foreground">
{t("states.noData", { ns: "common" })}
</TableCell>
</TableRow>
<AdminTableNoResourceRow colSpan={12} />
) : (
data.items.map((row) => (
<TableRow key={row.id}>
@@ -890,7 +887,14 @@ export function WalletTxnsPanel(): React.ReactElement {
</TableCell>
<AdminAgentIdentityCells row={row} />
<AdminPlayerIdentityCells row={row} />
<TableCell className="min-w-0 text-xs">{row.biz_type}</TableCell>
<TableCell>
<PlayerLedgerSourceBadge ledgerSource={row.ledger_source} />
</TableCell>
<TableCell className="min-w-0 text-xs">
{row.ledger_source === "credit_ledger"
? creditLedgerReasonLabel(row.biz_type, tSettlement)
: row.biz_type}
</TableCell>
<TableCell className="tabular-nums text-xs">
{row.amount} ({row.direction === 1 ? t("in") : t("out")})
</TableCell>
@@ -1006,11 +1010,7 @@ export function PlayerWalletPanel(): React.ReactElement {
</TableHeader>
<TableBody>
{result.wallets.length === 0 ? (
<TableRow>
<TableCell colSpan={4} className="text-muted-foreground">
{t("noWalletRows")}
</TableCell>
</TableRow>
<AdminTableNoResourceRow colSpan={4} />
) : (
result.wallets.map((w) => (
<TableRow key={w.id}>

View File

@@ -0,0 +1,36 @@
"use client";
import Link from "next/link";
import { useTranslation } from "react-i18next";
import { adminHasAnyPermission } from "@/lib/admin-permissions";
import { PRD_SETTLEMENT_AGENT_ACCESS_ANY } from "@/lib/admin-prd";
import { useAdminProfile } from "@/stores/admin-session";
/** 钱包模块仅服务主站钱包玩家;信用盘流水在结算中心。 */
export function WalletScopeHint(): React.ReactElement {
const { t } = useTranslation("wallet");
const profile = useAdminProfile();
const canSettlement = adminHasAnyPermission(profile?.permissions, [
...PRD_SETTLEMENT_AGENT_ACCESS_ANY,
]);
return (
<p className="text-sm text-muted-foreground">
{t("scopeHint", {
defaultValue:
"本模块为主站钱包模式:钱包流水与主站转账单。信用盘玩家的下注占用、结算记账请查看",
})}
{canSettlement ? (
<Link href="/admin/settlement-center" className="mx-1 text-primary underline">
{t("scopeHintSettlementLink", { defaultValue: "结算中心 → 信用流水" })}
</Link>
) : (
<span className="mx-1 font-medium text-foreground">
{t("scopeHintSettlement", { defaultValue: "结算中心 → 信用流水" })}
</span>
)}
</p>
);
}