diff --git a/src/components/reports/LowStockColumns.tsx b/src/components/reports/LowStockColumns.tsx new file mode 100644 index 0000000..3e5997b --- /dev/null +++ b/src/components/reports/LowStockColumns.tsx @@ -0,0 +1,34 @@ +"use client" + +import { ColumnDef } from "@tanstack/react-table" + +export type LowStockRecord = { + id: string + itemName: string + sku: string + quantity: number + threshold: number +} + +export const lowStockColumns: ColumnDef[] = [ + { + accessorKey: "itemName", + header: "Item Name", + }, + { + accessorKey: "sku", + header: "SKU", + }, + { + accessorKey: "quantity", + header: "Qty", + cell: ({ row }) => { + const val = row.getValue("quantity") as number + return
{val}
+ }, + }, + { + accessorKey: "threshold", + header: "Threshold", + }, +] diff --git a/src/components/reports/LowStockReport.tsx b/src/components/reports/LowStockReport.tsx new file mode 100644 index 0000000..014b38b --- /dev/null +++ b/src/components/reports/LowStockReport.tsx @@ -0,0 +1,68 @@ +"use client" + +import * as React from "react" +import pb from "@/lib/pocketbase" +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { lowStockColumns, LowStockRecord } from "./LowStockColumns" +import { ReportDataTable } from "./ReportDataTable" +import { showError } from "@/utils/toast" +import { AlertTriangle } from "lucide-react" + +export function LowStockReport() { + const [threshold, setThreshold] = React.useState(3) + const [data, setData] = React.useState([]) + const [loading, setLoading] = React.useState(false) + + const fetchLowStock = React.useCallback(async () => { + setLoading(true) + try { + const records = await pb.collection("stock_items").getFullList({ + filter: `quantity < ${threshold}`, + sort: "quantity", + }) + const formatted: LowStockRecord[] = records.map((item: any) => ({ + id: item.id, + itemName: item.name, + sku: item.sku, + quantity: Number(item.quantity ?? 0), + threshold, + })) + setData(formatted) + } catch (e) { + console.error("Low stock fetch error:", e) + showError("Failed to load low stock report.") + setData([]) + } finally { + setLoading(false) + } + }, [threshold]) + + React.useEffect(() => { + fetchLowStock() + }, [fetchLowStock]) + + return ( +
+
+
+ + setThreshold(Number(e.target.value || 0))} + className="max-w-xs" + /> +
+ +
+ +
+ ) +} + diff --git a/src/pages/Reports.tsx b/src/pages/Reports.tsx index 74d58d2..257b948 100644 --- a/src/pages/Reports.tsx +++ b/src/pages/Reports.tsx @@ -6,6 +6,7 @@ import { Button } from "@/components/ui/button"; import { FileText } from "lucide-react"; import pb from "@/lib/pocketbase"; import { showError } from "@/utils/toast"; +import { LowStockReport } from "@/components/reports/LowStockReport"; const Reports = () => { const [billingCompanies, setBillingCompanies] = useState<{ value: string; label: string }[]>([]); @@ -102,7 +103,7 @@ const Reports = () => {

Reports

-

Generate book-out reports by billing company.

+

Generate book-out reports by billing company and view low stock.

@@ -125,8 +126,14 @@ const Reports = () => { + +
+

Low Stock Report

+

Items below the selected threshold.

+ +
); }; -export default Reports; \ No newline at end of file +export default Reports;