Files
frontend/apps/as/src/shared/lib/use-data-table.tsx
T
2026-10-06 14:32:26 +09:00

61 lines
1.9 KiB
TypeScript

"use client";
import type { HTMLAttributes } from "react";
import type { UseQueryResult } from "@tanstack/react-query";
import { type TableOptions, useReactTable } from "@tanstack/react-table";
import type { PageResponse } from "@/shared/model";
import { NoData } from "@/shared/ui/no-data";
import { DataTable, Skeleton } from "@common/components";
import { matchQueryStatus } from "./match-query-status";
interface DataTableOptions<T> {
variant?: "default" | "secondary" | "line";
className?: HTMLAttributes<HTMLTableElement>["className"];
caption?: string;
viewPagination?: boolean;
onRowClick?: (row: T) => void;
}
interface UseDataTableOptions<T> {
/** 페이징 응답(PageResponse) 또는 페이징 없는 목록(T[]) */
query: UseQueryResult<PageResponse<T> | T[]>;
tableOptions: Omit<TableOptions<T>, "data" | "rowCount">;
dataTableOptions?: DataTableOptions<T>;
}
const EMPTY_ROWS: never[] = [];
export function useDataTable<T>({ query, tableOptions, dataTableOptions }: UseDataTableOptions<T>) {
const { data } = query;
const rows = Array.isArray(data) ? data : (data?.content ?? EMPTY_ROWS);
const rowCount = Array.isArray(data) ? data.length : (data?.totalElements ?? 0);
const table = useReactTable({
...tableOptions,
data: rows,
rowCount,
});
return {
tableComponent: matchQueryStatus(query, {
Pending: (
<div className="flex flex-col gap-2">
<Skeleton className="h-[4rem]" />
<Skeleton className="h-[16rem]" />
</div>
),
Empty: <NoData />,
Error: (
<p className="py-6 text-center text-lg text-muted-foreground">
데이터를 불러오는 중 오류가 발생했습니다.
</p>
),
Success: () => <DataTable table={table} {...dataTableOptions} />,
}),
tableInstance: table,
};
}