feat(agents, config, dashboard, i18n): add agent line provision wizard, site deletion, and site dashboard with multi-language support

Added agent line provision wizard page with permission gating, replacing redirect placeholder. Introduced site deletion API and UI with confirmation dialog in integration sites management. Added new site-scoped dashboard panel showing bet metrics, P/L trends, active players, and quick links. Enhanced chart tooltip to support custom formatters and fix indicator color
This commit is contained in:
2026-06-12 20:47:53 +08:00
parent 24fd7c10bd
commit 6ea0a6feec
48 changed files with 1573 additions and 629 deletions

View File

@@ -75,6 +75,7 @@ import { useAdminCurrencyCatalog } from "@/hooks/use-admin-currency-catalog";
import { useAdminDateTimeFormatter } from "@/hooks/use-admin-datetime-formatter";
import { formatAdminInstant } from "@/lib/admin-datetime";
import { getAdminRequestLocale } from "@/lib/admin-locale";
import { signedMoneyClass } from "@/lib/admin-signed-money";
import { cn } from "@/lib/utils";
import { formatAdminMinorUnits } from "@/lib/money";
import { LotteryApiBizError } from "@/types/api/errors";
@@ -461,6 +462,10 @@ function formatPlainMoney(value: number, currencyCode: string | null | undefined
return formatAdminMinorUnits(value, currencyCode || "NPR");
}
function signedProfitCell(amount: number, currencyCode: string | null | undefined): string {
return cn("text-center tabular-nums", signedMoneyClass(amount, true));
}
function formatUsagePercent(ratio: number | null | undefined): string {
return ratio == null ? "-" : `${Math.round(ratio * 100)}%`;
}
@@ -906,6 +911,10 @@ export function ReportsConsole({ initialCategory }: { initialCategory?: ReportCa
payload.items.reduce((sum, item) => sum - item.net_win_loss_minor, 0),
"NPR",
),
tone: (() => {
const houseGross = payload.items.reduce((sum, item) => sum - item.net_win_loss_minor, 0);
return houseGross >= 0 ? "good" : "bad";
})(),
},
{ label: t("preview.stats.players"), value: String(new Set(payload.items.map((item) => item.player_id)).size) },
],
@@ -1445,7 +1454,9 @@ export function ReportsConsole({ initialCategory }: { initialCategory?: ReportCa
<TableCell className="text-center">{summary.ticket_item_count}</TableCell>
<TableCell className="text-center">{formatPlainMoney(summary.total_bet_minor, summary.currency_code)}</TableCell>
<TableCell className="text-center">{formatPlainMoney(summary.total_payout_minor, summary.currency_code)}</TableCell>
<TableCell className="text-center">{formatPlainMoney(summary.approx_house_gross_minor, summary.currency_code)}</TableCell>
<TableCell className={signedProfitCell(summary.approx_house_gross_minor, summary.currency_code)}>
{formatPlainMoney(summary.approx_house_gross_minor, summary.currency_code)}
</TableCell>
<TableCell>{summary.settlement_batches.length}</TableCell>
</TableRow>
{summary.settlement_batches.map((batch) => (
@@ -1530,7 +1541,9 @@ export function ReportsConsole({ initialCategory }: { initialCategory?: ReportCa
<TableCell>-</TableCell>
<TableCell className="text-center">{formatPlainMoney(item.total_bet_minor, "NPR")}</TableCell>
<TableCell className="text-center">{formatPlainMoney(item.total_payout_minor, "NPR")}</TableCell>
<TableCell className="text-center">{formatPlainMoney(item.approx_house_gross_minor, "NPR")}</TableCell>
<TableCell className={signedProfitCell(item.approx_house_gross_minor, "NPR")}>
{formatPlainMoney(item.approx_house_gross_minor, "NPR")}
</TableCell>
<TableCell>-</TableCell>
<TableCell>-</TableCell>
<TableCell>-</TableCell>
@@ -1548,7 +1561,9 @@ export function ReportsConsole({ initialCategory }: { initialCategory?: ReportCa
</TableCell>
<TableCell className="text-center">{formatPlainMoney(item.total_bet_minor, "NPR")}</TableCell>
<TableCell className="text-center">{formatPlainMoney(item.total_payout_minor, "NPR")}</TableCell>
<TableCell className="text-center">{formatPlainMoney(item.net_win_loss_minor, "NPR")}</TableCell>
<TableCell className={signedProfitCell(item.net_win_loss_minor, "NPR")}>
{formatPlainMoney(item.net_win_loss_minor, "NPR")}
</TableCell>
<TableCell>-</TableCell>
<TableCell>-</TableCell>
<TableCell>-</TableCell>
@@ -1563,7 +1578,9 @@ export function ReportsConsole({ initialCategory }: { initialCategory?: ReportCa
<TableCell>{item.dimension}D</TableCell>
<TableCell className="text-center">{formatPlainMoney(item.total_bet_minor, "NPR")}</TableCell>
<TableCell className="text-center">{formatPlainMoney(item.total_payout_minor, "NPR")}</TableCell>
<TableCell className="text-center">{formatPlainMoney(item.approx_house_gross_minor, "NPR")}</TableCell>
<TableCell className={signedProfitCell(item.approx_house_gross_minor, "NPR")}>
{formatPlainMoney(item.approx_house_gross_minor, "NPR")}
</TableCell>
<TableCell>-</TableCell>
<TableCell>-</TableCell>
<TableCell>-</TableCell>