| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- "use client";
- import React, { useState } from "react";
- import {
- ColumnDef,
- flexRender,
- getCoreRowModel,
- getPaginationRowModel,
- getSortedRowModel,
- useReactTable,
- SortingState,
- } from "@tanstack/react-table";
- import { Button } from "@/components/ui/button";
- import {
- Table,
- TableBody,
- TableCell,
- TableHead,
- TableHeader,
- TableRow,
- } from "@/components/ui/table";
- import { Badge } from "@/components/ui/badge";
- import { format } from "date-fns";
- import { FileText, Edit, Trash2, Calendar, ChevronLeft, ChevronRight } from "lucide-react";
- interface Import {
- id: number;
- name: string;
- importDate: string;
- layoutId: number;
- layout: {
- id: number;
- name: string;
- };
- }
- interface ImportsTableProps {
- data: Import[];
- onView: (importRecord: Import) => void;
- onEdit: (importRecord: Import) => void;
- onDelete: (id: number) => void;
- }
- export function ImportsTable({ data, onView, onEdit, onDelete }: ImportsTableProps) {
- const [sorting, setSorting] = useState<SortingState>([
- { id: "importDate", desc: true },
- ]);
- const columns: ColumnDef<Import>[] = [
- {
- accessorKey: "name",
- header: "Name",
- cell: ({ row }) => (
- <div className="font-medium">{row.getValue("name")}</div>
- ),
- },
- {
- accessorKey: "layout.name",
- header: "Layout",
- cell: ({ row }) => (
- <Badge variant="outline" className="dark:border-gray-600 dark:text-gray-300">
- {row.original.layout.name}
- </Badge>
- ),
- },
- {
- accessorKey: "importDate",
- header: "Import Date",
- cell: ({ row }) => {
- const date = new Date(row.getValue("importDate"));
- return (
- <div className="flex items-center text-sm text-muted-foreground">
- <Calendar className="mr-2 h-3 w-3" />
- {format(date, "MMM d, yyyy HH:mm")}
- </div>
- );
- },
- },
- {
- id: "actions",
- header: "Actions",
- cell: ({ row }) => (
- <div className="flex gap-2">
- <Button
- variant="ghost"
- size="sm"
- onClick={() => onView(row.original)}
- title="View details"
- >
- <FileText className="h-4 w-4" />
- </Button>
- <Button
- variant="ghost"
- size="sm"
- onClick={() => onEdit(row.original)}
- title="Edit import"
- >
- <Edit className="h-4 w-4" />
- </Button>
- <Button
- variant="ghost"
- size="sm"
- onClick={() => onDelete(row.original.id)}
- title="Delete import"
- className="text-destructive hover:text-destructive"
- >
- <Trash2 className="h-4 w-4" />
- </Button>
- </div>
- ),
- enableSorting: false,
- },
- ];
- const table = useReactTable({
- data,
- columns,
- state: {
- sorting,
- },
- onSortingChange: setSorting,
- getCoreRowModel: getCoreRowModel(),
- getPaginationRowModel: getPaginationRowModel(),
- getSortedRowModel: getSortedRowModel(),
- initialState: {
- pagination: {
- pageSize: 10,
- },
- },
- });
- return (
- <div className="space-y-4">
- <div className="rounded-md border bg-white dark:bg-gray-800 dark:border-gray-700">
- <Table>
- <TableHeader>
- {table.getHeaderGroups().map((headerGroup) => (
- <TableRow key={headerGroup.id} className="dark:border-gray-700">
- {headerGroup.headers.map((header) => (
- <TableHead
- key={header.id}
- onClick={header.column.getToggleSortingHandler()}
- className={header.column.getCanSort() ? "cursor-pointer select-none" : ""}
- >
- <div className="flex items-center gap-1">
- {flexRender(
- header.column.columnDef.header,
- header.getContext()
- )}
- {header.column.getIsSorted() && (
- <span>
- {header.column.getIsSorted() === "asc" ? "↑" : "↓"}
- </span>
- )}
- </div>
- </TableHead>
- ))}
- </TableRow>
- ))}
- </TableHeader>
- <TableBody>
- {table.getRowModel().rows?.length ? (
- table.getRowModel().rows.map((row) => (
- <TableRow
- key={row.id}
- data-state={row.getIsSelected() && "selected"}
- className="dark:border-gray-700"
- >
- {row.getVisibleCells().map((cell) => (
- <TableCell key={cell.id}>
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
- </TableCell>
- ))}
- </TableRow>
- ))
- ) : (
- <TableRow>
- <TableCell colSpan={columns.length} className="h-24 text-center">
- No results.
- </TableCell>
- </TableRow>
- )}
- </TableBody>
- </Table>
- </div>
- <div className="flex items-center justify-between">
- <div className="text-sm text-muted-foreground">
- Showing {table.getRowModel().rows.length} of {data.length} imports
- </div>
- <div className="flex items-center space-x-2">
- <Button
- variant="outline"
- size="sm"
- onClick={() => table.previousPage()}
- disabled={!table.getCanPreviousPage()}
- >
- <ChevronLeft className="h-4 w-4 mr-1" />
- Previous
- </Button>
- <div className="text-sm font-medium">
- Page {table.getState().pagination.pageIndex + 1} of{" "}
- {table.getPageCount()}
- </div>
- <Button
- variant="outline"
- size="sm"
- onClick={() => table.nextPage()}
- disabled={!table.getCanNextPage()}
- >
- Next
- <ChevronRight className="h-4 w-4 ml-1" />
- </Button>
- </div>
- </div>
- </div>
- );
- }
|