Mirrors the Place-of-Delivery (#19) pattern: an admin clause library that feeds the PO T&C fields as dropdowns. (No "work order" type — POs only, per steer.) - schema + migration: TermsCondition (category enum + text + isActive); the migration seeds the prior TC_DEFAULTS as the starting clauses. - permission manage_terms (Manager + SuperUser + Admin). - admin screen /admin/terms: table + Add/Edit dialogs + activate/deactivate + delete (mirrors /admin/delivery-locations); sidebar link under Administration. - PO forms (new / edit / manager-edit): the five named T&C slots (Delivery / Dispatch / Inspection / Transit Insurance / Payment Terms) become a shared <TermsField> select sourced from active clauses of that category; "Others" stays free text; the fixed boilerplate lines are untouched. - tc* columns stay free-text SNAPSHOTS (export/import unchanged); a current value not among active clauses is preserved as a "(current)" option. - tests: terms CRUD + permission guard + grouping helper (6). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
38 lines
1.1 KiB
TypeScript
38 lines
1.1 KiB
TypeScript
"use client";
|
|
|
|
/**
|
|
* A single PO Terms & Conditions slot (issue #11) — a native
|
|
* <select name={field}> sourced from the admin-managed clauses for its category.
|
|
* Plain HTML so it works with the forms' native FormData submission.
|
|
*
|
|
* `options` are the active clause texts (also the stored value). `current` is the
|
|
* PO's existing/default value for this slot; if it isn't one of the active
|
|
* options (a removed clause, or an older custom value) it is preserved as a
|
|
* leading "(current)" option so an edit never silently drops it.
|
|
*/
|
|
export function TermsField({
|
|
field,
|
|
options,
|
|
current,
|
|
className,
|
|
}: {
|
|
field: string;
|
|
options: string[];
|
|
current?: string | null;
|
|
className?: string;
|
|
}) {
|
|
const cur = (current ?? "").trim();
|
|
const currentMissing = cur.length > 0 && !options.includes(cur);
|
|
|
|
return (
|
|
<select name={field} defaultValue={cur} className={className}>
|
|
<option value="">—</option>
|
|
{currentMissing && <option value={cur}>{cur} (current)</option>}
|
|
{options.map((o) => (
|
|
<option key={o} value={o}>
|
|
{o}
|
|
</option>
|
|
))}
|
|
</select>
|
|
);
|
|
}
|