refactor: update translations and improve table component structure

- Removed unused translation keys from English and Chinese JSON files.
- Updated UsersTable and CreditTransactionsTable components to utilize a centralized translation function for table-related messages.
- Initialized sorting state in both table components for consistent default behavior.
This commit is contained in:
javayhu 2025-07-06 18:20:31 +08:00
parent d9cda3e122
commit 04c2b2d7ee
4 changed files with 33 additions and 51 deletions

View File

@ -470,14 +470,6 @@
"banReason": "Ban Reason",
"banExpires": "Ban Expires"
},
"noResults": "No results",
"firstPage": "First Page",
"lastPage": "Last Page",
"nextPage": "Next Page",
"previousPage": "Previous Page",
"rowsPerPage": "Rows per page",
"page": "Page",
"loading": "Loading...",
"admin": "Admin",
"user": "User",
"email": {

View File

@ -471,14 +471,6 @@
"banReason": "封禁原因",
"banExpires": "封禁到期时间"
},
"noResults": "没有结果",
"firstPage": "第一页",
"lastPage": "最后一页",
"nextPage": "下一页",
"previousPage": "上一页",
"rowsPerPage": "每页行数",
"page": "页",
"loading": "加载中...",
"admin": "管理员",
"user": "用户",
"email": {

View File

@ -115,7 +115,10 @@ export function UsersTable({
onSortingChange,
}: UsersTableProps) {
const t = useTranslations('Dashboard.admin.users');
const [sorting, setSorting] = useState<SortingState>([]);
const tTable = useTranslations('Common.table');
const [sorting, setSorting] = useState<SortingState>([
{ id: 'createdAt', desc: true }
]);
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
@ -401,7 +404,7 @@ export function UsersTable({
colSpan={columns.length}
className="h-24 text-center"
>
{t('loading')}
{tTable('loading')}
</TableCell>
</TableRow>
) : table.getRowModel().rows?.length ? (
@ -426,7 +429,7 @@ export function UsersTable({
colSpan={columns.length}
className="h-24 text-center"
>
{t('noResults')}
{tTable('noResults')}
</TableCell>
</TableRow>
)}
@ -440,7 +443,7 @@ export function UsersTable({
<div className="flex w-full items-center gap-8 lg:w-fit">
<div className="hidden items-center gap-2 lg:flex">
<Label htmlFor="rows-per-page" className="text-sm font-medium">
{t('rowsPerPage')}
{tTable('rowsPerPage')}
</Label>
<Select
value={`${pageSize}`}
@ -466,7 +469,7 @@ export function UsersTable({
</Select>
</div>
<div className="flex w-fit items-center justify-center text-sm font-medium">
{t('page')} {pageIndex + 1} {' / '}
{tTable('page')} {pageIndex + 1} {' / '}
{Math.max(1, Math.ceil(total / pageSize))}
</div>
<div className="ml-auto flex items-center gap-2 lg:ml-0">
@ -476,7 +479,7 @@ export function UsersTable({
onClick={() => onPageChange(0)}
disabled={pageIndex === 0}
>
<span className="sr-only">{t('firstPage')}</span>
<span className="sr-only">{tTable('firstPage')}</span>
<ChevronsLeftIcon />
</Button>
<Button
@ -486,7 +489,7 @@ export function UsersTable({
onClick={() => onPageChange(pageIndex - 1)}
disabled={pageIndex === 0}
>
<span className="sr-only">{t('previousPage')}</span>
<span className="sr-only">{tTable('previousPage')}</span>
<ChevronLeftIcon />
</Button>
<Button
@ -496,7 +499,7 @@ export function UsersTable({
onClick={() => onPageChange(pageIndex + 1)}
disabled={pageIndex + 1 >= Math.ceil(total / pageSize)}
>
<span className="sr-only">{t('nextPage')}</span>
<span className="sr-only">{tTable('nextPage')}</span>
<ChevronRightIcon />
</Button>
<Button
@ -508,7 +511,7 @@ export function UsersTable({
}
disabled={pageIndex + 1 >= Math.ceil(total / pageSize)}
>
<span className="sr-only">{t('lastPage')}</span>
<span className="sr-only">{tTable('lastPage')}</span>
<ChevronsRightIcon />
</Button>
</div>

View File

@ -125,13 +125,28 @@ export function CreditTransactionsTable({
}: CreditTransactionsTableProps) {
const t = useTranslations('Dashboard.settings.credits.transactions');
const tTable = useTranslations('Common.table');
const [sorting, setSorting] = useState<SortingState>([]);
const [sorting, setSorting] = useState<SortingState>([
{ id: 'createdAt', desc: true }
]);
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
// show fake data in demo website
const isDemo = process.env.NEXT_PUBLIC_DEMO_WEBSITE === 'true';
// Map column IDs to translation keys
const columnIdToTranslationKey = {
type: 'columns.type' as const,
amount: 'columns.amount' as const,
remainingAmount: 'columns.remainingAmount' as const,
description: 'columns.description' as const,
paymentId: 'columns.paymentId' as const,
expirationDate: 'columns.expirationDate' as const,
expirationDateProcessedAt: 'columns.expirationDateProcessedAt' as const,
createdAt: 'columns.createdAt' as const,
updatedAt: 'columns.updatedAt' as const,
} as const;
// Get transaction type icon and color
const getTransactionTypeIcon = (type: string) => {
switch (type) {
@ -425,30 +440,6 @@ export function CreditTransactionsTable({
.getAllColumns()
.filter((column) => column.getCanHide())
.map((column) => {
const getColumnDisplayName = (columnId: string) => {
switch (columnId) {
case 'type':
return t('columns.type');
case 'amount':
return t('columns.amount');
case 'remainingAmount':
return t('columns.remainingAmount');
case 'description':
return t('columns.description');
case 'paymentId':
return t('columns.paymentId');
case 'expirationDate':
return t('columns.expirationDate');
case 'expirationDateProcessedAt':
return t('columns.expirationDateProcessedAt');
case 'createdAt':
return t('columns.createdAt');
case 'updatedAt':
return t('columns.updatedAt');
default:
return columnId;
}
};
return (
<DropdownMenuCheckboxItem
key={column.id}
@ -458,7 +449,11 @@ export function CreditTransactionsTable({
column.toggleVisibility(!!value)
}
>
{getColumnDisplayName(column.id)}
{t(
columnIdToTranslationKey[
column.id as keyof typeof columnIdToTranslationKey
] || 'columns.columns'
)}
</DropdownMenuCheckboxItem>
);
})}