Add ID and Created columns to all admin pages with sortable columns
- Add ID column to all admin list pages for easy record identification - Add Created column (created_at/date_joined) to pages missing it - Implement client-side column sorting in DataTable component - Fix sorting implementation to work without getSortingRowModel export 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,15 @@ const roleColors: Record<string, 'default' | 'secondary' | 'destructive'> = {
|
||||
};
|
||||
|
||||
const columns: ColumnDef<ManagedAdminUser>[] = [
|
||||
{
|
||||
accessorKey: 'id',
|
||||
header: 'ID',
|
||||
cell: ({ row }) => (
|
||||
<span className="font-mono text-sm text-muted-foreground">
|
||||
{row.original.id}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: 'email',
|
||||
header: 'Email',
|
||||
|
||||
@@ -170,6 +170,7 @@ export default function AppleSocialAuthPage() {
|
||||
onCheckedChange={handleSelectAll}
|
||||
/>
|
||||
</TableHead>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead>User</TableHead>
|
||||
<TableHead>Apple ID</TableHead>
|
||||
<TableHead>Apple Email</TableHead>
|
||||
@@ -202,6 +203,7 @@ export default function AppleSocialAuthPage() {
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className="font-mono text-sm text-muted-foreground">{entry.id}</TableCell>
|
||||
<TableCell>
|
||||
<Link
|
||||
href={`/admin/users/${entry.user_id}`}
|
||||
|
||||
@@ -170,6 +170,7 @@ export default function AuthTokensPage() {
|
||||
onCheckedChange={handleSelectAll}
|
||||
/>
|
||||
</TableHead>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead>User</TableHead>
|
||||
<TableHead>Email</TableHead>
|
||||
<TableHead>Token</TableHead>
|
||||
@@ -201,6 +202,7 @@ export default function AuthTokensPage() {
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className="font-mono text-sm text-muted-foreground">{token.user_id}</TableCell>
|
||||
<TableCell>
|
||||
<Link
|
||||
href={`/admin/users/${token.user_id}`}
|
||||
|
||||
@@ -170,6 +170,7 @@ export default function CompletionImagesPage() {
|
||||
onCheckedChange={handleSelectAll}
|
||||
/>
|
||||
</TableHead>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead>Preview</TableHead>
|
||||
<TableHead>Task</TableHead>
|
||||
<TableHead>Caption</TableHead>
|
||||
@@ -202,6 +203,7 @@ export default function CompletionImagesPage() {
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className="font-mono text-sm text-muted-foreground">{img.id}</TableCell>
|
||||
<TableCell>
|
||||
{img.image_url ? (
|
||||
<a href={img.image_url} target="_blank" rel="noopener noreferrer">
|
||||
|
||||
@@ -179,12 +179,14 @@ export default function CompletionsPage() {
|
||||
onCheckedChange={handleSelectAll}
|
||||
/>
|
||||
</TableHead>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead>Task</TableHead>
|
||||
<TableHead>Residence</TableHead>
|
||||
<TableHead>Completed By</TableHead>
|
||||
<TableHead>Completed At</TableHead>
|
||||
<TableHead>Cost</TableHead>
|
||||
<TableHead>Photo</TableHead>
|
||||
<TableHead>Created</TableHead>
|
||||
<TableHead className="w-24">Actions</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
@@ -212,6 +214,7 @@ export default function CompletionsPage() {
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className="font-mono text-sm text-muted-foreground">{completion.id}</TableCell>
|
||||
<TableCell>
|
||||
<Link
|
||||
href={`/completions/${completion.id}`}
|
||||
@@ -295,6 +298,9 @@ export default function CompletionsPage() {
|
||||
<span className="text-muted-foreground">-</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{new Date(completion.created_at).toLocaleDateString()}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
|
||||
@@ -175,6 +175,7 @@ export default function ConfirmationCodesPage() {
|
||||
onCheckedChange={handleSelectAll}
|
||||
/>
|
||||
</TableHead>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead>User</TableHead>
|
||||
<TableHead>Email</TableHead>
|
||||
<TableHead>Code</TableHead>
|
||||
@@ -208,6 +209,7 @@ export default function ConfirmationCodesPage() {
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className="font-mono text-sm text-muted-foreground">{code.id}</TableCell>
|
||||
<TableCell>
|
||||
<Link
|
||||
href={`/admin/users/${code.user_id}`}
|
||||
|
||||
@@ -31,6 +31,15 @@ import {
|
||||
import { toast } from 'sonner';
|
||||
|
||||
const columns: ColumnDef<Contractor>[] = [
|
||||
{
|
||||
accessorKey: 'id',
|
||||
header: 'ID',
|
||||
cell: ({ row }) => (
|
||||
<span className="font-mono text-sm text-muted-foreground">
|
||||
{row.original.id}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: 'Name',
|
||||
@@ -82,6 +91,11 @@ const columns: ColumnDef<Contractor>[] = [
|
||||
</Badge>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: 'created_at',
|
||||
header: 'Created',
|
||||
cell: ({ row }) => new Date(row.original.created_at).toLocaleDateString(),
|
||||
},
|
||||
{
|
||||
id: 'actions',
|
||||
cell: ({ row }) => {
|
||||
|
||||
@@ -269,6 +269,7 @@ export default function DevicesPage() {
|
||||
}}
|
||||
/>
|
||||
</TableHead>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead>Name</TableHead>
|
||||
<TableHead>User</TableHead>
|
||||
<TableHead>Device ID</TableHead>
|
||||
@@ -306,6 +307,7 @@ export default function DevicesPage() {
|
||||
}}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className="font-mono text-sm text-muted-foreground">{device.id}</TableCell>
|
||||
<TableCell className="font-medium">{device.name || 'Unknown'}</TableCell>
|
||||
<TableCell>
|
||||
{device.user_id ? (
|
||||
|
||||
@@ -170,6 +170,7 @@ export default function DocumentImagesPage() {
|
||||
onCheckedChange={handleSelectAll}
|
||||
/>
|
||||
</TableHead>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead>Preview</TableHead>
|
||||
<TableHead>Document</TableHead>
|
||||
<TableHead>Residence</TableHead>
|
||||
@@ -202,6 +203,7 @@ export default function DocumentImagesPage() {
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className="font-mono text-sm text-muted-foreground">{img.id}</TableCell>
|
||||
<TableCell>
|
||||
{img.image_url ? (
|
||||
<a href={img.image_url} target="_blank" rel="noopener noreferrer">
|
||||
|
||||
@@ -40,6 +40,15 @@ const documentTypeColors: Record<string, 'default' | 'secondary' | 'destructive'
|
||||
};
|
||||
|
||||
const columns: ColumnDef<Document>[] = [
|
||||
{
|
||||
accessorKey: 'id',
|
||||
header: 'ID',
|
||||
cell: ({ row }) => (
|
||||
<span className="font-mono text-sm text-muted-foreground">
|
||||
{row.original.id}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: 'title',
|
||||
header: 'Title',
|
||||
|
||||
@@ -122,11 +122,13 @@ export default function FeatureBenefitsPage() {
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead>Order</TableHead>
|
||||
<TableHead>Feature</TableHead>
|
||||
<TableHead>Free Tier</TableHead>
|
||||
<TableHead>Pro Tier</TableHead>
|
||||
<TableHead>Active</TableHead>
|
||||
<TableHead>Created</TableHead>
|
||||
<TableHead className="w-24">Actions</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
@@ -138,6 +140,7 @@ export default function FeatureBenefitsPage() {
|
||||
) : (
|
||||
data?.data?.map((benefit) => (
|
||||
<TableRow key={benefit.id}>
|
||||
<TableCell className="font-mono text-sm text-muted-foreground">{benefit.id}</TableCell>
|
||||
<TableCell>{benefit.display_order}</TableCell>
|
||||
<TableCell className="font-medium">{benefit.feature_name}</TableCell>
|
||||
<TableCell>{benefit.free_tier_text}</TableCell>
|
||||
@@ -147,6 +150,9 @@ export default function FeatureBenefitsPage() {
|
||||
{benefit.is_active ? 'Active' : 'Inactive'}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{new Date(benefit.created_at).toLocaleDateString()}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex gap-1">
|
||||
<Button variant="ghost" size="icon" onClick={() => handleEdit(benefit)}>
|
||||
|
||||
@@ -88,6 +88,15 @@ export default function NotificationPrefsPage() {
|
||||
};
|
||||
|
||||
const columns: ColumnDef<NotificationPreference>[] = [
|
||||
{
|
||||
accessorKey: 'id',
|
||||
header: 'ID',
|
||||
cell: ({ row }) => (
|
||||
<span className="font-mono text-sm text-muted-foreground">
|
||||
{row.original.id}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: 'username',
|
||||
header: 'User',
|
||||
@@ -226,6 +235,11 @@ export default function NotificationPrefsPage() {
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'created_at',
|
||||
header: 'Created',
|
||||
cell: ({ row }) => new Date(row.original.created_at).toLocaleDateString(),
|
||||
},
|
||||
{
|
||||
id: 'actions',
|
||||
cell: ({ row }) => {
|
||||
|
||||
@@ -20,6 +20,15 @@ import {
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
|
||||
const columns: ColumnDef<Notification>[] = [
|
||||
{
|
||||
accessorKey: 'id',
|
||||
header: 'ID',
|
||||
cell: ({ row }) => (
|
||||
<span className="font-mono text-sm text-muted-foreground">
|
||||
{row.original.id}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: 'title',
|
||||
header: 'Title',
|
||||
|
||||
@@ -207,6 +207,7 @@ export default function PasswordResetCodesPage() {
|
||||
onCheckedChange={handleSelectAll}
|
||||
/>
|
||||
</TableHead>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead>User</TableHead>
|
||||
<TableHead>Email</TableHead>
|
||||
<TableHead>Token</TableHead>
|
||||
@@ -241,6 +242,7 @@ export default function PasswordResetCodesPage() {
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className="font-mono text-sm text-muted-foreground">{code.id}</TableCell>
|
||||
<TableCell>
|
||||
<Link
|
||||
href={`/admin/users/${code.user_id}`}
|
||||
|
||||
@@ -143,11 +143,13 @@ export default function PromotionsPage() {
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead>ID (DB)</TableHead>
|
||||
<TableHead>Promotion ID</TableHead>
|
||||
<TableHead>Title</TableHead>
|
||||
<TableHead>Target</TableHead>
|
||||
<TableHead>Date Range</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
<TableHead>Created</TableHead>
|
||||
<TableHead className="w-24">Actions</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
@@ -159,6 +161,7 @@ export default function PromotionsPage() {
|
||||
) : (
|
||||
data?.data?.map((promo) => (
|
||||
<TableRow key={promo.id}>
|
||||
<TableCell className="font-mono text-sm text-muted-foreground">{promo.id}</TableCell>
|
||||
<TableCell><code className="text-xs bg-muted px-2 py-1 rounded">{promo.promotion_id}</code></TableCell>
|
||||
<TableCell className="font-medium">{promo.title}</TableCell>
|
||||
<TableCell>
|
||||
@@ -178,6 +181,9 @@ export default function PromotionsPage() {
|
||||
<Badge variant="destructive">Inactive</Badge>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{new Date(promo.created_at).toLocaleDateString()}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex gap-1">
|
||||
<Button variant="ghost" size="icon" onClick={() => handleEdit(promo)}>
|
||||
|
||||
@@ -32,6 +32,15 @@ import {
|
||||
import { toast } from 'sonner';
|
||||
|
||||
const columns: ColumnDef<Residence>[] = [
|
||||
{
|
||||
accessorKey: 'id',
|
||||
header: 'ID',
|
||||
cell: ({ row }) => (
|
||||
<span className="font-mono text-sm text-muted-foreground">
|
||||
{row.original.id}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: 'Name',
|
||||
|
||||
@@ -190,6 +190,7 @@ export default function ShareCodesPage() {
|
||||
onCheckedChange={handleSelectAll}
|
||||
/>
|
||||
</TableHead>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead>Code</TableHead>
|
||||
<TableHead>Residence</TableHead>
|
||||
<TableHead>Created By</TableHead>
|
||||
@@ -223,6 +224,7 @@ export default function ShareCodesPage() {
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className="font-mono text-sm text-muted-foreground">{code.id}</TableCell>
|
||||
<TableCell>
|
||||
<code className="text-sm bg-muted px-2 py-1 rounded font-mono">
|
||||
{code.code}
|
||||
|
||||
@@ -26,6 +26,15 @@ const tierColors: Record<string, 'default' | 'secondary' | 'outline'> = {
|
||||
};
|
||||
|
||||
const columns: ColumnDef<Subscription>[] = [
|
||||
{
|
||||
accessorKey: 'id',
|
||||
header: 'ID',
|
||||
cell: ({ row }) => (
|
||||
<span className="font-mono text-sm text-muted-foreground">
|
||||
{row.original.id}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: 'username',
|
||||
header: 'User',
|
||||
|
||||
@@ -239,12 +239,14 @@ export default function TaskTemplatesPage() {
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead className="w-16">Order</TableHead>
|
||||
<TableHead>Title</TableHead>
|
||||
<TableHead>Category</TableHead>
|
||||
<TableHead>Frequency</TableHead>
|
||||
<TableHead>iOS Icon</TableHead>
|
||||
<TableHead>Active</TableHead>
|
||||
<TableHead>Created</TableHead>
|
||||
<TableHead className="w-32">Actions</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
@@ -256,6 +258,7 @@ export default function TaskTemplatesPage() {
|
||||
) : (
|
||||
data?.data?.map((template) => (
|
||||
<TableRow key={template.id}>
|
||||
<TableCell className="font-mono text-sm text-muted-foreground">{template.id}</TableCell>
|
||||
<TableCell className="text-muted-foreground">{template.display_order}</TableCell>
|
||||
<TableCell className="font-medium max-w-xs">
|
||||
<div className="truncate">{template.title}</div>
|
||||
@@ -275,6 +278,9 @@ export default function TaskTemplatesPage() {
|
||||
{template.is_active ? 'Active' : 'Inactive'}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{new Date(template.created_at).toLocaleDateString()}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex gap-1">
|
||||
<Button
|
||||
|
||||
@@ -31,6 +31,15 @@ import {
|
||||
import { toast } from 'sonner';
|
||||
|
||||
const columns: ColumnDef<Task>[] = [
|
||||
{
|
||||
accessorKey: 'id',
|
||||
header: 'ID',
|
||||
cell: ({ row }) => (
|
||||
<span className="font-mono text-sm text-muted-foreground">
|
||||
{row.original.id}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: 'title',
|
||||
header: 'Title',
|
||||
@@ -81,6 +90,11 @@ const columns: ColumnDef<Task>[] = [
|
||||
return <Badge variant="default">Active</Badge>;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'created_at',
|
||||
header: 'Created',
|
||||
cell: ({ row }) => new Date(row.original.created_at).toLocaleDateString(),
|
||||
},
|
||||
{
|
||||
id: 'actions',
|
||||
cell: ({ row }) => {
|
||||
|
||||
@@ -170,6 +170,7 @@ export default function UserProfilesPage() {
|
||||
onCheckedChange={handleSelectAll}
|
||||
/>
|
||||
</TableHead>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead>User</TableHead>
|
||||
<TableHead>Email</TableHead>
|
||||
<TableHead>Phone</TableHead>
|
||||
@@ -202,6 +203,7 @@ export default function UserProfilesPage() {
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className="font-mono text-sm text-muted-foreground">{profile.id}</TableCell>
|
||||
<TableCell>
|
||||
<Link
|
||||
href={`/admin/users/${profile.user_id}`}
|
||||
|
||||
@@ -32,6 +32,15 @@ import {
|
||||
import { toast } from 'sonner';
|
||||
|
||||
const columns: ColumnDef<User>[] = [
|
||||
{
|
||||
accessorKey: 'id',
|
||||
header: 'ID',
|
||||
cell: ({ row }) => (
|
||||
<span className="font-mono text-sm text-muted-foreground">
|
||||
{row.original.id}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: 'username',
|
||||
header: 'Username',
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
import {
|
||||
ColumnDef,
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
useReactTable,
|
||||
RowSelectionState,
|
||||
SortingState,
|
||||
} from '@tanstack/react-table';
|
||||
import { ArrowUpDown, ArrowUp, ArrowDown } from 'lucide-react';
|
||||
|
||||
import {
|
||||
Table,
|
||||
@@ -17,6 +20,7 @@ import {
|
||||
TableRow,
|
||||
} from '@/components/ui/table';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { DataTablePagination } from './data-table-pagination';
|
||||
import { DataTableToolbar } from './data-table-toolbar';
|
||||
|
||||
@@ -52,6 +56,37 @@ export function DataTable<TData, TValue>({
|
||||
onRowSelectionChange,
|
||||
}: DataTableProps<TData, TValue>) {
|
||||
const [rowSelection, setRowSelection] = React.useState<RowSelectionState>({});
|
||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||
|
||||
// Sort data client-side based on sorting state
|
||||
const sortedData = React.useMemo(() => {
|
||||
if (sorting.length === 0) return data;
|
||||
|
||||
const [sort] = sorting;
|
||||
const { id, desc } = sort;
|
||||
|
||||
return [...data].sort((a, b) => {
|
||||
const aValue = (a as Record<string, unknown>)[id];
|
||||
const bValue = (b as Record<string, unknown>)[id];
|
||||
|
||||
// Handle null/undefined
|
||||
if (aValue == null && bValue == null) return 0;
|
||||
if (aValue == null) return desc ? -1 : 1;
|
||||
if (bValue == null) return desc ? 1 : -1;
|
||||
|
||||
// Compare values
|
||||
if (typeof aValue === 'number' && typeof bValue === 'number') {
|
||||
return desc ? bValue - aValue : aValue - bValue;
|
||||
}
|
||||
|
||||
// String comparison
|
||||
const aStr = String(aValue).toLowerCase();
|
||||
const bStr = String(bValue).toLowerCase();
|
||||
if (aStr < bStr) return desc ? 1 : -1;
|
||||
if (aStr > bStr) return desc ? -1 : 1;
|
||||
return 0;
|
||||
});
|
||||
}, [data, sorting]);
|
||||
|
||||
// Add selection column if enabled
|
||||
const tableColumns = React.useMemo(() => {
|
||||
@@ -84,19 +119,22 @@ export function DataTable<TData, TValue>({
|
||||
}, [columns, enableRowSelection]);
|
||||
|
||||
const table = useReactTable({
|
||||
data,
|
||||
data: sortedData,
|
||||
columns: tableColumns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
manualPagination: true,
|
||||
manualSorting: true,
|
||||
pageCount: Math.ceil(totalCount / pageSize),
|
||||
state: {
|
||||
rowSelection,
|
||||
sorting,
|
||||
pagination: {
|
||||
pageIndex: page - 1,
|
||||
pageSize,
|
||||
},
|
||||
},
|
||||
onRowSelectionChange: setRowSelection,
|
||||
onSortingChange: setSorting,
|
||||
enableRowSelection,
|
||||
});
|
||||
|
||||
@@ -127,12 +165,31 @@ export function DataTable<TData, TValue>({
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
{header.isPlaceholder ? null : header.column.getCanSort() ? (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="-ml-3 h-8 data-[state=open]:bg-accent"
|
||||
onClick={() => header.column.toggleSorting()}
|
||||
>
|
||||
{flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
{header.column.getIsSorted() === 'asc' ? (
|
||||
<ArrowUp className="ml-2 h-4 w-4" />
|
||||
) : header.column.getIsSorted() === 'desc' ? (
|
||||
<ArrowDown className="ml-2 h-4 w-4" />
|
||||
) : (
|
||||
<ArrowUpDown className="ml-2 h-4 w-4 opacity-50" />
|
||||
)}
|
||||
</Button>
|
||||
) : (
|
||||
flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)
|
||||
)}
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
@@ -188,5 +245,3 @@ export function DataTable<TData, TValue>({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
import * as React from 'react';
|
||||
|
||||
Reference in New Issue
Block a user