"use client"; import { useState, useMemo } from "react"; import { useQuery } from "@tanstack/react-query"; import { useReactTable, getCoreRowModel, getSortedRowModel, getPaginationRowModel, flexRender, SortingState, PaginationState, } from "@tanstack/react-table"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { TriangleAlertIcon } from "lucide-react"; import { Pagination, PaginationContent, PaginationItem, } from "@/components/ui/pagination"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Search } from "lucide-react"; import { FaSort, FaSortUp, FaSortDown } from "react-icons/fa"; import { fetchHarvestUnits } from "@/api/harvest"; import { Badge } from "@/components/ui/badge"; import { fetchInventoryItems, fetchInventoryStatus, fetchInventoryCategory, } from "@/api/inventory"; import { AddInventoryItem } from "./add-inventory-item"; import { EditInventoryItem } from "./edit-inventory-item"; import { DeleteInventoryItem } from "./delete-inventory-item"; import { InventoryItem } from "@/types"; export default function InventoryPage() { const [sorting, setSorting] = useState([]); const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10, }); ////////////////////////////// // query the necessary data for edit and etc. const { data: inventoryItems = [], isLoading: isItemLoading, isError: isItemError, } = useQuery({ queryKey: ["inventoryItems"], queryFn: fetchInventoryItems, staleTime: 60 * 1000, }); // console.table(inventoryItems); // console.log(inventoryItems); const { data: inventoryStatus = [], isLoading: isLoadingStatus, isError: isErrorStatus, } = useQuery({ queryKey: ["inventoryStatus"], queryFn: fetchInventoryStatus, staleTime: 60 * 1000, }); // console.log(inventoryStatus); const { data: inventoryCategory = [], isLoading: isLoadingCategory, isError: isErrorCategory, } = useQuery({ queryKey: ["inventoryCategory"], queryFn: fetchInventoryCategory, staleTime: 60 * 1000, }); const { data: harvestUnits = [], isLoading: isLoadingHarvestUnits, isError: isErrorHarvestUnits, } = useQuery({ queryKey: ["harvestUnits"], queryFn: fetchHarvestUnits, staleTime: 60 * 1000, }); ////////////////////////////// // console.table(inventoryItems); // console.table(inventoryStatus); // console.table(harvestUnits); const [searchTerm, setSearchTerm] = useState(""); const filteredItems = useMemo(() => { return inventoryItems .map((item) => ({ ...item, status: { id: item.status.id, name: item.status.name }, category: { id: item.category.id, name: item.category.name }, unit: { id: item.unit.id, name: item.unit.name }, fetchedInventoryStatus: inventoryStatus, fetchedInventoryCategory: inventoryCategory, fetchedHarvestUnits: harvestUnits, lastUpdated: new Date(item.updatedAt).toLocaleString("en-US", { year: "numeric", month: "short", day: "numeric", hour: "2-digit", minute: "2-digit", hour12: true, }), })) .filter((item) => item.name.toLowerCase().includes(searchTerm.toLowerCase()) ); }, [inventoryItems, searchTerm]); // prepare columns for table const columns = [ { accessorKey: "name", header: "Name" }, { accessorKey: "category", header: "Category", cell: ({ row }: { row: { original: InventoryItem } }) => row.original.category.name, }, { accessorKey: "quantity", header: "Quantity", }, { accessorKey: "unit", header: "Unit", cell: ({ row }: { row: { original: InventoryItem } }) => row.original.unit.name, }, { accessorKey: "lastUpdated", header: "Last Updated", }, { accessorKey: "status", header: "Status", cell: ({ row }: { row: { original: InventoryItem } }) => { const status = row.original.status.name; let statusClass = ""; if (status === "In Stock") { statusClass = "bg-green-500 hover:bg-green-600 text-white"; } else if (status === "Low Stock") { statusClass = "bg-yellow-300 hover:bg-yellow-400"; } else if (status === "Out of Stock") { statusClass = "bg-red-500 hover:bg-red-600 text-white"; } else if (status === "Expired") { statusClass = "bg-gray-500 hover:bg-gray-600 text-white"; } else if (status === "Reserved") { statusClass = "bg-blue-500 hover:bg-blue-600 text-white"; } return ( {status} ); }, }, { accessorKey: "edit", header: "Edit", cell: ({ row }: { row: { original: InventoryItem } }) => ( ), enableSorting: false, }, { accessorKey: "delete", header: "Delete", cell: ({ row }: { row: { original: InventoryItem } }) => ( ), enableSorting: false, }, ]; const table = useReactTable({ data: filteredItems, columns, state: { sorting, pagination }, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), getPaginationRowModel: getPaginationRowModel(), onSortingChange: setSorting, onPaginationChange: setPagination, }); const loadingStates = [ isItemLoading, isLoadingStatus, isLoadingCategory, isLoadingHarvestUnits, ]; const errorStates = [ isItemError, isErrorStatus, isErrorCategory, isErrorHarvestUnits, ]; const isLoading = loadingStates.some((loading) => loading); const isError = errorStates.some((error) => error); if (isLoading) return (
Loading...
); if (isError) return (
Error loading inventory data.
); if (inventoryItems.length === 0) { return (
No Inventory Data
You currently have no inventory items. Add a new item to get started!
); } return (

Inventory

setSearchTerm(e.target.value)} />
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => (
{flexRender( header.column.columnDef.header, header.getContext() )} {header.column.getCanSort() && !header.column.columnDef.enableSorting && ( {header.column.getIsSorted() === "desc" ? ( ) : header.column.getIsSorted() === "asc" ? ( ) : ( )} )}
))}
))}
{table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext() )} ))} ))}
); }