33 lines
1.0 KiB
TypeScript
33 lines
1.0 KiB
TypeScript
import {useListSearch} from "@/hooks/useListSearch";
|
|
import usePagination from "@/hooks/usePagination";
|
|
import { clsx } from "clsx";
|
|
import {ReactNode} from "react";
|
|
|
|
interface Props<T> {
|
|
list: T[];
|
|
searchFields: string[][];
|
|
pageSize?: number;
|
|
firstCard?: () => ReactNode;
|
|
renderCard: (item: T) => ReactNode;
|
|
className?: string
|
|
}
|
|
|
|
export default function CardList<T>({list, searchFields, renderCard, firstCard, className, pageSize = 20}: Props<T>) {
|
|
const {rows, renderSearch} = useListSearch(searchFields, list);
|
|
|
|
const {items, page, render, renderMinimal} = usePagination(rows, pageSize);
|
|
|
|
return (
|
|
<section className="flex flex-col gap-4 w-full">
|
|
<div className="w-full flex items-center gap-4">
|
|
{searchFields.length > 0 && renderSearch()}
|
|
{searchFields.length > 0 ? renderMinimal() : render()}
|
|
</div>
|
|
<div className={clsx("w-full h-full grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4", className)}>
|
|
{page === 0 && !!firstCard && firstCard()}
|
|
{items.map(renderCard)}
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|