From 05c89815139ba053d49cfefad89a0bba0a9f7bbb Mon Sep 17 00:00:00 2001 From: davidels1 <87242587+davidels1@users.noreply.github.com> Date: Wed, 14 Jan 2026 09:04:38 +0200 Subject: [PATCH] feat(reports): add low stock report component and integration Add new LowStockReport component with data fetching and table display functionality. Includes threshold filtering and refresh capability. Update Reports page to include the new low stock section and modify the description text. --- src/components/reports/LowStockColumns.tsx | 34 +++++++++++ src/components/reports/LowStockReport.tsx | 68 ++++++++++++++++++++++ src/pages/Reports.tsx | 11 +++- 3 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 src/components/reports/LowStockColumns.tsx create mode 100644 src/components/reports/LowStockReport.tsx 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;