pelagia-portal/App/components/po/delivery-location-field.tsx
Hardik 5aae45299b
All checks were successful
PR checks / checks (pull_request) Successful in 42s
PR checks / integration (pull_request) Successful in 30s
feat(po): admin-managed delivery locations + Place of Delivery dropdown (#19)
Replaces the free-text "Place of Delivery" with a dropdown sourced from a new
admin-managed Delivery Locations list (each = a Company FK + free-text address).

- schema + migration: new DeliveryLocation model (companyId, address, isActive).
- permission: manage_delivery_locations granted to Manager + SuperUser + Admin
  (Manager-accessible, not admin-only, per the issue).
- admin screen /admin/delivery-locations: table + Add/Edit dialogs +
  activate/deactivate + delete (mirrors /admin/sites); sidebar link under
  Administration for Manager/SuperUser/Admin.
- PO forms (new / edit / manager-edit): shared <DeliveryLocationField> native
  select populated from active locations, formatted "Company — address".
- PurchaseOrder.placeOfDelivery stays a free-text SNAPSHOT (no FK) — the dropdown
  only changes how the value is picked, so export/import/historical POs are
  unchanged, and an edit preserves a current value not in the list as a
  "(current)" option. Deleting a location is therefore always safe.
- tests: delivery-location CRUD + permission guard (6).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 02:08:59 +05:30

36 lines
1.2 KiB
TypeScript

"use client";
/**
* Place-of-Delivery dropdown (issue #19) — a native <select name="placeOfDelivery">
* sourced from the admin-managed delivery locations. Plain HTML so it works with
* the forms' native FormData submission (no client state needed).
*
* `options` are the formatted "Company — address" strings (also the stored value).
* `current` is the PO's existing place-of-delivery; if it isn't one of the active
* options (legacy / imported / a since-removed location) it is preserved as a
* leading "(current)" option so an edit never silently drops it.
*/
export function DeliveryLocationField({
options,
current,
className,
}: {
options: string[];
current?: string | null;
className?: string;
}) {
const cur = (current ?? "").trim();
const currentMissing = cur.length > 0 && !options.includes(cur);
return (
<select name="placeOfDelivery" defaultValue={cur} className={className}>
<option value=""> Select a delivery location </option>
{currentMissing && <option value={cur}>{cur} (current)</option>}
{options.map((o) => (
<option key={o} value={o}>
{o}
</option>
))}
</select>
);
}