[dyad] wrote 5 file(s)

This commit is contained in:
[dyad] 2025-09-12 11:17:55 +02:00
parent 3e307807d8
commit 5362363c31
3 changed files with 104 additions and 9 deletions

View file

@ -25,6 +25,14 @@ import { jsPDF } from "jspdf"
import { ReceiveStockDialog } from "./ReceiveStockDialog"
import pb from "@/lib/pocketbase"
import { createColumns, PurchaseOrder } from "./columns" // Import createColumns and PurchaseOrder type
import {
Dialog, // Import Dialog components
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
interface PurchaseOrderDataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[]
@ -56,6 +64,7 @@ export function PurchaseOrderDataTable<TData, TValue>({
const [rowSelection, setRowSelection] = React.useState({})
const [receiveDialogOpen, setReceiveDialogOpen] = React.useState(false)
const [selectedOrder, setSelectedOrder] = React.useState<PurchaseOrder | null>(null)
const [viewDialogOpen, setViewDialogOpen] = React.useState(false) // State for the view dialog
const openReceiveDialog = (order: PurchaseOrder) => {
setSelectedOrder(order)
@ -67,6 +76,16 @@ export function PurchaseOrderDataTable<TData, TValue>({
setReceiveDialogOpen(false)
}
const handleViewOrder = (order: PurchaseOrder) => {
setSelectedOrder(order)
setViewDialogOpen(true)
}
const closeViewDialog = () => {
setSelectedOrder(null)
setViewDialogOpen(false)
}
const generatePDF = (order: PurchaseOrder) => {
const doc = new jsPDF()
doc.setFontSize(16)
@ -105,11 +124,11 @@ export function PurchaseOrderDataTable<TData, TValue>({
}
}
const columnsWithActions = React.useMemo(() => createColumns({ onDownloadPdf: generatePDF }), [generatePDF]);
const columnsWithActions = React.useMemo(() => createColumns({ onDownloadPdf: generatePDF, onViewOrder: handleViewOrder }), [generatePDF, handleViewOrder]);
const table = useReactTable<PurchaseOrder>({ // Specify TData as PurchaseOrder
data, // Now 'data' (which is PurchaseOrder[]) is correctly assigned to the 'data' parameter of useReactTable
columns: columnsWithActions, // Use the correctly memoized columns
data: data as PurchaseOrder[], // Explicitly type data as PurchaseOrder[]
columns: columnsWithActions, // Use the columns with actions
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
onSortingChange: setSorting,
@ -229,6 +248,32 @@ export function PurchaseOrderDataTable<TData, TValue>({
</div>
</div>
{/* View Order Dialog */}
<Dialog open={viewDialogOpen} onOpenChange={closeViewDialog}>
<DialogContent className="sm:max-w-lg">
<DialogHeader>
<DialogTitle>Purchase Order Details</DialogTitle>
<DialogDescription>Order ID: {selectedOrder?.id}</DialogDescription>
</DialogHeader>
<div className="space-y-4">
<p><strong>Supplier:</strong> {selectedOrder?.supplierName}</p>
<p><strong>Order Date:</strong> {selectedOrder?.orderDate ? new Date(selectedOrder.orderDate).toLocaleDateString() : 'N/A'}</p>
<p><strong>Status:</strong> {selectedOrder?.status}</p>
<h4 className="font-semibold">Items:</h4>
<ul className="list-disc list-inside">
{selectedOrder?.items.map((item, index) => (
<li key={item.stockItemId}>
{item.itemName} (SKU: {item.sku}) - Quantity: {selectedOrder.quantities[index]}
</li>
))}
</ul>
</div>
<div className="flex justify-end space-x-2 pt-4">
<Button variant="outline" onClick={closeViewDialog}>Close</Button>
</div>
</DialogContent>
</Dialog>
{selectedOrder && (
<ReceiveStockDialog
open={receiveDialogOpen}

View file

@ -1,8 +1,16 @@
"use client"
import { ColumnDef } from "@tanstack/react-table"
import { MoreHorizontal, Download } from "lucide-react" // Import Download icon
import { MoreHorizontal, Download, Eye } from "lucide-react" // Import Eye icon
import { Button } from "@/components/ui/button"
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog" // Import Dialog components
import {
DropdownMenu,
DropdownMenuContent,
@ -11,6 +19,7 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { useState } from "react" // Import useState
export type PurchaseOrder = {
id: string
@ -25,10 +34,11 @@ export type PurchaseOrder = {
// Define the props for the actions column
interface ActionsColumnProps {
onDownloadPdf: (order: PurchaseOrder) => void;
onViewOrder: (order: PurchaseOrder) => void; // Add onViewOrder prop
}
// Export createColumns function
export const createColumns = ({ onDownloadPdf }: ActionsColumnProps): ColumnDef<PurchaseOrder>[] => [
export const createColumns = ({ onDownloadPdf, onViewOrder }: ActionsColumnProps): ColumnDef<PurchaseOrder>[] => [
{
accessorKey: "supplierName",
header: "Supplier Name",
@ -59,6 +69,7 @@ export const createColumns = ({ onDownloadPdf }: ActionsColumnProps): ColumnDef<
enableHiding: false,
cell: ({ row }) => {
const order = row.original
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false); // State for edit dialog, if needed later
return (
<DropdownMenu>
@ -74,8 +85,12 @@ export const createColumns = ({ onDownloadPdf }: ActionsColumnProps): ColumnDef<
onClick={() => navigator.clipboard.writeText(order.id)}
>
Copy Order ID
</DropdownMenuItem> {/* Correctly closed DropdownMenuItem */}
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => onViewOrder(order)}> {/* Call onViewOrder */}
<Eye className="mr-2 h-4 w-4" />
View Order
</DropdownMenuItem>
<DropdownMenuItem onClick={() => onDownloadPdf(order)}>
<Download className="mr-2 h-4 w-4" />
Download PDF

View file

@ -3,11 +3,12 @@ import { PurchaseOrderForm } from "@/components/purchase-orders/PurchaseOrderFor
import { Button } from "@/components/ui/button";
import { PlusCircle } from "lucide-react";
import {
Dialog,
Dialog, // Import Dialog components
DialogContent,
DialogHeader,
DialogTitle,
DialogTrigger,
DialogDescription, // Import DialogDescription
} from "@/components/ui/dialog";
import { createColumns, PurchaseOrder } from "@/components/purchase-orders/columns"; // Import createColumns
import { PurchaseOrderDataTable } from "@/components/purchase-orders/PurchaseOrderDataTable";
@ -18,6 +19,8 @@ const PurchaseOrders = () => {
const [purchaseOrders, setPurchaseOrders] = useState<PurchaseOrder[]>([]); // Explicitly type purchaseOrders
const [refreshTrigger, setRefreshTrigger] = useState(0);
const [filterValue, setFilterValue] = useState("");
const [viewOrderDialogOpen, setViewOrderDialogOpen] = useState(false); // State for the view order dialog
const [selectedOrderForView, setSelectedOrderForView] = useState<PurchaseOrder | null>(null); // State to hold the order to view
const fetchPurchaseOrders = useCallback(async () => {
try {
@ -62,8 +65,14 @@ const PurchaseOrders = () => {
// so this handler just needs to be passed down.
}, []);
// Call createColumns to get the columns array, passing the onDownloadPdf handler
const columns = createColumns({ onDownloadPdf: handleDownloadPdf });
// Define the handler to open the view order dialog
const handleViewOrder = useCallback((order: PurchaseOrder) => {
setSelectedOrderForView(order);
setViewOrderDialogOpen(true);
}, []);
// Call createColumns to get the columns array, passing the handlers
const columns = createColumns({ onDownloadPdf: handleDownloadPdf, onViewOrder: handleViewOrder });
return (
<div>
@ -94,6 +103,32 @@ const PurchaseOrders = () => {
onFilterChange={setFilterValue}
refreshData={handleRefreshData}
/>
{/* View Order Dialog */}
<Dialog open={viewOrderDialogOpen} onOpenChange={setViewOrderDialogOpen}>
<DialogContent className="sm:max-w-lg">
<DialogHeader>
<DialogTitle>Purchase Order Details</DialogTitle>
<DialogDescription>Order ID: {selectedOrderForView?.id}</DialogDescription>
</DialogHeader>
<div className="space-y-4">
<p><strong>Supplier:</strong> {selectedOrderForView?.supplierName}</p>
<p><strong>Order Date:</strong> {selectedOrderForView?.orderDate ? new Date(selectedOrderForView.orderDate).toLocaleDateString() : 'N/A'}</p>
<p><strong>Status:</strong> {selectedOrderForView?.status}</p>
<h4 className="font-semibold">Items:</h4>
<ul className="list-disc list-inside">
{selectedOrderForView?.items.map((item, index) => (
<li key={item.stockItemId}>
{item.itemName} (SKU: {item.sku}) - Quantity: {selectedOrderForView.quantities[index]}
</li>
))}
</ul>
</div>
<div className="flex justify-end space-x-2 pt-4">
<Button variant="outline" onClick={() => setViewOrderDialogOpen(false)}>Close</Button>
</div>
</DialogContent>
</Dialog>
</div>
);
};