11"use client" ;
22
3- import { useState , useMemo } from "react" ;
3+ import { useState , useEffect } from "react" ;
44import { useReactTable , getCoreRowModel , flexRender , ColumnDef } from "@tanstack/react-table" ;
55import { Table , TableBody , TableCell , TableHead , TableHeader , TableRow } from "@/components/ui/Table" ;
66import { TablePagination } from "./TablePagination" ;
77import { TableToolbar } from "./TableToolbar" ;
8+ import { Select , SelectContent , SelectItem , SelectTrigger , SelectValue } from "@/components/ui/Select" ;
9+ import { usePagination , useDebounced , useQueryParams } from "@/hooks" ;
810
911interface TableDataProps < T > {
1012 data : T [ ] ;
@@ -14,6 +16,9 @@ interface TableDataProps<T> {
1416 itemsPerPage ?: number ;
1517 className ?: string ;
1618 rightAction ?: React . ReactNode ;
19+ currentPage ?: number ;
20+ totalPages ?: number ;
21+ onSearchChange ?: ( search : string ) => void ;
1722}
1823
1924function TableData < T > ( {
@@ -24,29 +29,28 @@ function TableData<T>({
2429 itemsPerPage = 5 ,
2530 className,
2631 rightAction,
32+ currentPage = 1 ,
33+ totalPages = 1 ,
34+ onSearchChange,
2735} : TableDataProps < T > ) {
28- const [ globalFilter , setGlobalFilter ] = useState ( "" ) ;
29- const [ currentPage , setCurrentPage ] = useState ( 1 ) ;
36+ const { getParam, setParams } = useQueryParams ( ) ;
37+ const [ searchValue , setSearchValue ] = useState ( getParam ( "search" , "" ) ) ;
38+ const debouncedSearchValue = useDebounced ( searchValue , 500 ) ;
39+ const { handleItemsPerPageChange } = usePagination ( { currentPage, totalPages, itemsPerPage } ) ;
3040
31- const filteredData = useMemo ( ( ) => {
32- if ( ! searchable || ! globalFilter ) return data ;
41+ useEffect ( ( ) => {
42+ setParams ( {
43+ search : debouncedSearchValue || null ,
44+ page : debouncedSearchValue ? 1 : currentPage ,
45+ } ) ;
3346
34- return data . filter ( ( item : T ) =>
35- Object . values ( item as Record < string , unknown > ) . some ( ( value ) =>
36- value ?. toString ( ) . toLowerCase ( ) . includes ( globalFilter . toLowerCase ( ) )
37- )
38- ) ;
39- } , [ data , globalFilter , searchable ] ) ;
40-
41- const totalPages = Math . ceil ( filteredData . length / itemsPerPage ) ;
42-
43- const paginatedData = useMemo ( ( ) => {
44- const startIndex = ( currentPage - 1 ) * itemsPerPage ;
45- return filteredData . slice ( startIndex , startIndex + itemsPerPage ) ;
46- } , [ filteredData , currentPage , itemsPerPage ] ) ;
47+ if ( onSearchChange ) {
48+ onSearchChange ( debouncedSearchValue ) ;
49+ }
50+ } , [ debouncedSearchValue , onSearchChange , currentPage ] ) ;
4751
4852 const table = useReactTable ( {
49- data : paginatedData ,
53+ data,
5054 columns,
5155 getCoreRowModel : getCoreRowModel ( ) ,
5256 manualPagination : true ,
@@ -57,10 +61,9 @@ function TableData<T>({
5761 < TableToolbar
5862 searchable = { searchable }
5963 searchPlaceholder = { searchPlaceholder }
60- searchValue = { globalFilter }
64+ searchValue = { searchValue }
6165 onSearchChange = { ( value ) => {
62- setGlobalFilter ( value ) ;
63- setCurrentPage ( 1 ) ;
66+ setSearchValue ( value ) ;
6467 } }
6568 rightAction = { rightAction }
6669 />
@@ -100,11 +103,33 @@ function TableData<T>({
100103
101104 { totalPages > 1 && (
102105 < div className = "flex items-center justify-between" >
103- < div className = "text-muted-foreground text-sm" >
104- { currentPage } of { totalPages } pages
106+ < div className = "flex items-center gap-4" >
107+ < div className = "text-muted-foreground text-sm" >
108+ { currentPage } of { totalPages } pages
109+ </ div >
110+ < div className = "flex items-center gap-2" >
111+ < span className = "text-muted-foreground text-sm" > Items per page:</ span >
112+ < Select
113+ value = { itemsPerPage . toString ( ) }
114+ onValueChange = { ( value ) => {
115+ const newItemsPerPage = parseInt ( value , 10 ) ;
116+ handleItemsPerPageChange ( newItemsPerPage ) ;
117+ } }
118+ >
119+ < SelectTrigger className = "w-16" >
120+ < SelectValue />
121+ </ SelectTrigger >
122+ < SelectContent >
123+ < SelectItem value = "1" > 1</ SelectItem >
124+ < SelectItem value = "2" > 2</ SelectItem >
125+ < SelectItem value = "5" > 5</ SelectItem >
126+ < SelectItem value = "10" > 10</ SelectItem >
127+ </ SelectContent >
128+ </ Select >
129+ </ div >
105130 </ div >
106131
107- < TablePagination currentPage = { currentPage } totalPages = { totalPages } onPageChange = { setCurrentPage } />
132+ < TablePagination currentPage = { currentPage } totalPages = { totalPages } itemsPerPage = { itemsPerPage } />
108133 </ div >
109134 ) }
110135 </ div >
0 commit comments