"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,
TableFooter,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import Link from "next/link";
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card";
import { cn } from "@/lib/utils";
import AlertDeleteMaterials from "./AlertDeleteMaterial";
import { trpc } from "@/app/_trpc/client";
import { ProjectMaterials } from "../types";
export const columns: ColumnDef<ProjectMaterials>[] = [
{
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")}
>
Disponible
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
},
cell: ({ row }) => {
return <div className="lowercase px-10">
{row?.original?.projectMaterials?.reduce((acc,project)=>{
return acc+project?.availableQuantity
},0) || 0}
</div>
},
},
{
accessorKey: "project",
header: ({ column }) => {
return (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
Projectos
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
},
cell: ({ row }) => {
return <div className="lowercase px-3 grid grid-cols-[repeat(auto-fill,minmax(50px,1fr))] ">
<HoverCard>
<HoverCardTrigger asChild>
<Button variant="link">@ {row?.original?.projectMaterials?.length}</Button>
</HoverCardTrigger>
<HoverCardContent className="w-80">
<Table>
<TableCaption className=" text-xs">Materiales en projectos activos</TableCaption>
<TableHeader>
<TableRow>
<TableHead className=" text-xs">Nombre</TableHead>
<TableHead className=" text-xs">Requeridos</TableHead>
<TableHead className=" text-xs">Disponibles</TableHead>
<TableHead className="text-right text-xs">Usados</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{row?.original?.projectMaterials?.map((project) => (
<TableRow key={project.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/projects/${project.projectId}`}>
{project?.project?.name}
</Link>
</TableCell>
<TableCell className=" text-xs">{project.requiredQuantity}</TableCell>
<TableCell className=" text-xs">{project.availableQuantity}</TableCell>
<TableCell className="text-right text-xs">
{project.usedQuantity}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</HoverCardContent>
</HoverCard>
</div>
},
},
{
id: "actions",
enableHiding: false,
cell: ({ row }) => {
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 MaterialList({searchParams}:{searchParams:Record<string,any>}) {
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
);
const [data]=trpc.projects.getAllProjectMaterials.useSuspenseQuery(searchParams)
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const [selectedMaterials, setSelectedMaterials] = React.useState<any>([]);
const table = useReactTable({
data: data ? data : [],
columns:columns as any,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
},
});
React.useMemo(() => {
const materialList = table?.getFilteredSelectedRowModel()?.flatRows?.map((row) => row.original);
setSelectedMaterials(materialList);
}, [table,rowSelection]) // eslint-disable-next-line react-hooks/exhaustive-deps
return (
<div className="w-full">
<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"
/>
<div className="flex flex-1 gap-1">
<AlertDeleteMaterials selectedMaterials={selectedMaterials} />
<DropdownMenu >
<DropdownMenuTrigger asChild>
<Button variant="outline" size="sm" 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>
<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 MaterialList;