diff --git a/messages/en.json b/messages/en.json index f7b9c34..3e22e9c 100644 --- a/messages/en.json +++ b/messages/en.json @@ -39,7 +39,9 @@ "firstPage": "First Page", "lastPage": "Last Page", "nextPage": "Next Page", - "previousPage": "Previous Page" + "previousPage": "Previous Page", + "ascending": "Asc", + "descending": "Desc" } }, "PricingPage": { diff --git a/messages/zh.json b/messages/zh.json index 886a5ea..3b85703 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -39,7 +39,9 @@ "firstPage": "第一页", "lastPage": "最后一页", "nextPage": "下一页", - "previousPage": "上一页" + "previousPage": "上一页", + "ascending": "升序", + "descending": "降序" } }, "PricingPage": { diff --git a/src/components/admin/users-table.tsx b/src/components/admin/users-table.tsx index 3423be9..581659b 100644 --- a/src/components/admin/users-table.tsx +++ b/src/components/admin/users-table.tsx @@ -6,6 +6,8 @@ import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { Input } from '@/components/ui/input'; @@ -27,6 +29,7 @@ import { import type { User } from '@/lib/auth-types'; import { formatDate } from '@/lib/formatter'; import { getStripeDashboardCustomerUrl } from '@/lib/urls/urls'; +import { IconCaretDownFilled, IconCaretUpFilled } from '@tabler/icons-react'; import { type ColumnDef, type ColumnFiltersState, @@ -40,7 +43,6 @@ import { useReactTable, } from '@tanstack/react-table'; import { - ArrowUpDownIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, @@ -68,20 +70,47 @@ function DataTableColumnHeader({ title, className, }: DataTableColumnHeaderProps) { + const tTable = useTranslations('Common.table'); if (!column.getCanSort()) { return
{title}
; } + const isSorted = column.getIsSorted(); // 'asc' | 'desc' | false + return (
- + + + + + + { + if (value === 'asc') column.toggleSorting(false); + else if (value === 'desc') column.toggleSorting(true); + }} + > + + + {tTable('ascending')} + + + + + {tTable('descending')} + + + + +
); } @@ -117,7 +146,7 @@ export function UsersTable({ const t = useTranslations('Dashboard.admin.users'); const tTable = useTranslations('Common.table'); const [sorting, setSorting] = useState([ - { id: 'createdAt', desc: true } + { id: 'createdAt', desc: true }, ]); const [columnFilters, setColumnFilters] = useState([]); const [columnVisibility, setColumnVisibility] = useState({}); diff --git a/src/components/settings/credits/credit-transactions-table.tsx b/src/components/settings/credits/credit-transactions-table.tsx index 022a475..d9a3d89 100644 --- a/src/components/settings/credits/credit-transactions-table.tsx +++ b/src/components/settings/credits/credit-transactions-table.tsx @@ -5,6 +5,8 @@ import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { Input } from '@/components/ui/input'; @@ -32,6 +34,12 @@ import { import { CreditDetailViewer } from '@/credits/credit-detail-viewer'; import { CREDIT_TRANSACTION_TYPE } from '@/credits/types'; import { formatDate } from '@/lib/formatter'; +import { CaretDownIcon, CaretUpIcon } from '@radix-ui/react-icons'; +import { + IconCaretDownFilled, + IconCaretUpFilled, + IconSortAscending2, +} from '@tabler/icons-react'; import { type ColumnDef, type ColumnFiltersState, @@ -45,13 +53,17 @@ import { useReactTable, } from '@tanstack/react-table'; import { + ArrowDownIcon, ArrowUpDownIcon, + ArrowUpIcon, BanknoteIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, + ChevronUpIcon, ChevronsLeftIcon, ChevronsRightIcon, + ChevronsUpDownIcon, ClockIcon, CoinsIcon, GemIcon, @@ -91,16 +103,51 @@ function DataTableColumnHeader({ title, className, }: DataTableColumnHeaderProps) { + const tTable = useTranslations('Common.table'); + + // Only show dropdown for sortable columns + if (!column.getCanSort()) { + return
{title}
; + } + + // Determine current sort state + const isSorted = column.getIsSorted(); // 'asc' | 'desc' | false + return (
- + + + + + + { + if (value === 'asc') column.toggleSorting(false); + else if (value === 'desc') column.toggleSorting(true); + }} + > + + + {tTable('ascending')} + + + + + {tTable('descending')} + + + + +
); }