"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { managerEditPo } from "./manager-po-edit-actions"; import { LineItemsEditor } from "@/components/po/po-line-items-editor"; import { TC_DEFAULTS, TC_FIXED_LINE } from "@/lib/validations/po"; import type { LineItemInput } from "@/lib/validations/po"; import type { Vendor, PurchaseOrder } from "@prisma/client"; import type { VesselOption, AccountGroup } from "@/app/(portal)/po/new/new-po-form"; import { SearchableSelect } from "@/components/ui/searchable-select"; type SerializedLineItem = { id: string; poId: string; name: string; description: string | null; quantity: number; unit: string; size: string | null; unitPrice: number; totalPrice: number; gstRate: number; sortOrder: number; productId: string | null; }; type PoFull = Omit & { totalAmount: number; lineItems: SerializedLineItem[]; vessel: { id: string; name: string } | null; account: { id: string; name: string; code: string }; vendor: { id: string; name: string; vendorId: string | null } | null; }; interface Props { po: PoFull; vessels: VesselOption[]; accounts: AccountGroup[]; vendors: Vendor[]; } const INPUT = "w-full rounded-lg border border-amber-300 bg-amber-50 px-3 py-2 text-sm focus:border-amber-500 focus:outline-none focus:ring-2 focus:ring-amber-400/30 placeholder:text-neutral-400"; const LABEL = "block text-xs font-semibold text-amber-800 mb-1"; /** Controlled account picker so SearchableSelect can be used inside the uncontrolled manager form */ function ManagerAccountSelect({ accountId, accounts }: { accountId: string; accounts: AccountGroup[] }) { const [value, setValue] = useState(accountId); return ; } export function ManagerEditPoForm({ po, vessels, accounts, vendors }: Props) { const router = useRouter(); const [editing, setEditing] = useState(false); const [pending, setPending] = useState(false); const [error, setError] = useState(""); const [saved, setSaved] = useState(false); const extPo = po as typeof po & { piQuotationNo?: string | null; piQuotationDate?: Date | null; requisitionNo?: string | null; requisitionDate?: Date | null; placeOfDelivery?: string | null; tcDelivery?: string | null; tcDispatch?: string | null; tcInspection?: string | null; tcTransitInsurance?: string | null; tcPaymentTerms?: string | null; tcOthers?: string | null; }; const [lineItems, setLineItems] = useState( po.lineItems.map((li) => ({ name: li.name, description: li.description ?? undefined, quantity: li.quantity, unit: li.unit, size: li.size ?? undefined, unitPrice: li.unitPrice, gstRate: li.gstRate, })) ); function isoDate(d: Date | null | undefined) { if (!d) return ""; return new Date(d).toISOString().split("T")[0]; } async function handleSave() { setPending(true); setError(""); const form = document.getElementById("mgr-edit-po-form") as HTMLFormElement; const data = new FormData(form); lineItems.forEach((item, i) => { data.set(`lineItems[${i}].name`, item.name); data.set(`lineItems[${i}].description`, item.description ?? ""); data.set(`lineItems[${i}].quantity`, String(item.quantity)); data.set(`lineItems[${i}].unit`, item.unit); data.set(`lineItems[${i}].size`, item.size ?? ""); data.set(`lineItems[${i}].unitPrice`, String(item.unitPrice)); data.set(`lineItems[${i}].gstRate`, String(item.gstRate ?? 0.18)); }); const result = await managerEditPo(po.id, data); if ("error" in result) { setError(result.error); setPending(false); } else { setSaved(true); setEditing(false); setPending(false); router.refresh(); } } if (!editing) { return (
{saved && (

PO updated. Original values are preserved in the activity trail.

)}

Edit any field on this PO. Original values will be saved to the audit trail.

); } return (
{/* Header */}

Manager — Editing PO

All changes will be saved to the audit trail with the original values.

e.preventDefault()}> {/* Order Information */}

Order Information

{/* Quotation Reference */}

Quotation Reference

{/* Requisition */}

Requisition

{/* Delivery */}

Delivery