feat(admin, i18n): enhance reports, draws, config, and player workflows
This commit is contained in:
@@ -1,151 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { AdminPageCard } from "@/components/admin/admin-page-card";
|
||||
import { useConfirmAction } from "@/hooks/use-confirm-action";
|
||||
import { SettingsSectionActions } from "@/modules/settings/components/settings-section-actions";
|
||||
import { useSettingsSection } from "@/modules/settings/hooks/use-settings-section";
|
||||
import { DRAW_KEYS } from "@/modules/settings/settings-keys";
|
||||
import type { AdminSettingBatchItem } from "@/api/admin-settings";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
|
||||
interface CurrencyFormatDraft {
|
||||
currencyDisplayDecimals: string;
|
||||
currencyDecimalSeparator: string;
|
||||
currencyThousandsSeparator: string;
|
||||
}
|
||||
|
||||
const INITIAL: CurrencyFormatDraft = {
|
||||
currencyDisplayDecimals: "2",
|
||||
currencyDecimalSeparator: ".",
|
||||
currencyThousandsSeparator: ",",
|
||||
};
|
||||
|
||||
function fromKv(kv: Record<string, unknown>): CurrencyFormatDraft {
|
||||
return {
|
||||
currencyDisplayDecimals: String(kv[DRAW_KEYS.CURRENCY_DISPLAY_DECIMALS] ?? 2),
|
||||
currencyDecimalSeparator: String(kv[DRAW_KEYS.CURRENCY_DECIMAL_SEPARATOR] ?? "."),
|
||||
currencyThousandsSeparator: String(kv[DRAW_KEYS.CURRENCY_THOUSANDS_SEPARATOR] ?? ","),
|
||||
};
|
||||
}
|
||||
|
||||
function buildDirtyItems(draft: CurrencyFormatDraft, saved: CurrencyFormatDraft): AdminSettingBatchItem[] {
|
||||
const items: AdminSettingBatchItem[] = [];
|
||||
if (draft.currencyDisplayDecimals !== saved.currencyDisplayDecimals) {
|
||||
items.push({
|
||||
key: DRAW_KEYS.CURRENCY_DISPLAY_DECIMALS,
|
||||
value: Math.max(
|
||||
0,
|
||||
Math.min(12, Number.parseInt(draft.currencyDisplayDecimals || "2", 10) || 2),
|
||||
),
|
||||
});
|
||||
}
|
||||
if (draft.currencyDecimalSeparator !== saved.currencyDecimalSeparator) {
|
||||
items.push({
|
||||
key: DRAW_KEYS.CURRENCY_DECIMAL_SEPARATOR,
|
||||
value: (draft.currencyDecimalSeparator || ".").slice(0, 1),
|
||||
});
|
||||
}
|
||||
if (draft.currencyThousandsSeparator !== saved.currencyThousandsSeparator) {
|
||||
items.push({
|
||||
key: DRAW_KEYS.CURRENCY_THOUSANDS_SEPARATOR,
|
||||
value: (draft.currencyThousandsSeparator || ",").slice(0, 1),
|
||||
});
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
export function CurrencyFormatSettingsPanel() {
|
||||
const { t } = useTranslation(["config", "adminUsers", "common"]);
|
||||
const { request: requestConfirm, ConfirmDialog } = useConfirmAction();
|
||||
const buildItems = useCallback(buildDirtyItems, []);
|
||||
const section = useSettingsSection({
|
||||
initialDraft: INITIAL,
|
||||
fromKv,
|
||||
buildDirtyItems: buildItems,
|
||||
saveSuccessKey: "system.saveCurrencyFormatSuccess",
|
||||
saveFailedKey: "system.saveFailed",
|
||||
});
|
||||
|
||||
const { draft, loading, saving, dirty, updateField, discard, save } = section;
|
||||
|
||||
return (
|
||||
<>
|
||||
<AdminPageCard
|
||||
title={t("system.sections.currencyFormat", { ns: "config" })}
|
||||
description={t("system.sections.currencyFormatDescription", { ns: "config" })}
|
||||
>
|
||||
<div className="space-y-5">
|
||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="currency-display-decimals" className="text-sm font-medium">
|
||||
{t("system.fields.currencyDisplayDecimals", { ns: "config" })}
|
||||
</Label>
|
||||
<Input
|
||||
id="currency-display-decimals"
|
||||
type="number"
|
||||
min="0"
|
||||
max="12"
|
||||
step="1"
|
||||
value={draft.currencyDisplayDecimals}
|
||||
placeholder={t("system.placeholders.currencyDisplayDecimals", { ns: "config" })}
|
||||
onChange={(e) => updateField("currencyDisplayDecimals", e.target.value)}
|
||||
disabled={loading || saving}
|
||||
/>
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="currency-decimal-separator" className="text-sm font-medium">
|
||||
{t("system.fields.currencyDecimalSeparator", { ns: "config" })}
|
||||
</Label>
|
||||
<Input
|
||||
id="currency-decimal-separator"
|
||||
value={draft.currencyDecimalSeparator}
|
||||
placeholder={t("system.placeholders.currencyDecimalSeparator", { ns: "config" })}
|
||||
onChange={(e) => updateField("currencyDecimalSeparator", e.target.value)}
|
||||
disabled={loading || saving}
|
||||
maxLength={1}
|
||||
/>
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="currency-thousands-separator" className="text-sm font-medium">
|
||||
{t("system.fields.currencyThousandsSeparator", { ns: "config" })}
|
||||
</Label>
|
||||
<Input
|
||||
id="currency-thousands-separator"
|
||||
value={draft.currencyThousandsSeparator}
|
||||
placeholder={t("system.placeholders.currencyThousandsSeparator", { ns: "config" })}
|
||||
onChange={(e) => updateField("currencyThousandsSeparator", e.target.value)}
|
||||
disabled={loading || saving}
|
||||
maxLength={1}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SettingsSectionActions
|
||||
dirty={dirty}
|
||||
loading={loading}
|
||||
saving={saving}
|
||||
onSave={() =>
|
||||
requestConfirm({
|
||||
title: t("system.confirmSaveCurrencyFormatTitle", { ns: "config" }),
|
||||
description: t("system.confirmSaveCurrencyFormatDescription", { ns: "config" }),
|
||||
confirmLabel: t("confirm.confirmSave", { ns: "common" }),
|
||||
onConfirm: () => {
|
||||
void save();
|
||||
},
|
||||
})
|
||||
}
|
||||
onDiscard={discard}
|
||||
saveLabel={t("actions.save", { ns: "adminUsers" })}
|
||||
savingLabel={t("saving", { ns: "adminUsers" })}
|
||||
discardLabel={t("system.discard", { ns: "config" })}
|
||||
/>
|
||||
</div>
|
||||
</AdminPageCard>
|
||||
<ConfirmDialog />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -11,9 +11,6 @@ export const DRAW_KEYS = {
|
||||
DRAW_BUFFER_DRAWS_AHEAD: "draw.buffer_draws_ahead",
|
||||
REQUIRE_MANUAL_REVIEW: "draw.require_manual_review",
|
||||
COOLDOWN_MINUTES: "draw.cooldown_minutes",
|
||||
CURRENCY_DISPLAY_DECIMALS: "currency.display_decimals",
|
||||
CURRENCY_DECIMAL_SEPARATOR: "currency.decimal_separator",
|
||||
CURRENCY_THOUSANDS_SEPARATOR: "currency.thousands_separator",
|
||||
} as const;
|
||||
|
||||
export const SETTLEMENT_KEYS = {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import { WalletConfigDocScreen } from "@/modules/config/doc/wallet-config-doc-screen";
|
||||
import { AdminPageCard } from "@/components/admin/admin-page-card";
|
||||
import { AdminSettingsDataProvider } from "@/modules/settings/admin-settings-data-context";
|
||||
import { CurrencyFormatSettingsPanel } from "@/modules/settings/panels/currency-format-settings-panel";
|
||||
import { DrawSettingsPanel } from "@/modules/settings/panels/draw-settings-panel";
|
||||
import { FrontendSettingsPanel } from "@/modules/settings/panels/frontend-settings-panel";
|
||||
import { SettlementSettingsPanel } from "@/modules/settings/panels/settlement-settings-panel";
|
||||
@@ -15,7 +14,6 @@ function SystemSettingsContent() {
|
||||
return (
|
||||
<div className="flex w-full max-w-none flex-col gap-6">
|
||||
<DrawSettingsPanel />
|
||||
<CurrencyFormatSettingsPanel />
|
||||
<SettlementSettingsPanel />
|
||||
|
||||
<AdminPageCard
|
||||
|
||||
Reference in New Issue
Block a user