feat(ui): enhance table and admin components with improved layout and status display
- Updated global CSS to center-align table headers and cells, ensuring a consistent layout. - Modified admin table components to replace switches with status badges for better clarity. - Enhanced internationalization support by adding new strings for version actions and validation messages in multiple locales. - Refactored configuration document screens to include version selection and improved user feedback on status changes.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useConfirmAction } from "@/hooks/use-confirm-action";
|
||||
import { useAdminDateTimeFormatter } from "@/hooks/use-admin-datetime-formatter";
|
||||
import { useExportLabels } from "@/hooks/use-export-labels";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from "sonner";
|
||||
@@ -16,8 +17,10 @@ import {
|
||||
} from "@/api/admin-player";
|
||||
import { AdminListPaginationFooter } from "@/components/admin/admin-list-pagination-footer";
|
||||
import { AdminTableExportButton } from "@/components/admin/admin-table-export-button";
|
||||
import { AdminStatusBadge } from "@/components/admin/admin-status-badge";
|
||||
import { ConfirmableSwitch } from "@/components/admin/confirmable-switch";
|
||||
import { resolvePlayerStatusTone } from "@/lib/admin-status-tone";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import {
|
||||
Dialog,
|
||||
@@ -66,7 +69,8 @@ const PLAYER_STATUS_OPTIONS = [
|
||||
|
||||
export function PlayersConsole(): React.ReactElement {
|
||||
const { t } = useTranslation(["players", "common"]);
|
||||
const { request: requestConfirm, ConfirmDialog } = useConfirmAction();
|
||||
const { request: requestConfirm, ConfirmDialog, busy: confirmBusy } = useConfirmAction();
|
||||
const formatDt = useAdminDateTimeFormatter();
|
||||
const exportLabels = useExportLabels("players");
|
||||
const profile = useAdminProfile();
|
||||
useAdminCurrencyCatalog();
|
||||
@@ -338,8 +342,8 @@ export function PlayersConsole(): React.ReactElement {
|
||||
<TableHead>{t("username")}</TableHead>
|
||||
<TableHead>{t("nickname")}</TableHead>
|
||||
<TableHead className="whitespace-nowrap">{t("currency")}</TableHead>
|
||||
<TableHead className="whitespace-nowrap text-right">{t("balance")}</TableHead>
|
||||
<TableHead className="whitespace-nowrap text-right">{t("available")}</TableHead>
|
||||
<TableHead className="whitespace-nowrap text-center">{t("balance")}</TableHead>
|
||||
<TableHead className="whitespace-nowrap text-center">{t("available")}</TableHead>
|
||||
<TableHead className="w-20 whitespace-nowrap">{t("status")}</TableHead>
|
||||
<TableHead className="whitespace-nowrap">{t("lastLogin")}</TableHead>
|
||||
<TableHead className="min-w-[10rem]">{t("actions")}</TableHead>
|
||||
@@ -365,21 +369,28 @@ export function PlayersConsole(): React.ReactElement {
|
||||
<TableCell>{row.username ?? "—"}</TableCell>
|
||||
<TableCell>{row.nickname ?? "—"}</TableCell>
|
||||
<TableCell>{row.default_currency}</TableCell>
|
||||
<TableCell className="whitespace-nowrap text-right tabular-nums text-xs">
|
||||
<TableCell className="whitespace-nowrap text-center tabular-nums text-xs">
|
||||
{row.wallets.length > 0
|
||||
? formatAdminMinorUnits(row.wallets[0].balance, row.wallets[0].currency_code)
|
||||
: "—"}
|
||||
</TableCell>
|
||||
<TableCell className="whitespace-nowrap text-right tabular-nums text-xs">
|
||||
<TableCell className="whitespace-nowrap text-center tabular-nums text-xs">
|
||||
{row.wallets.length > 0
|
||||
? formatAdminMinorUnits(row.wallets[0].available_balance, row.wallets[0].currency_code)
|
||||
: "—"}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{canFreezePlayers ? (
|
||||
{row.status === 2 ? (
|
||||
<div className="flex justify-center">
|
||||
<Switch
|
||||
<AdminStatusBadge status={row.status} tone={resolvePlayerStatusTone(row.status)}>
|
||||
{playerStatusLabelT(row.status, t)}
|
||||
</AdminStatusBadge>
|
||||
</div>
|
||||
) : canFreezePlayers ? (
|
||||
<div className="flex justify-center">
|
||||
<ConfirmableSwitch
|
||||
checked={row.status === 0}
|
||||
confirmBusy={confirmBusy}
|
||||
disabled={freezeBusyId === row.id}
|
||||
aria-label={t("status")}
|
||||
onCheckedChange={(checked) => {
|
||||
@@ -407,15 +418,7 @@ export function PlayersConsole(): React.ReactElement {
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className="whitespace-nowrap text-xs text-muted-foreground">
|
||||
{row.last_login_at
|
||||
? new Date(row.last_login_at).toLocaleString("zh-CN", {
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
})
|
||||
: "—"}
|
||||
{row.last_login_at ? formatDt(row.last_login_at) : "—"}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{canManagePlayers || canFreezePlayers ? (
|
||||
|
||||
Reference in New Issue
Block a user