+ {criteria.length} criteria configured · {criteria.filter((c) => c.enabled).length} enabled +
+ +No criteria configured yet.
++ Add the first criterion the rep needs to confirm before a deal can be qualified. +
+
+ {criterion.key}
+
+ + Pick a teammate or choose “Other…” to type any name. +
+ Deal pulse — {label} ({health.score}/100) +
+ {health.signals.length === 0 ? ( ++ Baseline score (50) — nothing notable yet. Log contact or progress the stage to move + the dial. +
+ ) : ( ++ Rule-based. Every signal traces to a date or stage you can see — no AI. +
++ {conflicts.length === 1 + ? `Berth ${conflicts[0]!.mooringNumber} is ${ + conflicts[0]!.status === 'sold' ? 'Sold' : 'Under Offer' + } to another deal.` + : `${conflicts.length} linked berths are no longer freely available.`} +
++ You can still progress this interest as a backup, but the rep on the other deal owns the + primary path. If their deal falls through, this one can step in. +
+
@@ -528,3 +581,43 @@ export function LinkedBerthsList({ interestId }: LinkedBerthsListProps) {
);
}
+
+/** Section header + body wrapper for the three-bucket layout. Kept inline
+ * because it's only used here — promoting it to /shared isn't worth the
+ * indirection for a card-header + a help line. */
+function BerthSection({
+ title,
+ hint,
+ count,
+ emptyText,
+ children,
+}: {
+ title: string;
+ hint: string;
+ count: number;
+ emptyText?: string;
+ children: React.ReactNode;
+}) {
+ return (
+ {hint}
+ {emptyText}
+
+ Records that money was received or refunded. No invoices are issued — the bank handles
+ that.
+
+ No payments recorded yet.
+
+ All criteria confirmed — this lead is ready to qualify.
+
+ {gaps.length === 1
+ ? 'A past milestone is missing its date.'
+ : `${gaps.length} past milestones are missing their dates.`}
+
+ Backfill {gaps.join(' · ')} below so reports show accurate cycle times.
+
+ Email the client a one-time link to a public form pre-filled with what we have on file.
+ Submissions auto-update this client + interest record.
+
+ Upload anything that didn't flow through the system automatically. Reservations,
+ deposit invoicing, and client billing are handled outside the CRM — this checklist is for
+ the paperwork that lives on the deal itself.
+
+ All required documents are attached. Anything else you upload here will appear in the
+ client's signed-docs folder.
+ {slot.description}
+ Reminders are personal nudges — a follow-up call, a note to yourself, or something a
+ teammate needs to action by a date. They show up in your dashboard, the daily digest
+ email, and on whichever client / interest / berth you link them to.
+
+ {title}
+ {count > 0 ? (
+ ({count})
+ ) : null}
+
+ Payments
+
+ {payments.map((p) => (
+
+ )}
+
+ Qualification
+ {fullyQualified ? (
+
+
+ {criteria.map((c) => (
+
+
+ {showPromoteHint ? (
+ Need more info before drafting the EOI?
+