1
- " use client" ;
1
+ ' use client' ;
2
2
3
3
import {
4
4
ColumnDef ,
5
5
ColumnFiltersState ,
6
6
flexRender ,
7
7
getCoreRowModel ,
8
+ getSortedRowModel ,
9
+ SortingState ,
8
10
getPaginationRowModel ,
9
11
getFilteredRowModel ,
10
12
useReactTable ,
11
- } from "@tanstack/react-table" ;
12
- import { Button } from "@/components/ui/button" ;
13
- import { Input } from "@/components/ui/input" ;
14
- import {
15
- Table ,
16
- TableBody ,
17
- TableCell ,
18
- TableHead ,
19
- TableHeader ,
20
- TableRow ,
21
- } from "@/components/ui/table" ;
22
- import { useState } from "react" ;
13
+ VisibilityState ,
14
+ } from '@tanstack/react-table' ;
15
+ import { Button } from '@/components/ui/button' ;
16
+ import { Input } from '@/components/ui/input' ;
17
+ import { Table , TableBody , TableCell , TableHead , TableHeader , TableRow } from '@/components/ui/table' ;
18
+ import { useState } from 'react' ;
19
+ import { ChevronDown , Search } from 'lucide-react' ;
20
+ import { DataTablePagination } from './data-table-pagination' ;
23
21
22
+ import {
23
+ DropdownMenu ,
24
+ DropdownMenuCheckboxItem ,
25
+ DropdownMenuContent ,
26
+ DropdownMenuTrigger ,
27
+ } from '@/components/ui/dropdown-menu' ;
24
28
interface DataTableProps < TData , TValue > {
25
29
columns : ColumnDef < TData , TValue > [ ] ;
26
30
data : TData [ ] ;
27
31
searchKey : string ;
28
32
}
29
33
30
- export function DataTable < TData , TValue > ( {
31
- columns,
32
- data,
33
- searchKey,
34
- } : DataTableProps < TData , TValue > ) {
34
+ export function DataTable < TData , TValue > ( { columns, data, searchKey } : DataTableProps < TData , TValue > ) {
35
35
const [ columnFilters , setColumnFilters ] = useState < ColumnFiltersState > ( [ ] ) ;
36
+ const [ sorting , setSorting ] = useState < SortingState > ( [ ] ) ;
37
+ const [ columnVisibility , setColumnVisibility ] = useState < VisibilityState > ( { } ) ;
38
+
36
39
const table = useReactTable ( {
37
40
data,
38
41
columns,
42
+ onSortingChange : setSorting ,
39
43
getCoreRowModel : getCoreRowModel ( ) ,
40
44
getPaginationRowModel : getPaginationRowModel ( ) ,
41
45
onColumnFiltersChange : setColumnFilters ,
46
+ onColumnVisibilityChange : setColumnVisibility ,
47
+ getSortedRowModel : getSortedRowModel ( ) ,
42
48
getFilteredRowModel : getFilteredRowModel ( ) ,
43
49
44
50
state : {
45
51
columnFilters,
52
+ sorting,
53
+ columnVisibility,
46
54
} ,
47
55
} ) ;
48
56
49
57
return (
50
58
< div >
51
59
< div className = "flex items-center py-4" >
52
- < Input
53
- placeholder = "Search ..."
54
- value = { ( table . getColumn ( searchKey ) ?. getFilterValue ( ) as string ) ?? "" }
55
- onChange = { event =>
56
- table . getColumn ( searchKey ) ?. setFilterValue ( event . target . value )
57
- }
58
- className = "max-w-sm"
59
- />
60
+ < div className = "relative max-w-sm" >
61
+ < Search className = "absolute left-3 top-[0.8rem] text-gray-400" size = { 20 } />
62
+ < Input
63
+ placeholder = "Order ID or transaction ID..."
64
+ value = { ( table . getColumn ( searchKey ) ?. getFilterValue ( ) as string ) ?? '' }
65
+ onChange = { ( event ) => table . getColumn ( searchKey ) ?. setFilterValue ( event . target . value ) }
66
+ className = "pl-10"
67
+ />
68
+ </ div >
69
+ < DropdownMenu >
70
+ < DropdownMenuTrigger asChild >
71
+ < Button variant = "outline" className = "ml-auto" >
72
+ < span className = "" > Filter Column</ span >
73
+ < ChevronDown className = "h-4 w-4" />
74
+ </ Button >
75
+ </ DropdownMenuTrigger >
76
+ < DropdownMenuContent align = "end" >
77
+ { table
78
+ . getAllColumns ( )
79
+ . filter ( ( column ) => column . getCanHide ( ) )
80
+ . map ( ( column ) => {
81
+ return (
82
+ < DropdownMenuCheckboxItem
83
+ key = { column . id }
84
+ className = "capitalize"
85
+ checked = { column . getIsVisible ( ) }
86
+ onCheckedChange = { ( value ) => column . toggleVisibility ( ! ! value ) }
87
+ >
88
+ { column . id }
89
+ </ DropdownMenuCheckboxItem >
90
+ ) ;
91
+ } ) }
92
+ </ DropdownMenuContent >
93
+ </ DropdownMenu >
60
94
</ div >
61
95
< div className = "rounded-md border" >
62
96
< Table >
63
- < TableHeader >
64
- { table . getHeaderGroups ( ) . map ( headerGroup => (
97
+ < TableHeader className = "bg-slate-100" >
98
+ { table . getHeaderGroups ( ) . map ( ( headerGroup ) => (
65
99
< TableRow key = { headerGroup . id } >
66
- { headerGroup . headers . map ( header => {
100
+ { headerGroup . headers . map ( ( header ) => {
67
101
return (
68
102
< TableHead key = { header . id } >
69
- { header . isPlaceholder
70
- ? null
71
- : flexRender (
72
- header . column . columnDef . header ,
73
- header . getContext ( ) ,
74
- ) }
103
+ { header . isPlaceholder ? null : flexRender ( header . column . columnDef . header , header . getContext ( ) ) }
75
104
</ TableHead >
76
105
) ;
77
106
} ) }
@@ -80,52 +109,24 @@ export function DataTable<TData, TValue>({
80
109
</ TableHeader >
81
110
< TableBody >
82
111
{ table . getRowModel ( ) . rows ?. length ? (
83
- table . getRowModel ( ) . rows . map ( row => (
84
- < TableRow
85
- key = { row . id }
86
- data-state = { row . getIsSelected ( ) && "selected" }
87
- >
88
- { row . getVisibleCells ( ) . map ( cell => (
89
- < TableCell key = { cell . id } >
90
- { flexRender (
91
- cell . column . columnDef . cell ,
92
- cell . getContext ( ) ,
93
- ) }
94
- </ TableCell >
112
+ table . getRowModel ( ) . rows . map ( ( row ) => (
113
+ < TableRow key = { row . id } data-state = { row . getIsSelected ( ) && 'selected' } >
114
+ { row . getVisibleCells ( ) . map ( ( cell ) => (
115
+ < TableCell key = { cell . id } > { flexRender ( cell . column . columnDef . cell , cell . getContext ( ) ) } </ TableCell >
95
116
) ) }
96
117
</ TableRow >
97
118
) )
98
119
) : (
99
120
< TableRow >
100
- < TableCell
101
- colSpan = { columns . length }
102
- className = "h-24 text-center"
103
- >
121
+ < TableCell colSpan = { columns . length } className = "h-24 text-center" >
104
122
No results.
105
123
</ TableCell >
106
124
</ TableRow >
107
125
) }
108
126
</ TableBody >
109
127
</ Table >
110
128
</ div >
111
- < div className = "flex items-center justify-end space-x-2 py-4" >
112
- < Button
113
- variant = "outline"
114
- size = "sm"
115
- onClick = { ( ) => table . previousPage ( ) }
116
- disabled = { ! table . getCanPreviousPage ( ) }
117
- >
118
- Previous
119
- </ Button >
120
- < Button
121
- variant = "outline"
122
- size = "sm"
123
- onClick = { ( ) => table . nextPage ( ) }
124
- disabled = { ! table . getCanNextPage ( ) }
125
- >
126
- Next
127
- </ Button >
128
- </ div >
129
+ < DataTablePagination table = { table } />
129
130
</ div >
130
131
) ;
131
132
}
0 commit comments