"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { upsertRequirement, deleteRequirement } from "./actions"; const INPUT = "rounded-lg border border-neutral-300 px-3 py-2 text-sm focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-500/20"; const BTN = "rounded-lg bg-primary-600 px-4 py-2 text-sm font-semibold text-white hover:bg-primary-700 disabled:opacity-60"; type Opt = { id: string; name: string }; type RankOpt = { id: string; code: string; name: string }; type Req = { id: string; vessel: string; rank: string; minStrength: number }; export function CrewStrengthManager({ requirements, vessels, ranks }: { requirements: Req[]; vessels: Opt[]; ranks: RankOpt[] }) { const router = useRouter(); const [f, setF] = useState({ vesselId: "", rankId: "", minStrength: "1" }); const [pending, setPending] = useState(false); const [error, setError] = useState(""); async function submit(e: React.FormEvent) { e.preventDefault(); setPending(true); setError(""); const fd = new FormData(); fd.set("vesselId", f.vesselId); fd.set("rankId", f.rankId); fd.set("minStrength", f.minStrength); const res = await upsertRequirement(fd); setPending(false); if ("error" in res) setError(res.error); else { setF({ vesselId: "", rankId: "", minStrength: "1" }); router.refresh(); } } return (

Crew strength

Required crew per rank, per vessel. Drives the leave-clash backfill — a leave that drops cover below the required strength auto-raises a requisition.

setF({ ...f, minStrength: e.target.value })} required />
{error &&

{error}

}
{requirements.length === 0 ? ( ) : requirements.map((r) => ( ))}
Vessel Rank Min strength
No requirements set. Unconfigured rank/vessel pairs default to a strength of 1.
{r.vessel} {r.rank} {r.minStrength}
); }