From e13232e2ad97208c2993cc7182aa526c73d4fe91 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 9 May 2026 04:10:24 +0200 Subject: [PATCH] feat(berths): NocoDB-aligned dropdown enums + dual-unit auto-fill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pull verbatim SingleSelect choices from NocoDB Berths via MCP and lock them into BERTH_*_OPTIONS / _TYPES in lib/constants.ts: Side Pontoon (10 values), Mooring Type (5), Cleat Type (2), Cleat Capacity (2), Bollard Type (2), Bollard Capacity (2), Access (5), Area (A–E), Bow Facing (4-value UX-only constraint over a SingleLineText). Power Capacity / Voltage stay numeric inputs (NocoDB stores Number). Add `toSelectOptions()` mapper for shadcn ``. Inline `EditableSpec` gains `selectOptions` for the variant and `linkedUnit { field, multiplier }` to auto-patch the metric column on save (× 0.3048 for ft→m on length, width, draft, nominal boat size, water depth). Promote nominal boat size + tenure type from read-only `` to `` so reps can edit them. Tenure type currently uses the validator's `'permanent' | 'fixed_term'` set; will swap to per-port configurable list once Vocabularies admin lands (Wave 5). Mobile berth cards: replace status-coloured stripe with `mooringLetterDot()` so it groups by dock letter; status conveyed by the existing pill below. Berth detail header: "{Letter} Dock" chip instead of bare "A" / "B" text. Berth area filter: ` + setValue('bowFacing', v)} + options={BERTH_BOW_FACING_OPTIONS} + />
diff --git a/src/components/berths/berth-tabs.tsx b/src/components/berths/berth-tabs.tsx index c3fba85c..26693efd 100644 --- a/src/components/berths/berth-tabs.tsx +++ b/src/components/berths/berth-tabs.tsx @@ -8,6 +8,17 @@ import { EntityActivityFeed } from '@/components/shared/entity-activity-feed'; import { InlineEditableField } from '@/components/shared/inline-editable-field'; import { InlineTagEditor } from '@/components/shared/inline-tag-editor'; import { apiFetch } from '@/lib/api/client'; +import { + BERTH_ACCESS_OPTIONS, + BERTH_BOLLARD_CAPACITIES, + BERTH_BOLLARD_TYPES, + BERTH_BOW_FACING_OPTIONS, + BERTH_CLEAT_CAPACITIES, + BERTH_CLEAT_TYPES, + BERTH_MOORING_TYPES, + BERTH_SIDE_PONTOON_OPTIONS, + toSelectOptions, +} from '@/lib/constants'; import { BerthReservationsTab } from './berth-reservations-tab'; import { BerthInterestsTab } from './berth-interests-tab'; import { BerthInterestPulse } from './berth-interest-pulse'; @@ -96,6 +107,8 @@ function EditableSpec({ patch, numeric = false, suffix, + selectOptions, + linkedUnit, }: { label: string; value: string | null; @@ -103,28 +116,54 @@ function EditableSpec({ patch: ReturnType; numeric?: boolean; suffix?: string; + /** When provided, the inline editor uses a `` `{value,label}` objects. */ +export function toSelectOptions( + values: T, +): Array<{ value: T[number]; label: T[number] }> { + return values.map((v) => ({ value: v, label: v })); +} + // ─── Lead Categories ───────────────────────────────────────────────────────── export const LEAD_CATEGORIES = ['general_interest', 'specific_qualified', 'hot_lead'] as const;