feat(api, i18n): add agent_node_id to various admin queries and enhance multi-language support

Introduced the agent_node_id field in AdminDrawListQuery, AdminPlayerListQuery, AdminSettlementBatchListQuery, TicketItemsListQuery, and TransferOrderListQuery to improve filtering capabilities. Updated the admin-breadcrumb and admin-sidebar components to include new translations for agent-related terms in English, Nepali, and Chinese, enhancing the overall user experience and multi-language support across the admin interface.
This commit is contained in:
2026-06-02 14:37:08 +08:00
parent a4e7a2d228
commit b15e377187
105 changed files with 5305 additions and 1596 deletions

View File

@@ -0,0 +1,92 @@
"use client";
import {
createContext,
useCallback,
useContext,
useEffect,
useMemo,
useRef,
useState,
type ReactNode,
} from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { getAdminSettings } from "@/api/admin-settings";
/** 系统设置页一次拉取的分组(避免各卡片重复 GET */
export const SYSTEM_SETTINGS_GROUPS = ["draw", "settlement", "frontend", "wallet"] as const;
function mergeItemsToKv(
items: { key: string; value: unknown }[],
into: Record<string, unknown>,
): void {
for (const item of items) {
into[item.key] = item.value;
}
}
type AdminSettingsDataContextValue = {
kv: Record<string, unknown> | null;
loading: boolean;
reload: () => Promise<void>;
patchKv: (updates: Record<string, unknown>) => void;
};
const AdminSettingsDataContext = createContext<AdminSettingsDataContextValue | null>(null);
export function AdminSettingsDataProvider({ children }: { children: ReactNode }) {
const { t } = useTranslation(["config"]);
const [kv, setKv] = useState<Record<string, unknown> | null>(null);
const [loading, setLoading] = useState(true);
const tRef = useRef(t);
tRef.current = t;
const reload = useCallback(async () => {
setLoading(true);
try {
const responses = await Promise.all(
SYSTEM_SETTINGS_GROUPS.map((group) => getAdminSettings(group)),
);
const merged: Record<string, unknown> = {};
for (const res of responses) {
mergeItemsToKv(res.items, merged);
}
setKv(merged);
} catch {
toast.error(tRef.current("system.loadFailed", { ns: "config" }));
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
void reload();
}, [reload]);
const patchKv = useCallback((updates: Record<string, unknown>) => {
setKv((prev) => (prev === null ? { ...updates } : { ...prev, ...updates }));
}, []);
const value = useMemo(
() => ({ kv, loading, reload, patchKv }),
[kv, loading, reload, patchKv],
);
return (
<AdminSettingsDataContext.Provider value={value}>{children}</AdminSettingsDataContext.Provider>
);
}
export function useAdminSettingsData(): AdminSettingsDataContextValue {
const ctx = useContext(AdminSettingsDataContext);
if (ctx === null) {
throw new Error("useAdminSettingsData must be used within AdminSettingsDataProvider");
}
return ctx;
}
export function useOptionalAdminSettingsData(): AdminSettingsDataContextValue | null {
return useContext(AdminSettingsDataContext);
}