feat(admin, i18n): enhance admin dashboard and user management with new features and translations

Added the ability to filter admin dashboard data by site code and agent node ID, improving data retrieval capabilities. Introduced new functions for fetching dashboard data based on these parameters. Updated the admin users and roles management components to reflect these changes. Enhanced multi-language support by adding new translations for agent management and permission levels in English, Nepali, and Chinese, ensuring a consistent user experience across the admin interface.
This commit is contained in:
2026-06-03 10:07:51 +08:00
parent b15e377187
commit ce27a3ec8a
66 changed files with 1361 additions and 720 deletions

View File

@@ -467,11 +467,13 @@ export function DashboardAgentRankingCard({
export function DashboardAnalyticsPanel({
enabled,
playOptions,
scope,
}: {
enabled: boolean;
playOptions: { code: string; label: string }[];
scope: { siteCode: string; agentNodeId: number | undefined };
}): ReactNode {
const analytics = useDashboardAnalytics({ enabled, playOptions });
const analytics = useDashboardAnalytics({ enabled, playOptions, scope });
return (
<section className="space-y-4">
<DashboardAnalyticsMain analytics={analytics} />

View File

@@ -18,7 +18,7 @@ import {
Scale,
} from "lucide-react";
import { getAdminDashboard } from "@/api/admin-dashboard";
import { getAdminDashboardByScope } from "@/api/admin-dashboard";
import { useAdminPlayTypeCatalog } from "@/hooks/use-admin-play-type-catalog";
import { useCachedPlayTypeOptions } from "@/hooks/use-cached-play-type-options";
import { useAsyncEffect } from "@/hooks/use-async-effect";
@@ -188,7 +188,7 @@ export function DashboardConsole(): ReactElement {
setAbnormalTransferTotal(null);
try {
const d = await getAdminDashboard();
const d = await getAdminDashboardByScope({});
setHall(d.hall);
if (d.resolved_draw != null) {
@@ -242,7 +242,11 @@ export function DashboardConsole(): ReactElement {
const pendingReviewTotal = resultBatchQueue?.pending_review_total ?? 0;
const analytics = useDashboardAnalytics({ enabled: canFinance, playOptions });
const analytics = useDashboardAnalytics({
enabled: canFinance,
playOptions,
scope: { siteCode: "", agentNodeId: undefined },
});
const showAnalytics = canFinance;
const quickLinks: { href: string; label: string; icon: ReactNode }[] = [

View File

@@ -1088,7 +1088,7 @@ export function PlatformLifetimePayoutSnapshot({
const bet = coerceAdminMinor(finance.total_bet_minor);
const payout = coerceAdminMinor(finance.total_payout_minor);
let win = coerceAdminMinor(finance.total_win_minor);
let jackpot = coerceAdminMinor(finance.total_jackpot_minor);
const jackpot = coerceAdminMinor(finance.total_jackpot_minor);
if (payout > 0 && win + jackpot === 0) {
win = payout;
}

View File

@@ -61,9 +61,11 @@ export function formatDashboardSignedMoneyMinor(minor: number, currencyCode: str
export function useDashboardAnalytics({
enabled,
playOptions,
scope,
}: {
enabled: boolean;
playOptions: { code: string; label: string }[];
scope: { siteCode: string; agentNodeId: number | undefined };
}) {
const { t } = useTranslation(["dashboard", "common"]);
const tRef = useTranslationRef(["dashboard", "common"]);
@@ -94,6 +96,8 @@ export function useDashboardAnalytics({
period,
metric: "overview",
play_code: playCode !== "" ? playCode : undefined,
site_code: scope.siteCode || undefined,
agent_node_id: scope.agentNodeId,
...(period === "custom" ? { date_from: customFrom, date_to: customTo } : {}),
});
setData(payload);
@@ -110,11 +114,11 @@ export function useDashboardAnalytics({
} finally {
setLoading(false);
}
}, [enabled, period, playCode, customFrom, customTo]);
}, [enabled, period, playCode, customFrom, customTo, scope.agentNodeId, scope.siteCode]);
useAsyncEffect(() => {
void load();
}, [enabled, period, playCode, customFrom, customTo]);
}, [enabled, period, playCode, customFrom, customTo, scope.agentNodeId, scope.siteCode]);
const currency = data?.currency_code ?? null;
const summary = data?.summary;