完善账单页面,抽取公共页面组件
This commit is contained in:
88
src/components/data-table.tsx
Normal file
88
src/components/data-table.tsx
Normal file
@@ -0,0 +1,88 @@
|
||||
'use client'
|
||||
import {Table as TableRoot, TableBody, TableCell, TableHead, TableHeader, TableRow} from '@/components/ui/table'
|
||||
import {ColumnDef, flexRender, getCoreRowModel, useReactTable} from '@tanstack/react-table'
|
||||
import {Pagination, PaginationProps} from '@/components/ui/pagination'
|
||||
import {Loader} from 'lucide-react'
|
||||
import {merge} from '@/lib/utils'
|
||||
|
||||
export type DataTableProps<T> = {
|
||||
data: T[]
|
||||
status: 'load' | 'done' | 'fail'
|
||||
columns: ColumnDef<T>[]
|
||||
pagination: PaginationProps
|
||||
classNames?: {
|
||||
headRow?: string
|
||||
dataRow?: string
|
||||
}
|
||||
}
|
||||
|
||||
export default function DataTable<T extends Record<string, unknown>>(props: DataTableProps<T>) {
|
||||
|
||||
const table = useReactTable({
|
||||
data: props.data,
|
||||
columns: props.columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
manualPagination: true,
|
||||
rowCount: props.pagination.total,
|
||||
state: {
|
||||
pagination: {
|
||||
pageIndex: props.pagination.page,
|
||||
pageSize: props.pagination.size,
|
||||
},
|
||||
columnFilters: [],
|
||||
},
|
||||
})
|
||||
|
||||
return (<>
|
||||
{/* 数据表*/}
|
||||
<div className={`border rounded-md relative`}>
|
||||
<TableRoot>
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map(group => (
|
||||
<TableRow key={group.id}>
|
||||
{group.headers.map(header => (
|
||||
<TableHead key={header.id} colSpan={header.colSpan}>
|
||||
{header.isPlaceholder ? null : flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext(),
|
||||
)}
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{props.status === 'fail' ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={props.columns.length} className={`text-center text-destructive`}>加载失败</TableCell>
|
||||
</TableRow>
|
||||
) : !props.data?.length ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={props.columns.length} className={`text-center`}>暂无数据</TableCell>
|
||||
</TableRow>
|
||||
) : table.getRowModel().rows.map(row => (
|
||||
<TableRow key={row.id} data-state={row.getIsSelected() && 'selected'} className={merge(props.classNames?.dataRow)}>
|
||||
{row.getVisibleCells().map(cell => (
|
||||
<TableCell key={cell.id}>
|
||||
{flexRender(
|
||||
cell.column.columnDef.cell,
|
||||
cell.getContext(),
|
||||
)}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</TableRoot>
|
||||
{props.status === 'load' && (
|
||||
<div className={`absolute inset-0 bg-white/10 backdrop-blur-xs flex items-center justify-center gap-2 transition`}>
|
||||
<Loader className={`animate-spin`}/>
|
||||
<span>加载中</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 分页器 */}
|
||||
<Pagination {...props.pagination}/>
|
||||
</>)
|
||||
}
|
||||
Reference in New Issue
Block a user