75 lines
2.1 KiB
TypeScript
75 lines
2.1 KiB
TypeScript
"use client";
|
|
|
|
import { useMemo, useState } from "react";
|
|
import { receivePurchaseOrder } from "@/lib/actions";
|
|
import type { PurchaseOrderLineDetailRow } from "@/lib/types";
|
|
|
|
type Props = {
|
|
orderId: number;
|
|
lines: PurchaseOrderLineDetailRow[];
|
|
};
|
|
|
|
export function PurchaseOrderFulfillmentForm({ orderId, lines }: Props) {
|
|
const [quantities, setQuantities] = useState<Record<number, string>>({});
|
|
|
|
const payload = useMemo(
|
|
() =>
|
|
JSON.stringify(
|
|
lines
|
|
.map((line) => ({
|
|
lineId: line.lineId,
|
|
quantity: Number(quantities[line.lineId] || 0)
|
|
}))
|
|
.filter((line) => line.quantity > 0)
|
|
),
|
|
[lines, quantities]
|
|
);
|
|
|
|
return (
|
|
<form action={receivePurchaseOrder} className="form-grid">
|
|
<input type="hidden" name="orderId" value={orderId} />
|
|
<input type="hidden" name="fulfillmentLines" value={payload} />
|
|
<div className="table-wrap">
|
|
<table className="table">
|
|
<thead>
|
|
<tr>
|
|
<th>SKU</th>
|
|
<th>Item</th>
|
|
<th>Remaining</th>
|
|
<th>Receive Now</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{lines.map((line) => (
|
|
<tr key={line.lineId}>
|
|
<td>{line.sku}</td>
|
|
<td>{line.partName}</td>
|
|
<td>{line.remainingQuantity} {line.unitOfMeasure}</td>
|
|
<td>
|
|
<input
|
|
className="input"
|
|
type="number"
|
|
min="0"
|
|
max={line.remainingQuantity}
|
|
step="0.01"
|
|
value={quantities[line.lineId] ?? ""}
|
|
onChange={(event) =>
|
|
setQuantities((current) => ({
|
|
...current,
|
|
[line.lineId]: event.target.value
|
|
}))
|
|
}
|
|
/>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<button className="button secondary" type="submit">
|
|
Receive Selected Quantities
|
|
</button>
|
|
</form>
|
|
);
|
|
}
|