feat: 增加管理端多语言与多模块界面国际化支持
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import {
|
||||
@@ -42,6 +43,7 @@ interface Draft {
|
||||
}
|
||||
|
||||
export function WalletConfigDocScreen() {
|
||||
const { t } = useTranslation(["config", "adminUsers"]);
|
||||
const [draft, setDraft] = useState<Draft>({
|
||||
inMin: "",
|
||||
inMax: "",
|
||||
@@ -71,11 +73,11 @@ export function WalletConfigDocScreen() {
|
||||
setSaved(d);
|
||||
setDirty(false);
|
||||
} catch {
|
||||
toast.error("加载失败");
|
||||
toast.error(t("wallet.loadFailed", { ns: "config" }));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, []);
|
||||
}, [t]);
|
||||
|
||||
useEffect(() => {
|
||||
queueMicrotask(() => {
|
||||
@@ -95,11 +97,13 @@ export function WalletConfigDocScreen() {
|
||||
await updateAdminSetting(KEYS.IN_MAX, displayToMinorUnits(draft.inMax));
|
||||
await updateAdminSetting(KEYS.OUT_MIN, displayToMinorUnits(draft.outMin));
|
||||
await updateAdminSetting(KEYS.OUT_MAX, displayToMinorUnits(draft.outMax));
|
||||
toast.success("保存成功");
|
||||
toast.success(t("wallet.saveSuccess", { ns: "config" }));
|
||||
setSaved(draft);
|
||||
setDirty(false);
|
||||
} catch (error) {
|
||||
toast.error(error instanceof LotteryApiBizError ? error.message : "保存失败");
|
||||
toast.error(
|
||||
error instanceof LotteryApiBizError ? error.message : t("wallet.saveFailed", { ns: "config" }),
|
||||
);
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
@@ -108,81 +112,81 @@ export function WalletConfigDocScreen() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>钱包转账限额配置</CardTitle>
|
||||
<CardTitle>{t("wallet.title", { ns: "config" })}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
金额单位为游戏币种最小单位(如 NPR 下 100 = 1.00 NPR)。最小金额至少为 1 最小单位。
|
||||
{t("wallet.description", { ns: "config" })}
|
||||
</p>
|
||||
<div className="grid gap-6 sm:grid-cols-2">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="in-min">转入最小金额</Label>
|
||||
<Label htmlFor="in-min">{t("wallet.fields.inMin", { ns: "config" })}</Label>
|
||||
<Input
|
||||
id="in-min"
|
||||
type="number"
|
||||
min="0"
|
||||
step="0.01"
|
||||
placeholder="例如 1.00"
|
||||
placeholder={t("wallet.placeholders.min", { ns: "config" })}
|
||||
value={draft.inMin}
|
||||
onChange={(e) => handleChange("inMin", e.target.value)}
|
||||
disabled={loading || saving}
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
主站钱包转入彩票钱包的单笔下限
|
||||
{t("wallet.hints.inMin", { ns: "config" })}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="in-max">转入最大金额</Label>
|
||||
<Label htmlFor="in-max">{t("wallet.fields.inMax", { ns: "config" })}</Label>
|
||||
<Input
|
||||
id="in-max"
|
||||
type="number"
|
||||
min="0"
|
||||
step="0.01"
|
||||
placeholder="例如 10000.00"
|
||||
placeholder={t("wallet.placeholders.max", { ns: "config" })}
|
||||
value={draft.inMax}
|
||||
onChange={(e) => handleChange("inMax", e.target.value)}
|
||||
disabled={loading || saving}
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
主站钱包转入彩票钱包的单笔上限
|
||||
{t("wallet.hints.inMax", { ns: "config" })}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="out-min">转出最小金额</Label>
|
||||
<Label htmlFor="out-min">{t("wallet.fields.outMin", { ns: "config" })}</Label>
|
||||
<Input
|
||||
id="out-min"
|
||||
type="number"
|
||||
min="0"
|
||||
step="0.01"
|
||||
placeholder="例如 1.00"
|
||||
placeholder={t("wallet.placeholders.min", { ns: "config" })}
|
||||
value={draft.outMin}
|
||||
onChange={(e) => handleChange("outMin", e.target.value)}
|
||||
disabled={loading || saving}
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
彩票钱包转出主站钱包的单笔下限
|
||||
{t("wallet.hints.outMin", { ns: "config" })}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="out-max">转出最大金额</Label>
|
||||
<Label htmlFor="out-max">{t("wallet.fields.outMax", { ns: "config" })}</Label>
|
||||
<Input
|
||||
id="out-max"
|
||||
type="number"
|
||||
min="0"
|
||||
step="0.01"
|
||||
placeholder="例如 10000.00"
|
||||
placeholder={t("wallet.placeholders.max", { ns: "config" })}
|
||||
value={draft.outMax}
|
||||
onChange={(e) => handleChange("outMax", e.target.value)}
|
||||
disabled={loading || saving}
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
彩票钱包转出主站钱包的单笔上限
|
||||
{t("wallet.hints.outMax", { ns: "config" })}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<Button onClick={() => void handleSave()} disabled={!dirty || loading || saving}>
|
||||
{saving ? "保存中…" : "保存"}
|
||||
{saving ? t("saving", { ns: "adminUsers" }) : t("actions.save", { ns: "adminUsers" })}
|
||||
</Button>
|
||||
{dirty && (
|
||||
<Button
|
||||
@@ -192,7 +196,7 @@ export function WalletConfigDocScreen() {
|
||||
setDirty(false);
|
||||
}}
|
||||
>
|
||||
放弃更改
|
||||
{t("wallet.discard", { ns: "config" })}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user