refactor(admin-reports, i18n): remove rebate commission report and enhance localization

Removed the `getAdminReportRebateCommission` function and its references from the admin reports API and localization files. Updated CSS for improved money display handling in admin components. Enhanced localization support by adding new finance and support workspace entries in English, Nepali, and Chinese, improving user experience across the application.
This commit is contained in:
2026-06-16 16:04:03 +08:00
parent d4cf4ff436
commit a020e34a7d
38 changed files with 1259 additions and 353 deletions

View File

@@ -343,17 +343,21 @@ export function ReconcileConsole(): React.ReactElement {
<CardTitle className="admin-list-title">{t("createTitle")}</CardTitle>
<p className="text-sm text-muted-foreground">{t("createHint")}</p>
</CardHeader>
<CardContent className="admin-list-content pt-4">
<div className="grid gap-4 xl:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]">
<div className="grid gap-4">
<div className="grid gap-1.5">
<Label htmlFor="rc-type">{t("reconcileType")}</Label>
<Input id="rc-type" value={t("reconcileTypeFixed")} readOnly className="bg-muted/30" />
</div>
<div className="grid gap-1.5">
<CardContent className="admin-list-content">
<div className="admin-list-toolbar">
<div className="admin-list-field">
<span className="text-sm font-medium leading-none sm:shrink-0">{t("reconcileType")}</span>
<span className="inline-flex h-8 min-h-8 min-w-0 items-center rounded-md border border-border/60 bg-muted/30 px-2.5 text-sm text-foreground">
{t("reconcileTypeFixed")}
</span>
</div>
<div className="admin-list-field">
<Label htmlFor="rc-date-range" className="sm:shrink-0">
{t("dateRange")}
</Label>
<div className="min-w-0 w-full sm:w-60">
<AdminDateRangeField
id="rc-date-range"
label={t("dateRange")}
from={dateFrom}
to={dateTo}
onRangeChange={({ from, to }) => {
@@ -363,102 +367,101 @@ export function ReconcileConsole(): React.ReactElement {
/>
</div>
</div>
<div className="grid gap-4">
<div className="grid gap-1.5">
<Label htmlFor="rc-player-search">{t("playerSearch")}</Label>
<Input
id="rc-player-search"
value={playerSearch}
onChange={(e) => setPlayerSearch(e.target.value)}
placeholder={t("playerSearchPlaceholder")}
/>
</div>
{selectedPlayer ? (
<div className="flex items-center justify-between gap-3 rounded-lg border bg-muted/20 px-3 py-2 text-sm">
<div className="min-w-0 truncate font-medium text-foreground">
{selectedPlayer.site_player_id}
{selectedPlayer.nickname ? ` · ${selectedPlayer.nickname}` : ""}
{selectedPlayer.username ? ` · ${selectedPlayer.username}` : ""}
{` · ${selectedPlayer.site_code}`}
</div>
<Button
type="button"
size="sm"
variant="outline"
onClick={() => {
setSelectedPlayer(null);
setPlayerSearch("");
setPlayerResults([]);
}}
>
{t("playerClear")}
</Button>
</div>
) : null}
{playerSearch.trim() !== "" || playerResults.length > 0 || playerLoading ? (
<div className="rounded-lg border bg-background">
<div className="max-h-56 overflow-y-auto">
{playerLoading ? (
<AdminLoadingInline className="py-2" label={t("loadingPlayers")} />
) : playerResults.length === 0 ? (
<AdminNoResourceState compact className="px-3 py-4" />
) : (
<div className="divide-y">
{playerResults.map((player) => {
const active = selectedPlayer?.id === player.id;
return (
<button
key={player.id}
type="button"
className={cn(
"flex w-full px-3 py-2.5 text-left text-sm transition-colors hover:bg-muted/25",
active && "bg-muted/30 font-medium",
)}
onClick={() => {
setSelectedPlayer(player);
setPlayerSearch(player.site_player_id);
}}
>
<span className="min-w-0 truncate">
{player.site_player_id}
{player.nickname ? ` · ${player.nickname}` : ""}
{player.username ? ` · ${player.username}` : ""}
{` · ${player.site_code}`}
</span>
</button>
);
})}
</div>
)}
</div>
</div>
) : null}
<div className="admin-list-field min-w-0 flex-1">
<Label htmlFor="rc-player-search" className="sm:shrink-0">
{t("playerSearch")}
</Label>
<Input
id="rc-player-search"
className="w-full sm:w-52"
value={playerSearch}
onChange={(e) => setPlayerSearch(e.target.value)}
placeholder={t("playerSearchPlaceholder")}
/>
</div>
<div className="admin-list-actions">
<Button
type="button"
className="w-full sm:w-auto"
disabled={submitting}
onClick={() =>
requestConfirm({
title: t("confirmCreateTitle"),
description: t("confirmCreateDescription", {
playerHint: selectedPlayer
? t("confirmCreatePlayer")
: t("confirmCreateAllPlayers"),
}),
onConfirm: () => onCreate(),
})
}
>
{submitting ? t("submitting") : t("createTask")}
</Button>
</div>
</div>
<div className="mt-4 flex justify-end">
<Button
type="button"
className="w-full sm:w-auto"
disabled={submitting}
onClick={() =>
requestConfirm({
title: t("confirmCreateTitle"),
description: t("confirmCreateDescription", {
playerHint: selectedPlayer
? t("confirmCreatePlayer")
: t("confirmCreateAllPlayers"),
}),
onConfirm: () => onCreate(),
})
}
>
{submitting ? t("submitting") : t("createTask")}
</Button>
</div>
{selectedPlayer ? (
<div className="flex items-center justify-between gap-3 rounded-lg border bg-muted/20 px-3 py-2 text-sm">
<div className="min-w-0 truncate font-medium text-foreground">
{selectedPlayer.site_player_id}
{selectedPlayer.nickname ? ` · ${selectedPlayer.nickname}` : ""}
{selectedPlayer.username ? ` · ${selectedPlayer.username}` : ""}
{` · ${selectedPlayer.site_code}`}
</div>
<Button
type="button"
size="sm"
variant="outline"
onClick={() => {
setSelectedPlayer(null);
setPlayerSearch("");
setPlayerResults([]);
}}
>
{t("playerClear")}
</Button>
</div>
) : null}
{playerSearch.trim() !== "" || playerResults.length > 0 || playerLoading ? (
<div className="rounded-lg border bg-background">
<div className="max-h-56 overflow-y-auto">
{playerLoading ? (
<AdminLoadingInline className="py-2" label={t("loadingPlayers")} />
) : playerResults.length === 0 ? (
<AdminNoResourceState compact className="px-3 py-4" />
) : (
<div className="divide-y">
{playerResults.map((player) => {
const active = selectedPlayer?.id === player.id;
return (
<button
key={player.id}
type="button"
className={cn(
"flex w-full px-3 py-2.5 text-left text-sm transition-colors hover:bg-muted/25",
active && "bg-muted/30 font-medium",
)}
onClick={() => {
setSelectedPlayer(player);
setPlayerSearch(player.site_player_id);
}}
>
<span className="min-w-0 truncate">
{player.site_player_id}
{player.nickname ? ` · ${player.nickname}` : ""}
{player.username ? ` · ${player.username}` : ""}
{` · ${player.site_code}`}
</span>
</button>
);
})}
</div>
)}
</div>
</div>
) : null}
</CardContent>
</Card>
) : (