+ Paginated Table Search

This commit is contained in:
Nicolas
2025-02-17 01:41:46 +01:00
parent b8357d1d06
commit 6c67a11cab
4 changed files with 112 additions and 52 deletions

View File

@@ -1,37 +1,76 @@
'use client';
import { useEffect, useState } from 'react';
import SortableTable, { Pagination, SortableTableProps } from './Table';
import { PrismaClient } from '@repo/db';
import { getData } from './pagiantedTableActions';
"use client";
import { useEffect, useState, useCallback } from "react";
import SortableTable, { Pagination, SortableTableProps } from "./Table";
import { PrismaClient } from "@repo/db";
import { getData } from "./pagiantedTableActions";
interface PaginatedTableProps<TData>
extends Omit<SortableTableProps<TData>, 'data'> {
extends Omit<SortableTableProps<TData>, "data"> {
prismaModel: keyof PrismaClient;
rowsPerPage?: number;
showEditButton?: boolean;
searchFields: string[];
}
export function PaginatedTable<TData>({
prismaModel,
rowsPerPage = 10,
showEditButton = false,
searchFields,
...restProps
}: PaginatedTableProps<TData>) {
const [data, setData] = useState<TData[]>([]);
const [page, setPage] = useState(0);
const [total, setTotal] = useState(0);
const [searchTerm, setSearchTerm] = useState("");
const [debouncedSearchTerm, setDebouncedSearchTerm] = useState(searchTerm);
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(() => {
getData(prismaModel, rowsPerPage, page * rowsPerPage).then((result) => {
getData(
prismaModel,
rowsPerPage,
page * rowsPerPage,
debouncedSearchTerm,
searchFields
).then((result) => {
if (result) {
setData(result.data);
setTotal(result.total);
}
});
}, [page]);
}, [page, debouncedSearchTerm]);
return (
<div className="space-y-4">
<div className="space-y-4 m-4">
{searchFields.length > 0 && (
<div className="flex justify-end">
<input
type="text"
placeholder="Suchen..."
value={searchTerm}
onChange={(e) => {
setSearchTerm(e.target.value);
handleSearchChange(e.target.value);
}}
className="input input-bordered w-full max-w-xs justify-end"
/>
</div>
)}
<SortableTable
data={data}
prismaModel={prismaModel}