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:
99
src/modules/settings/hooks/use-settings-section.ts
Normal file
99
src/modules/settings/hooks/use-settings-section.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import { updateAdminSettingsBatch, type AdminSettingBatchItem } from "@/api/admin-settings";
|
||||
import { setCachedApplyRebateToPayoutSetting } from "@/lib/admin-settlement-settings-cache";
|
||||
import { useAdminSettingsData } from "@/modules/settings/admin-settings-data-context";
|
||||
import { SETTLEMENT_KEYS } from "@/modules/settings/settings-keys";
|
||||
import { LotteryApiBizError } from "@/types/api/errors";
|
||||
|
||||
export function useSettingsSection<TDraft>(options: {
|
||||
initialDraft: TDraft;
|
||||
fromKv: (kv: Record<string, unknown>) => TDraft;
|
||||
buildDirtyItems: (draft: TDraft, saved: TDraft) => AdminSettingBatchItem[];
|
||||
saveSuccessKey: string;
|
||||
saveFailedKey: string;
|
||||
}) {
|
||||
const { t } = useTranslation(["config"]);
|
||||
const tRef = useRef(t);
|
||||
tRef.current = t;
|
||||
|
||||
const { kv, loading, patchKv } = useAdminSettingsData();
|
||||
const [draft, setDraft] = useState(options.initialDraft);
|
||||
const [saved, setSaved] = useState(options.initialDraft);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const hydratedRef = useRef(false);
|
||||
|
||||
const { fromKv, buildDirtyItems, saveSuccessKey, saveFailedKey } = options;
|
||||
|
||||
const dirty = useMemo(
|
||||
() => buildDirtyItems(draft, saved).length > 0,
|
||||
[draft, saved, buildDirtyItems],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (kv === null) {
|
||||
return;
|
||||
}
|
||||
const next = fromKv(kv);
|
||||
setDraft(next);
|
||||
setSaved(next);
|
||||
hydratedRef.current = true;
|
||||
}, [kv, fromKv]);
|
||||
|
||||
const updateField = <K extends keyof TDraft>(field: K, value: TDraft[K]) => {
|
||||
setDraft((prev) => ({ ...prev, [field]: value }));
|
||||
};
|
||||
|
||||
const discard = () => {
|
||||
setDraft(saved);
|
||||
};
|
||||
|
||||
const save = async (): Promise<boolean> => {
|
||||
const items = buildDirtyItems(draft, saved);
|
||||
if (items.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
setSaving(true);
|
||||
try {
|
||||
await updateAdminSettingsBatch(items);
|
||||
const updates: Record<string, unknown> = {};
|
||||
for (const item of items) {
|
||||
updates[item.key] = item.value;
|
||||
if (item.key === SETTLEMENT_KEYS.APPLY_REBATE_TO_PAYOUT) {
|
||||
setCachedApplyRebateToPayoutSetting(Boolean(item.value));
|
||||
}
|
||||
}
|
||||
patchKv(updates);
|
||||
setSaved(draft);
|
||||
toast.success(tRef.current(saveSuccessKey, { ns: "config" }));
|
||||
return true;
|
||||
} catch (error) {
|
||||
toast.error(
|
||||
error instanceof LotteryApiBizError
|
||||
? error.message
|
||||
: tRef.current(saveFailedKey, { ns: "config" }),
|
||||
);
|
||||
return false;
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
const sectionLoading = loading || (kv !== null && !hydratedRef.current);
|
||||
|
||||
return {
|
||||
draft,
|
||||
saved,
|
||||
loading: sectionLoading,
|
||||
saving,
|
||||
dirty,
|
||||
updateField,
|
||||
discard,
|
||||
save,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user