"use client";
/* One stock line: a garment in one size. On hand against par, where it lives, what is coming, and the
three things done about it: print a label, count its shelf, put it on the draft order. */
import { useCallback, useState } from "react";
import { useParams } from "next/navigation";
import { useDerived, useSnap } from "@/lib/client";
import { bcBound, key, label, locMap, locTrail, money, onOrderText, onhand, reorderAt } from "@/lib/compute";
import { INK, MBody, MButton, MEmpty, MKick, MONO, MPill, MRow, MRule, MTop, useToast } from "@/components/m";
import PrintSheet from "@/components/m/stock/PrintSheet";
import { heldByStaff, lastCountedText } from "@/components/m/stock/stockdata";
const dt: React.CSSProperties = { margin: 0, padding: "11px 14px 11px 0", borderBottom: "1px solid var(--color-divider)", fontSize: 12, fontWeight: 800, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--color-neutral-600)" };
const dd: React.CSSProperties = { margin: 0, padding: "11px 0", borderBottom: "1px solid var(--color-divider)", textAlign: "right", fontWeight: 700 };
export default function MLinePage() {
const params = useParams<{ itemId: string; si: string }>();
const { s, isAdmin, mutate, busy } = useSnap();
const { L } = useDerived();
const toast = useToast();
const [printing, setPrinting] = useState(false);
// Stable, because MSheet re-runs its focus handling whenever onClose changes.
const closePrint = useCallback(() => setPrinting(false), []);
const itemId = decodeURIComponent(String(params.itemId || ""));
const si = /^\d+$/.test(String(params.si || "")) ? Number(params.si) : -1;
const it = s.catalog.find((x) => x.id === itemId);
if (!it || it.archived || si < 0 || si >= it.sizes.length) {
return (
<>
>
);
}
const k = key(it.id, si);
const size = String(it.sizes[si]);
const oh = onhand(s, L, k), par = reorderAt(s, k);
const code = bcBound(s, it, si);
const locs = locMap(s);
const placedId = s.placed[k];
const placed = placedId ? locs[placedId] : undefined;
const shelf = placed ? (locTrail(locs, placed.id, 0) || placed.name) : "";
const onOrder = onOrderText(s, it.id, si);
const short = Math.max(0, par - oh);
const addToDraft = async () => {
const r = await mutate<{ added: number; qty: number }>("stock.orderLine", { itemId: it.id, si });
if (!r.ok) { toast(r.error); return; }
toast(r.result.added > 0 ? `Added ${r.result.added} to the draft order` : "Already on the draft order");
};
return (
<>
{code || (it.sku ? `SKU ${it.sku}` : "No barcode")}
{label(it)} · {size}
{oh} / {par} par
{short > 0
?
{short} short
:
At par}
- Shelf
- {shelf || "Not on a shelf"}
- On order
- {onOrder || "None"}
- Last counted
- {lastCountedText(s, it.id, si)}
- Held by staff
- {heldByStaff(s, it.id, si)}
- Unit cost
- {money(it.cost)}
setPrinting(true)} />
{!code && No barcode bound
}
{!code && isAdmin && }
{placed && }
{isAdmin && (
)}
{code && }
>
);
}