feat(uat-p4): inheritance polish - yacht dims, occupancy chip, map-flip flag
Phase 4 of the active UAT sweep wraps the inheritance/polish bucket. - BerthOccupancyChip: new shared component that surfaces the competing active interest on a non-available berth as a colour-coded chip with a stage badge. Adopted in LinkedBerthRowItem, BerthRecommenderPanel recommendation card, and InterestBerthStatusBanner; the banner aligns query keys with the chip so React Query dedupes the network call. - OverviewTab inheritance: getInterestById now ships a yachtDimensions block when the interest is linked to a yacht with dimensions. The Berth Requirements rows render a "↩ <value> from yacht" pill when the desired field is blank; clicking the pill copies the value into the interest. After a manual edit, a toast offers to write the new value back to the yacht record so the canonical truth stays in sync. - Map-flip inheritance: ExternalEoiUploadDialog and UploadForSigningDialog now expose a single "Mark berth(s) as Under Offer on the public map" checkbox that defaults ON when any in-bundle berth already has is_specific_interest=true. On submit, PATCHes the in-bundle berths that don't already match; sister surface to the EOI generate dialog's per-berth picker. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -218,10 +218,28 @@ interface TierInputs {
|
||||
activeInterestCount: number;
|
||||
lostCount: number;
|
||||
maxActiveStage: number;
|
||||
/** Berth's status column. Reconciles against the interest_berths
|
||||
* aggregates: a berth flagged "Under Offer" or "Sold" via the
|
||||
* status column alone (admin-set, NocoDB import, or a stale row
|
||||
* with no live interest_berths entry) shouldn't fall into Tier A.
|
||||
* Optional for backcompat — pure aggregate-based callers still
|
||||
* classify correctly when this is undefined. */
|
||||
status?: string;
|
||||
}
|
||||
|
||||
export function classifyTier(t: TierInputs): Tier {
|
||||
// Berth status overrides the aggregate path. A sold berth is
|
||||
// effectively closed — treat it as late stage. An Under Offer
|
||||
// berth has at least one party engaged even if interest_berths
|
||||
// doesn't echo them (e.g. admin manually flipped status). Both
|
||||
// collapse the "Open · Under Offer" contradiction surfaced in UAT
|
||||
// 2026-05-26. Sold > UnderOffer > active interest aggregates.
|
||||
const normStatus = (t.status ?? '').toLowerCase();
|
||||
if (normStatus === 'sold') return 'D';
|
||||
if (t.activeInterestCount > 0 && t.maxActiveStage >= LATE_STAGE_THRESHOLD) return 'D';
|
||||
if (normStatus === 'under offer' || normStatus === 'under_offer') {
|
||||
return t.activeInterestCount > 0 ? 'C' : 'C';
|
||||
}
|
||||
if (t.activeInterestCount > 0) return 'C';
|
||||
if (t.lostCount > 0) return 'B';
|
||||
return 'A';
|
||||
|
||||
Reference in New Issue
Block a user