Lines
-
+
+
+
+ New item
+
+
+
{lines.length > 0 && (
diff --git a/Frontend/erp-system/app/dashboard/procurement/purchase-orders/page.tsx b/Frontend/erp-system/app/dashboard/procurement/purchase-orders/page.tsx
index bf4b352..7676f2e 100644
--- a/Frontend/erp-system/app/dashboard/procurement/purchase-orders/page.tsx
+++ b/Frontend/erp-system/app/dashboard/procurement/purchase-orders/page.tsx
@@ -2,9 +2,9 @@
import { useEffect, useState } from "react"
import Link from "next/link"
-import { ChevronLeft, ChevronRight, Plus, ShoppingCart } from "lucide-react"
+import { Check, ChevronLeft, ChevronRight, Eye, Pencil, Plus, ShoppingCart, Trash2 } from "lucide-react"
-import { purchaseOrdersApi } from "@/lib/api/purchase-orders"
+import { isPoEditable, purchaseOrdersApi } from "@/lib/api/purchase-orders"
import { vendorsApi } from "@/lib/api/vendors"
import { errorMessage } from "@/lib/error-map"
import { PurchaseOrderStatus, PurchaseOrderSummary } from "@/types/procurement"
@@ -16,6 +16,7 @@ import { Input } from "@/components/ui/input"
import { Skeleton } from "@/components/ui/skeleton"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
+import { toast } from "@/components/ui/toast"
import { PoStatusBadge } from "@/components/procurement/status-badges"
type StatusFilter = PurchaseOrderStatus | "All"
@@ -32,6 +33,8 @@ export default function PurchaseOrdersListPage() {
const [query, setQuery] = useState("")
const [status, setStatus] = useState
("All")
const [page, setPage] = useState(1)
+ const [deletingId, setDeletingId] = useState(null)
+ const [approvingId, setApprovingId] = useState(null)
useEffect(() => {
const timeout = setTimeout(() => setQuery(searchInput.trim()), 300)
@@ -60,6 +63,34 @@ export default function PurchaseOrdersListPage() {
return vendors.find((v) => v.vendorId === vendorId)?.code ?? `#${vendorId}`
}
+ async function handleDelete(po: PurchaseOrderSummary) {
+ if (!window.confirm(`Delete draft ${po.docNo}? This cannot be undone.`)) return
+ setDeletingId(po.poId)
+ try {
+ await purchaseOrdersApi.remove(po.poId)
+ toast.success("Draft deleted", po.docNo)
+ load()
+ } catch (err) {
+ toast.error("Could not delete purchase order", errorMessage(err))
+ } finally {
+ setDeletingId(null)
+ }
+ }
+
+ async function handleApprove(po: PurchaseOrderSummary) {
+ if (!window.confirm(`Approve ${po.docNo}? It will be locked for editing once approved.`)) return
+ setApprovingId(po.poId)
+ try {
+ const updated = await purchaseOrdersApi.submit(po.poId)
+ toast.success("Purchase order approved", `${updated.docNo} — now ${updated.status}.`)
+ load()
+ } catch (err) {
+ toast.error("Could not approve purchase order", errorMessage(err))
+ } finally {
+ setApprovingId(null)
+ }
+ }
+
const hasFilters = query.length > 0 || status !== "All"
return (
@@ -133,24 +164,76 @@ export default function PurchaseOrdersListPage() {
Status
Grand total
Created
+ Actions
- {pos.map((po) => (
-
-
-
- {po.docNo}
-
-
- {vendorCode(po.vendorId)}
-
-
-
- {po.totals.currency} {po.totals.grandTotal.toFixed(2)}
- {new Date(po.createdAt).toLocaleString()}
-
- ))}
+ {pos.map((po) => {
+ const editable = isPoEditable(po.status)
+ return (
+
+
+
+ {po.docNo}
+
+
+ {vendorCode(po.vendorId)}
+
+
+
+ {po.totals.currency} {po.totals.grandTotal.toFixed(2)}
+ {new Date(po.createdAt).toLocaleString()}
+
+
+
+
+
+ {editable && (
+ <>
+
+
+
+
+
+ >
+ )}
+
+
+
+ )
+ })}
diff --git a/Frontend/erp-system/app/dashboard/production/templates/[id]/StageEditorPanel.tsx b/Frontend/erp-system/app/dashboard/production/templates/[id]/StageEditorPanel.tsx
index 825740d..613f95b 100644
--- a/Frontend/erp-system/app/dashboard/production/templates/[id]/StageEditorPanel.tsx
+++ b/Frontend/erp-system/app/dashboard/production/templates/[id]/StageEditorPanel.tsx
@@ -1,6 +1,6 @@
"use client"
-import { Plus, Trash2, X } from "lucide-react"
+import { Plus, Trash2 } from "lucide-react"
import { cn } from "@/lib/utils"
import { CustomFieldType, StageInputSource } from "@/types/production"
@@ -15,6 +15,7 @@ import {
} from "./types"
import { Button } from "@/components/ui/button"
+import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { Field, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
@@ -175,265 +176,264 @@ export function StageEditorPanel({
}
return (
-
-
-
Stage editor
-
-
+