"use client";
import * as React from "react";
import {
ColumnDef,
ColumnFiltersState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
import { ArrowUpDown, ChevronDown, MoreHorizontal } from "lucide-react";
import { Button, buttonVariants } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Input } from "@/components/ui/input";
import {
Table,
TableBody,
TableCaption,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { ToolSelect, UserToolSelect } from "@/database/schema";
import { Badge } from "@/components/ui/badge";
import Link from "next/link";
import AlertDeleteTools from "./AlertDeleteTools";
import { cn } from "@/lib/utils";
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card";
import { trpc } from "@/app/_trpc/client";
import { DialogUpdateTools } from "./DialogModifyTools";
import { SelectedTool, UserToolsWithUser } from "../types";
import { Tool } from "@/server/tool/domain/models";
import DialogUserTools from "./DialogUserTools";
export type Payment = {
id: string;
amount: number;
status: "pending" | "processing" | "success" | "failed";
email: string;
};
export const columns: ColumnDef<any>[] = [
{
id: "select",
header: ({ table }) => (
<Checkbox
checked={
table.getIsAllPageRowsSelected() ||
(table.getIsSomePageRowsSelected() && "indeterminate")
}
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
aria-label="Select all"
/>
),
cell: ({ row }) => (
<Checkbox
checked={row.getIsSelected()}
onCheckedChange={(value) => row.toggleSelected(!!value)}
aria-label="Select row"
/>
),
enableSorting: false,
enableHiding: false,
},
{
accessorKey: "name",
header: ({ column }) => {
return (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
Nombre
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
},
cell: ({ row }) => <div className="capitalize">{row.getValue("name")}</div>,
},
{
accessorKey: "quantity",
header: ({ column }) => {
return (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
Cantidad
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
},
cell: ({ row }) => (
<div className="lowercase">{row.getValue("quantity")}</div>
),
},
{
accessorKey: "userTool",
header: ({ column }) => {
return (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
Usuarios asignados
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
},
cell: ({ row }) => (
<div className="lowercase px-3 grid grid-cols-[repeat(auto-fill,minmax(50px,1fr))] ">
<HoverCard>
<HoverCardTrigger asChild>
<Button variant="link">
{row?.original?.userTool?.reduce(
(acc:number, tool:ToolSelect) => acc + tool.quantity,
0
)}
</Button>
</HoverCardTrigger>
<HoverCardContent className="w-80">
{row?.original?.userTool?.length > 0 ? (
<Table>
<TableCaption className=" text-xs">
Materiales en projectos activos
</TableCaption>
<TableHeader>
<TableRow>
<TableHead className=" text-xs">Nombre</TableHead>
<TableHead className=" text-xs">Asignados</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{row?.original?.userTool?.map((tool:UserToolsWithUser) => {
return (
<TableRow key={tool?.id}>
<TableCell className="font-medium text-xs">
<Link
className={cn(
buttonVariants({ variant: "link" }),
"text-xs p-0 text-wrap font-normal text-blue-700"
)}
href={`/dashboard/user/${tool?.user?.id}`}
>
{tool?.user?.firstName}
</Link>
</TableCell>
<TableCell className=" text-xs">
{tool?.quantity}
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
) : (
<div className="text-center capitalize ">
Sin usuarios asignados
</div>
)}
</HoverCardContent>
</HoverCard>
</div>
),
},
{
id: "actions",
enableHiding: false,
cell: ({ row }) => {
const payment = row.original;
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="h-8 w-8 p-0">
<span className="sr-only">Open menu</span>
<MoreHorizontal className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem>View customer</DropdownMenuItem>
<DropdownMenuItem>View payment details</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
},
},
];
function DataTableTools() {
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
);
const [data]=trpc.tools.getTools.useSuspenseQuery()
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const [selectedTools, setSelectedTools] = React.useState<SelectedTool[]>([]);
const table = useReactTable({
data: data ? data : [],
columns: columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
},
});
React.useMemo(() => {
if(!data)return
const toolList = table
.getFilteredSelectedRowModel()
.flatRows?.map((row) => ({
id: row.original.id,
name: row.original.name,
inStock: row.original.quantity,
quantity:0,
totalAssignedUsers: row?.original?.userTool?.reduce(
(acc:number, tool:Tool) => acc + tool.quantity,
0
),
}));
setSelectedTools(toolList);
}, [rowSelection,data,table]) // eslint-disable-next-line react-hooks/exhaustive-deps
return (
<div className="w-full">
<div className="flex gap-6 mt-1">
<AlertDeleteTools selectedTools={selectedTools} />
<DialogUserTools
mode="assign"
selectedTools={selectedTools}
setSelectedTools={setSelectedTools}
/>
<DialogUpdateTools
selectedTools={selectedTools}
setSelectedTools={setSelectedTools}
/>
</div>
<div className="flex items-center gap-10 py-4">
<Input
placeholder="Filtrar por nombre..."
value={(table.getColumn("name")?.getFilterValue() as string) ?? ""}
onChange={(event) =>
table.getColumn("name")?.setFilterValue(event.target.value)
}
className="max-w-sm"
/>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" className="ml-auto">
Filas <ChevronDown className="ml-2 h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{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>
</div>
<div className="rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</TableHead>
);
})}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row, index) => (
<TableRow
key={`row-${row.id}-${index}`}
data-state={row.getIsSelected() && "selected"}
>
{row.getVisibleCells().map((cell, index) => (
<TableCell key={`cell-${cell}-${index}`}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell
colSpan={columns.length}
className="h-24 text-center"
>
Sin resultados...
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
<div className="flex items-center justify-end space-x-2 py-4">
<div className="flex-1 text-sm text-muted-foreground">
{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()}
>
Anterior
</Button>
<Button
variant="outline"
size="sm"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
>
Siguiente
</Button>
</div>
</div>
</div>
);
}
export default DataTableTools;