"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { Badge, Button, Card, ErrorBanner, Field, Input, Modal, PageHeader, Select, Textarea } from "@/components/ui"; import { apiFetch, ApiClientError } from "@/lib/client-api"; interface TemplateRow { id: string; name: string; machineId: string | null; machineName: string | null; defaultSettings: string | null; defaultInstructions: string | null; qcRequired: boolean; active: boolean; } interface MachineOption { id: string; name: string; } export default function TemplatesClient({ initialTemplates, machines, }: { initialTemplates: TemplateRow[]; machines: MachineOption[]; }) { const router = useRouter(); const [edit, setEdit] = useState(null); const [newOpen, setNewOpen] = useState(false); return (
setNewOpen(true)}>New template} /> {initialTemplates.map((t) => ( ))} {initialTemplates.length === 0 && ( )}
Name Machine QC Status
{t.name} {t.machineName ?? "—"} {t.qcRequired ? required : } {t.active ? "active" : "inactive"}
No operation templates yet.
{newOpen && ( setNewOpen(false)} onSaved={() => router.refresh()} /> )} {edit && ( setEdit(null)} onSaved={() => router.refresh()} /> )}
); } function TemplateModal({ template, machines, onClose, onSaved, }: { template?: TemplateRow; machines: MachineOption[]; onClose: () => void; onSaved: () => void; }) { const editing = !!template; const [name, setName] = useState(template?.name ?? ""); const [machineId, setMachineId] = useState(template?.machineId ?? ""); const [instructions, setInstructions] = useState(template?.defaultInstructions ?? ""); const [settings, setSettings] = useState(template?.defaultSettings ?? ""); const [qcRequired, setQcRequired] = useState(template?.qcRequired ?? false); const [active, setActive] = useState(template?.active ?? true); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); async function submit(e: React.FormEvent) { e.preventDefault(); setBusy(true); setError(null); try { const body = { name, machineId: machineId || null, defaultInstructions: instructions, defaultSettings: settings, qcRequired, ...(editing ? { active } : {}), }; if (editing) { await apiFetch(`/api/v1/operation-templates/${template!.id}`, { method: "PATCH", body: JSON.stringify(body), }); } else { await apiFetch("/api/v1/operation-templates", { method: "POST", body: JSON.stringify(body), }); } onSaved(); onClose(); } catch (err) { setError(err instanceof ApiClientError ? err.message : "Save failed"); } finally { setBusy(false); } } async function deactivate() { if (!template || !confirm(`Deactivate ${template.name}?`)) return; setBusy(true); setError(null); try { await apiFetch(`/api/v1/operation-templates/${template.id}`, { method: "DELETE" }); onSaved(); onClose(); } catch (err) { setError(err instanceof ApiClientError ? err.message : "Deactivate failed"); setBusy(false); } } return ( {editing && template!.active && ( )}
} >
setName(e.target.value)} required />