MIF_E31221222/sigap-website/components/admin/users/data-table.tsx

201 lines
7.5 KiB
TypeScript

"use client"
import { useState } from "react"
import {
type ColumnFiltersState,
type SortingState,
type VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { ChevronDown, RefreshCw } from "lucide-react"
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
interface DataTableProps<TData, TValue> {
columns: any[]
data: TData[]
onRowClick?: (row: TData) => void
}
export function DataTable<TData, TValue>({ columns, data, onRowClick }: DataTableProps<TData, TValue>) {
const [sorting, setSorting] = useState<SortingState>([])
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})
const [rowSelection, setRowSelection] = useState({})
const table = useReactTable({
data,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
},
})
return (
<div className="w-full">
<div className="flex items-center justify-between py-4 bg-[#1c1c1c] px-4 border-b border-[#2a2a2a]">
<div className="flex items-center gap-2">
<Input
placeholder="Search email, phone or UID"
value={(table.getColumn("email")?.getFilterValue() as string) ?? ""}
onChange={(event) => table.getColumn("email")?.setFilterValue(event.target.value)}
className="max-w-sm bg-[#121212] border-[#2a2a2a] text-white"
/>
<Select defaultValue="all">
<SelectTrigger className="w-[180px] bg-[#121212] border-[#2a2a2a] text-white">
<SelectValue placeholder="All users" />
</SelectTrigger>
<SelectContent className="bg-[#121212] border-[#2a2a2a] text-white">
<SelectItem value="all">All users</SelectItem>
<SelectItem value="admin">Admins</SelectItem>
<SelectItem value="user">Users</SelectItem>
</SelectContent>
</Select>
<Select defaultValue="all">
<SelectTrigger className="w-[180px] bg-[#121212] border-[#2a2a2a] text-white">
<SelectValue placeholder="Provider" />
</SelectTrigger>
<SelectContent className="bg-[#121212] border-[#2a2a2a] text-white">
<SelectItem value="all">All providers</SelectItem>
<SelectItem value="email">Email</SelectItem>
<SelectItem value="google">Google</SelectItem>
</SelectContent>
</Select>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" className="bg-[#121212] border-[#2a2a2a] text-white">
All columns <ChevronDown className="ml-2 h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="bg-[#121212] border-[#2a2a2a] text-white">
{table
.getAllColumns()
.filter((column) => column.getCanHide())
.map((column) => {
return (
<DropdownMenuCheckboxItem
key={column.id}
className="capitalize"
checked={column.getIsVisible()}
onCheckedChange={(value) => column.toggleVisibility(!!value)}
>
{column.id}
</DropdownMenuCheckboxItem>
)
})}
</DropdownMenuContent>
</DropdownMenu>
<Button variant="outline" className="bg-[#121212] border-[#2a2a2a] text-white">
Sorted by created at <ChevronDown className="ml-2 h-4 w-4" />
</Button>
</div>
<div className="flex items-center gap-2">
<Button variant="outline" size="icon" className="bg-[#121212] border-[#2a2a2a] text-white">
<RefreshCw className="h-4 w-4" />
</Button>
<Button className="bg-emerald-600 hover:bg-emerald-700 text-white">
Add user <ChevronDown className="ml-2 h-4 w-4" />
</Button>
</div>
</div>
<div className="rounded-md border-0">
<Table className="bg-[#121212] text-white">
<TableHeader className="bg-[#1c1c1c]">
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id} className="border-[#2a2a2a] hover:bg-[#1c1c1c]">
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id} className="text-gray-400">
{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
</TableHead>
)
})}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && "selected"}
className="cursor-pointer border-[#2a2a2a] hover:bg-[#1c1c1c]"
onClick={() => onRowClick && onRowClick(row.original)}
>
{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-end space-x-2 py-4 px-4 bg-[#121212] text-white">
<div className="flex-1 text-sm text-gray-400">
{table.getFilteredSelectedRowModel().rows.length} of {table.getFilteredRowModel().rows.length} row(s)
selected.
</div>
<div className="space-x-2">
<Button
variant="outline"
size="sm"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
className="bg-[#1c1c1c] border-[#2a2a2a] text-white hover:bg-[#2a2a2a]"
>
Previous
</Button>
<Button
variant="outline"
size="sm"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
className="bg-[#1c1c1c] border-[#2a2a2a] text-white hover:bg-[#2a2a2a]"
>
Next
</Button>
</div>
</div>
</div>
)
}