'use client'; import { useEffect, useState, useCallback, Ref, useImperativeHandle, } from 'react'; import SortableTable, { Pagination, SortableTableProps } from './Table'; import { PrismaClient } from '@repo/db'; import { getData } from './pagiantedTableActions'; export interface PaginatedTableRef { refresh: () => void; } interface PaginatedTableProps extends Omit, 'data'> { prismaModel: keyof PrismaClient; filter?: Record; rowsPerPage?: number; showEditButton?: boolean; searchFields?: string[]; include?: Record; leftOfSearch?: React.ReactNode; rightOfSearch?: React.ReactNode; ref?: Ref; } export function PaginatedTable({ prismaModel, rowsPerPage = 10, showEditButton = false, searchFields = [], filter, include, ref, leftOfSearch, rightOfSearch, ...restProps }: PaginatedTableProps) { const [data, setData] = useState([]); const [page, setPage] = useState(0); const [total, setTotal] = useState(0); const [searchTerm, setSearchTerm] = useState(''); const [debouncedSearchTerm, setDebouncedSearchTerm] = useState(searchTerm); const RefreshTableData = async () => { getData( prismaModel, rowsPerPage, page * rowsPerPage, debouncedSearchTerm, searchFields, filter, include ).then((result) => { if (result) { setData(result.data); setTotal(result.total); } }); }; useImperativeHandle(ref, () => ({ refresh: () => { console.log('refresh'); RefreshTableData(); }, })); const debounce = (func: Function, delay: number) => { let timer: NodeJS.Timeout; return (...args: any[]) => { clearTimeout(timer); timer = setTimeout(() => func(...args), delay); }; }; const handleSearchChange = useCallback( debounce((value: string) => { setDebouncedSearchTerm(value); }, 500), [] ); useEffect(() => { RefreshTableData(); }, [page, debouncedSearchTerm]); return (
{searchFields.length > 0 && (
{leftOfSearch}
{ setSearchTerm(e.target.value); handleSearchChange(e.target.value); }} className="input input-bordered w-full max-w-xs justify-end" />
{rightOfSearch}
)}
); }