import { useState } from "react"; import { ApiError } from "../api/client"; import { packetsApi } from "../api/packets"; import type { PacketRead } from "../api/types"; import { errorText, fmtTime } from "../lib/format"; import type { Write } from "../warehouse/PullTable"; import { WeldRecord } from "./WeldRecord"; import type { Mutate } from "./tabs"; /** * The stage checklist, grouped as the department's template, with the weld record beside it. Each tick is one PUT * for its key; ticks of different keys never clash. */ export function ChecklistTab({ p, write, mutate, reload, onError, }: { p: PacketRead; write: Write; mutate: Mutate; reload: () => Promise; onError: (text: string) => void; }) { const editable = !!p.stage && p.can.includes("edit_checklist"); const [pending, setPending] = useState>({}); const state = p.stage?.checklist ?? {}; const groups: Array<{ group: string; items: PacketRead["checklist_items"] }> = []; for (const it of p.checklist_items) { const g = groups.find((x) => x.group === it.group); if (g) g.items.push(it); else groups.push({ group: it.group, items: [it] }); } const tick = async (key: string, done: boolean) => { setPending((o) => ({ ...o, [key]: done })); const r = await write((g) => packetsApi.setChecklist(p.id, key, done, g)); setPending((o) => { const n = { ...o }; delete n[key]; return n; }); if (!r.ok && r.err !== undefined) { if (r.err instanceof ApiError && (r.err.status === 409 || r.err.status === 412)) await reload(); onError(errorText(r.err)); } }; const weld = p.dept.weld !== false; return (
{groups.length ? null :
No checklist for this department.
} {groups.map((g) => (

{g.group}

{g.items.map((i) => { const c = state[i.key]; const done = pending[i.key] ?? !!c?.done; const by = c?.done ? [c.stamp || c.by_name, fmtTime(c.at)].filter(Boolean).join(" ยท ") : ""; return ( ); })}
))} {!editable && groups.length ?
Checklist is completed at the stall.
: null}
{weld ? (
) : null}
); }