refactor: update agent API schemas, standardize UI text styling, and enhance settlement credit ledger components

This commit is contained in:
2026-06-11 18:02:02 +08:00
parent 44ad51698f
commit 1eb6702c51
54 changed files with 1888 additions and 1103 deletions

View File

@@ -659,14 +659,14 @@ export function OddsConfigDocScreen({
id="odds-rebate-rate"
type="text"
inputMode="decimal"
className="h-9 font-mono tabular-nums"
className="h-9 text-base font-semibold"
disabled={saving}
value={rebatePercentUi}
placeholder={t("odds.placeholders.rebateRate", { ns: "config" })}
onChange={(e) => setRebateForPlayPercent(e.target.value)}
/>
) : (
<ConfigReadonlyValue mono className="h-9 w-full max-w-xs justify-center">
<ConfigReadonlyValue className="h-9 w-full max-w-xs justify-center text-base font-semibold">
{rebatePercentUi}
</ConfigReadonlyValue>
)}
@@ -703,7 +703,7 @@ export function OddsConfigDocScreen({
<Input
type="text"
inputMode="decimal"
className="ml-auto h-9 w-full max-w-[9rem] font-mono tabular-nums"
className="ml-auto h-9 w-full max-w-[9rem] text-base font-semibold"
disabled={saving}
value={oddsMultiplierLabel(row.odds_value)}
placeholder={t("odds.placeholders.multiplier", { ns: "config" })}
@@ -714,7 +714,7 @@ export function OddsConfigDocScreen({
}
/>
) : (
<ConfigReadonlyValue mono className="ml-auto h-9 w-full max-w-[9rem] justify-center">
<ConfigReadonlyValue className="ml-auto h-9 w-full max-w-[9rem] justify-center text-base font-semibold">
{oddsMultiplierLabel(row.odds_value)}
</ConfigReadonlyValue>
)
@@ -743,7 +743,7 @@ export function OddsConfigDocScreen({
<Input
type="text"
inputMode="decimal"
className="h-9 w-full font-mono tabular-nums"
className="h-9 w-full text-base font-semibold"
disabled={saving}
value={oddsMultiplierLabel(row.odds_value)}
placeholder={t("odds.placeholders.multiplier", { ns: "config" })}
@@ -754,7 +754,7 @@ export function OddsConfigDocScreen({
}
/>
) : (
<ConfigReadonlyValue mono className="h-9 w-full justify-center">
<ConfigReadonlyValue className="h-9 w-full justify-center text-base font-semibold">
{oddsMultiplierLabel(row.odds_value)}
</ConfigReadonlyValue>
)
@@ -771,14 +771,14 @@ export function OddsConfigDocScreen({
<Input
type="text"
inputMode="decimal"
className="h-9 w-full font-mono tabular-nums"
className="h-9 w-full text-base font-semibold"
disabled={saving}
value={rebatePercentUi}
placeholder={t("odds.placeholders.rebateRate", { ns: "config" })}
onChange={(e) => setRebateForPlayPercent(e.target.value)}
/>
) : (
<ConfigReadonlyValue mono className="h-9 w-full justify-center">
<ConfigReadonlyValue className="h-9 w-full justify-center text-base font-semibold">
{rebatePercentUi}
</ConfigReadonlyValue>
)}
@@ -857,10 +857,10 @@ export function OddsConfigDocScreen({
{publishDiffRows.map((row) => (
<div key={row.scope} className="grid grid-cols-3 px-3 py-2 text-sm">
<span>{row.label}</span>
<span className="text-right font-mono tabular-nums">
<span className="text-right text-base font-semibold">
{row.oldValue === null ? "—" : oddsMultiplierLabel(row.oldValue)}
</span>
<span className="text-right font-mono tabular-nums">
<span className="text-right text-base font-semibold">
{row.newValue === null ? "—" : oddsMultiplierLabel(row.newValue)}
</span>
</div>

View File

@@ -92,7 +92,7 @@ export function OddsConfigSummaryPanel({
return (
<div key={scope} className="grid grid-cols-[minmax(0,1fr)_auto] gap-3 text-sm">
<dt className="text-muted-foreground">{prizeScopeLabel(scope, t)}</dt>
<dd className="font-mono text-right tabular-nums text-foreground">
<dd className="text-right text-lg font-semibold text-foreground">
{row ? oddsMultiplierLabel(row.odds_value) : "—"}
</dd>
</div>
@@ -101,7 +101,7 @@ export function OddsConfigSummaryPanel({
{playRebatePercent ? (
<div className="grid grid-cols-[minmax(0,1fr)_auto] gap-3 text-sm">
<dt className="text-muted-foreground">{t("odds.rebateRate")}</dt>
<dd className="font-mono text-right tabular-nums text-foreground">{playRebatePercent}</dd>
<dd className="text-right text-lg font-semibold text-foreground">{playRebatePercent}</dd>
</div>
) : null}
</dl>

View File

@@ -818,7 +818,7 @@ export function PlayConfigDocScreen() {
<Input
type="text"
inputMode="decimal"
className="mx-auto h-8 w-24 text-center font-mono tabular-nums"
className="mx-auto h-8 w-24 text-center text-sm font-semibold"
disabled={saving}
value={formatAdminMinorDecimal(row.min_bet_amount, amountCurrencyCode)}
placeholder={t("play.placeholders.minBetAmount", { ns: "config" })}
@@ -830,7 +830,7 @@ export function PlayConfigDocScreen() {
}
/>
) : (
<ConfigReadonlyValue mono className="justify-center">
<ConfigReadonlyValue className="justify-center text-sm font-semibold">
{formatAdminMinorDecimal(row.min_bet_amount, amountCurrencyCode)}
</ConfigReadonlyValue>
)}
@@ -840,7 +840,7 @@ export function PlayConfigDocScreen() {
<Input
type="text"
inputMode="decimal"
className="mx-auto h-8 w-24 text-center font-mono tabular-nums"
className="mx-auto h-8 w-24 text-center text-sm font-semibold"
disabled={saving}
value={formatAdminMinorDecimal(row.max_bet_amount, amountCurrencyCode)}
placeholder={t("play.placeholders.maxBetAmount", { ns: "config" })}
@@ -852,7 +852,7 @@ export function PlayConfigDocScreen() {
}
/>
) : (
<ConfigReadonlyValue mono className="justify-center">
<ConfigReadonlyValue className="justify-center text-sm font-semibold">
{formatAdminMinorDecimal(row.max_bet_amount, amountCurrencyCode)}
</ConfigReadonlyValue>
)}

View File

@@ -553,14 +553,14 @@ export function RebateConfigDocScreen({
type="number"
step="0.01"
min={0}
className="font-mono tabular-nums"
className="h-9 text-base font-semibold"
disabled={saving}
value={p2}
placeholder={t("rebate.placeholders.d2", { ns: "config" })}
onChange={(e) => setP2(e.target.value)}
/>
) : (
<ConfigReadonlyValue mono>{p2}</ConfigReadonlyValue>
<ConfigReadonlyValue className="text-base font-semibold">{p2}</ConfigReadonlyValue>
)}
</div>
<div className="grid gap-2">
@@ -570,14 +570,14 @@ export function RebateConfigDocScreen({
type="number"
step="0.01"
min={0}
className="font-mono tabular-nums"
className="h-9 text-base font-semibold"
disabled={saving}
value={p3}
placeholder={t("rebate.placeholders.d3", { ns: "config" })}
onChange={(e) => setP3(e.target.value)}
/>
) : (
<ConfigReadonlyValue mono>{p3}</ConfigReadonlyValue>
<ConfigReadonlyValue className="text-base font-semibold">{p3}</ConfigReadonlyValue>
)}
</div>
<div className="grid gap-2">
@@ -587,14 +587,14 @@ export function RebateConfigDocScreen({
type="number"
step="0.01"
min={0}
className="font-mono tabular-nums"
className="h-9 text-base font-semibold"
disabled={saving}
value={p4}
placeholder={t("rebate.placeholders.d4", { ns: "config" })}
onChange={(e) => setP4(e.target.value)}
/>
) : (
<ConfigReadonlyValue mono>{p4}</ConfigReadonlyValue>
<ConfigReadonlyValue className="text-base font-semibold">{p4}</ConfigReadonlyValue>
)}
</div>
</div>

View File

@@ -98,6 +98,10 @@ function defaultRiskRowFromAmount(amount: number): DraftRiskRow {
};
}
function formatMinorToEditableMajor(minor: number, currencyCode: string): string {
return formatAdminMinorDecimal(minor, currencyCode).replace(/,/g, "");
}
export function RiskCapDocScreen() {
const { t } = useTranslation(["config", "adminUsers", "common"]);
const tRef = useTranslationRef(["config", "common"]);
@@ -161,7 +165,7 @@ export function RiskCapDocScreen() {
setDefaultCapStr("");
return;
}
setDefaultCapStr(formatAdminMinorDecimal(defaultRow.cap_amount, amountCurrencyCode));
setDefaultCapStr(formatMinorToEditableMajor(defaultRow.cap_amount, amountCurrencyCode));
}
const loadDetail = useCallback(async (id: number) => {
@@ -381,7 +385,12 @@ export function RiskCapDocScreen() {
() => specialRows.filter(({ row }) => row.draw_id != null),
[specialRows],
);
const defaultCapDisplay = defaultCapStr || formatAdminMinorDecimal(0, amountCurrencyCode);
const defaultCapDisplay = detail
? formatAdminMinorDecimal(
draftRows.find(isDefaultRiskRow)?.cap_amount ?? 0,
amountCurrencyCode,
)
: formatAdminMinorDecimal(0, amountCurrencyCode);
async function handleDeleteVersion(row: ConfigVersionSummary) {
try {
@@ -524,7 +533,7 @@ export function RiskCapDocScreen() {
].map((card) => (
<div key={card.key} className="rounded-xl border border-border/60 bg-background p-4 shadow-sm">
<p className="text-xs text-muted-foreground">{card.label}</p>
<p className="mt-1 font-mono text-lg font-semibold tabular-nums">{card.value}</p>
<p className="mt-1 text-2xl font-semibold tabular-nums text-foreground">{card.value}</p>
<p className="mt-2 text-xs leading-5 text-muted-foreground">{card.hint}</p>
</div>
))}
@@ -539,15 +548,15 @@ export function RiskCapDocScreen() {
id="default-cap"
type="text"
inputMode="decimal"
className="w-[220px] font-mono tabular-nums"
className="h-9 w-[220px] text-base font-semibold"
disabled={saving}
value={defaultCapStr}
placeholder={t("riskCap.placeholders.defaultCap", { ns: "config" })}
onChange={(e) => setDefaultCapStr(e.target.value)}
/>
) : (
<ConfigReadonlyValue mono className="w-[220px]">
{defaultCapStr || formatAdminMinorDecimal(0, amountCurrencyCode)}
<ConfigReadonlyValue className="h-9 w-[220px] text-base font-semibold">
{defaultCapDisplay}
</ConfigReadonlyValue>
)}
</div>
@@ -679,9 +688,9 @@ export function RiskCapDocScreen() {
<Input
type="text"
inputMode="decimal"
className="h-8 font-mono tabular-nums"
className="h-8 tabular-nums"
disabled={saving}
value={formatAdminMinorDecimal(r.cap_amount, amountCurrencyCode)}
value={formatMinorToEditableMajor(r.cap_amount, amountCurrencyCode)}
placeholder={t("riskCap.placeholders.capAmount", { ns: "config" })}
onChange={(e) =>
updateRow(idx, {
@@ -691,7 +700,7 @@ export function RiskCapDocScreen() {
}
/>
) : (
<ConfigReadonlyValue mono>
<ConfigReadonlyValue>
{formatAdminMinorDecimal(r.cap_amount, amountCurrencyCode)}
</ConfigReadonlyValue>
)}