feat(admin, players): enhance player management and admin interfaces
Some checks failed
lotteryadmin CI / build (push) Has been cancelled
Some checks failed
lotteryadmin CI / build (push) Has been cancelled
Updated the player management components to improve error handling and display for various operations, including ticket loading and transaction retrieval. Introduced new status badges for better visual representation of player statuses. Enhanced localization support for error messages and improved the overall user experience in the admin console. Refactored components for better maintainability and clarity.
This commit is contained in:
@@ -127,6 +127,7 @@ export function AgentsConsole(): React.ReactElement {
|
||||
const [profileSaving, setProfileSaving] = useState(false);
|
||||
const [selectedProfile, setSelectedProfile] = useState<AgentProfileRow | null>(null);
|
||||
const [selectedProfileLoading, setSelectedProfileLoading] = useState(false);
|
||||
const [selectedProfileErr, setSelectedProfileErr] = useState<string | null>(null);
|
||||
const [playerCreateRequestKey, setPlayerCreateRequestKey] = useState(0);
|
||||
const [nodeDialogOpen, setNodeDialogOpen] = useState(false);
|
||||
const [nodeDialogMode, setNodeDialogMode] = useState<"create" | "edit">("create");
|
||||
@@ -450,12 +451,14 @@ export function AgentsConsole(): React.ReactElement {
|
||||
if (selectedNode === null) {
|
||||
setSelectedProfile(null);
|
||||
setSelectedProfileLoading(false);
|
||||
setSelectedProfileErr(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const nodeId = selectedNode.id;
|
||||
let cancelled = false;
|
||||
setSelectedProfileLoading(true);
|
||||
setSelectedProfileErr(null);
|
||||
|
||||
void getAgentNodeProfile(nodeId)
|
||||
.then((row) => {
|
||||
@@ -470,6 +473,9 @@ export function AgentsConsole(): React.ReactElement {
|
||||
.catch(() => {
|
||||
if (!cancelled) {
|
||||
setSelectedProfile(null);
|
||||
setSelectedProfileErr(
|
||||
t("profile.loadFailed", { defaultValue: "代理档案加载失败,请稍后重试。" }),
|
||||
);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -1024,6 +1030,10 @@ export function AgentsConsole(): React.ReactElement {
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{selectedProfileErr ? (
|
||||
<p className="border-b border-border/70 px-4 py-2 text-sm text-destructive">{selectedProfileErr}</p>
|
||||
) : null}
|
||||
|
||||
<AgentLineDetailPanel
|
||||
node={selectedNode}
|
||||
profile={selectedProfile}
|
||||
|
||||
@@ -69,7 +69,7 @@ import { adminHasAnyPermission } from "@/lib/admin-permissions";
|
||||
import { PRD_SETTLEMENT_AGENT_MANAGE, PRD_USERS_MANAGE } from "@/lib/admin-prd";
|
||||
import { isSiteAdminOperator } from "@/lib/admin-session-variants";
|
||||
import { settlementBillOperableByBoundAgent } from "@/modules/settlement/settlement-bill-operable";
|
||||
import { resolveRoleStatusTone } from "@/lib/admin-status-tone";
|
||||
import { resolvePlayerStatusTone } from "@/lib/admin-status-tone";
|
||||
import { useAdminProfile } from "@/stores/admin-session";
|
||||
import { LotteryApiBizError } from "@/types/api/errors";
|
||||
import type { AdminPlayerRow } from "@/types/api/admin-player";
|
||||
@@ -201,6 +201,7 @@ export function AgentsPlayersPanel({
|
||||
const [total, setTotal] = useState(0);
|
||||
const [lastPage, setLastPage] = useState(1);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [listErr, setListErr] = useState<string | null>(null);
|
||||
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [saving, setSaving] = useState(false);
|
||||
@@ -252,6 +253,7 @@ export function AgentsPlayersPanel({
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
setListErr(null);
|
||||
try {
|
||||
const data = await getAdminPlayers({
|
||||
page,
|
||||
@@ -262,10 +264,11 @@ export function AgentsPlayersPanel({
|
||||
setItems(data.items);
|
||||
setTotal(data.meta.total);
|
||||
setLastPage(Math.max(1, data.meta.last_page));
|
||||
} catch {
|
||||
} catch (e) {
|
||||
setItems([]);
|
||||
setTotal(0);
|
||||
setLastPage(1);
|
||||
setListErr(e instanceof LotteryApiBizError ? e.message : t("common:loadFailed"));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -819,6 +822,9 @@ export function AgentsPlayersPanel({
|
||||
<AdminLoadingState minHeight="6rem" />
|
||||
) : (
|
||||
<>
|
||||
{listErr ? (
|
||||
<p className="mb-3 text-sm text-destructive">{listErr}</p>
|
||||
) : null}
|
||||
<div className="admin-table-shell overflow-hidden rounded-2xl border border-border/70 bg-card shadow-sm">
|
||||
<div className="overflow-x-auto">
|
||||
<Table>
|
||||
@@ -910,7 +916,7 @@ export function AgentsPlayersPanel({
|
||||
</TableCell>
|
||||
{!embedded ? (
|
||||
<TableCell>
|
||||
<AdminStatusBadge tone={resolveRoleStatusTone(row.status)}>
|
||||
<AdminStatusBadge status={row.status} tone={resolvePlayerStatusTone(row.status)}>
|
||||
{playerStatusLabel(row.status, t)}
|
||||
</AdminStatusBadge>
|
||||
</TableCell>
|
||||
|
||||
Reference in New Issue
Block a user