Update page.tsx

This commit is contained in:
NotII
2025-07-25 20:56:22 +01:00
parent cb1335b8fd
commit 707f7e359f

View File

@@ -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<string[]>([]);
const [isConfirmDialogOpen, setIsConfirmDialogOpen] = useState(false);
const [bulkAction, setBulkAction] = useState<'enable' | 'disable' | null>(null);
const [exportDate, setExportDate] = useState<string>(new Date().toISOString().split('T')[0]);
const [isExporting, setIsExporting] = useState<boolean>(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)}
/>
<Popover>
<PopoverTrigger asChild>
<Button
variant="outline"
className="gap-2"
>
<Calendar className="h-4 w-4" />
{exportDate}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-3" align="end">
<div className="space-y-2">
<label className="text-sm font-medium">Select Date for Export</label>
<Input
type="date"
value={exportDate}
onChange={(e) => setExportDate(e.target.value)}
className="w-full"
/>
</div>
</PopoverContent>
</Popover>
<Button
variant="outline"
onClick={handleExportStock}
disabled={isExporting}
className="gap-2"
>
{isExporting ? (
<RefreshCw className="h-4 w-4 animate-spin" />
) : (
<Download className="h-4 w-4" />
)}
{isExporting ? 'Exporting...' : 'Export CSV'}
</Button>
{selectedProducts.length > 0 && (
<DropdownMenu>
<DropdownMenuTrigger asChild>