From 707f7e359fdfe2641be9fdfe98b5cc645a159b41 Mon Sep 17 00:00:00 2001 From: NotII <46204250+NotII@users.noreply.github.com> Date: Fri, 25 Jul 2025 20:56:22 +0100 Subject: [PATCH] Update page.tsx --- app/dashboard/stock/page.tsx | 101 ++++++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 1 deletion(-) diff --git a/app/dashboard/stock/page.tsx b/app/dashboard/stock/page.tsx index a652354..5cbb8d8 100644 --- a/app/dashboard/stock/page.tsx +++ b/app/dashboard/stock/page.tsx @@ -13,6 +13,11 @@ import { DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; import { AlertDialog, AlertDialogAction, @@ -25,7 +30,7 @@ import { AlertDialogTrigger, } from "@/components/ui/alert-dialog"; import { Product } from "@/models/products"; -import { Package, RefreshCw, ChevronDown, CheckSquare, XSquare, Boxes } from "lucide-react"; +import { Package, RefreshCw, ChevronDown, CheckSquare, XSquare, Boxes, Download, Calendar } from "lucide-react"; import { clientFetch } from "@/lib/api"; import { toast } from "sonner"; @@ -45,6 +50,8 @@ export default function StockManagementPage() { const [selectedProducts, setSelectedProducts] = useState([]); const [isConfirmDialogOpen, setIsConfirmDialogOpen] = useState(false); const [bulkAction, setBulkAction] = useState<'enable' | 'disable' | null>(null); + const [exportDate, setExportDate] = useState(new Date().toISOString().split('T')[0]); + const [isExporting, setIsExporting] = useState(false); useEffect(() => { const authToken = document.cookie @@ -249,6 +256,63 @@ export default function StockManagementPage() { ); }; + const handleExportStock = async () => { + setIsExporting(true); + try { + const response = await clientFetch(`/api/analytics/daily-stock-report?date=${exportDate}`); + + if (!response || !response.products) { + throw new Error('No data received from server'); + } + + // Convert data to CSV format + const csvHeaders = [ + 'Product Name', + 'Quantity Sold', + 'Total Revenue (£)', + 'Average Price (£)', + 'Order Count', + 'Current Stock', + 'Stock Status', + 'Unit Type' + ]; + + const csvData = [ + csvHeaders.join(','), + ...response.products.map((product: any) => [ + `"${product.productName.replace(/"/g, '""')}"`, // Escape quotes in product names + product.quantitySold, + product.totalRevenue.toFixed(2), + product.averagePrice.toFixed(2), + product.orderCount, + product.currentStock || 0, + `"${product.stockStatus}"`, + `"${product.unitType || 'N/A'}"` + ].join(',')) + ].join('\n'); + + // Create and download the CSV file + const blob = new Blob([csvData], { type: 'text/csv;charset=utf-8;' }); + const link = document.createElement('a'); + const url = URL.createObjectURL(blob); + + link.setAttribute('href', url); + link.setAttribute('download', `daily-stock-report-${exportDate}.csv`); + link.style.visibility = 'hidden'; + + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + toast.success(`Stock report for ${exportDate} exported successfully`); + } catch (error) { + console.error('Error exporting stock report:', error); + toast.error('Failed to export stock report'); + } finally { + setIsExporting(false); + } + }; + const getStockStatus = (product: Product) => { if (!product.stockTracking) return 'Not tracked'; if (product.currentStock === undefined) return 'Unknown'; @@ -284,6 +348,41 @@ export default function StockManagementPage() { value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} /> + + + + + +
+ + setExportDate(e.target.value)} + className="w-full" + /> +
+
+
+ {selectedProducts.length > 0 && (