// ─── Pipeline Stages ───────────────────────────────────────────────────────── export const PIPELINE_STAGES = [ 'open', 'details_sent', 'in_communication', 'eoi_sent', 'eoi_signed', 'deposit_10pct', 'contract_sent', 'contract_signed', 'completed', ] as const; export type PipelineStage = (typeof PIPELINE_STAGES)[number]; export const STAGE_LABELS: Record = { open: 'Open', details_sent: 'Details Sent', in_communication: 'In Comms', eoi_sent: 'EOI Sent', eoi_signed: 'EOI Signed', deposit_10pct: 'Deposit 10%', contract_sent: 'Contract Sent', contract_signed: 'Contract Signed', completed: 'Completed', }; export const STAGE_BADGE: Record = { open: 'bg-slate-100 text-slate-700', details_sent: 'bg-blue-100 text-blue-700', in_communication: 'bg-sky-100 text-sky-700', eoi_sent: 'bg-indigo-100 text-indigo-700', eoi_signed: 'bg-amber-100 text-amber-700', deposit_10pct: 'bg-orange-100 text-orange-700', contract_sent: 'bg-yellow-100 text-yellow-700', contract_signed: 'bg-green-100 text-green-700', completed: 'bg-emerald-100 text-emerald-700', }; export const STAGE_DOT: Record = { open: 'bg-slate-400', details_sent: 'bg-blue-500', in_communication: 'bg-sky-500', eoi_sent: 'bg-indigo-500', eoi_signed: 'bg-amber-500', deposit_10pct: 'bg-orange-500', contract_sent: 'bg-yellow-500', contract_signed: 'bg-green-500', completed: 'bg-emerald-500', }; // Default revenue-forecast probability weights per stage (0–1). // Editable per port via settings (`pipeline_weights`); these are the fallbacks. export const STAGE_WEIGHTS: Record = { open: 0.05, details_sent: 0.1, in_communication: 0.2, eoi_sent: 0.4, eoi_signed: 0.6, deposit_10pct: 0.75, contract_sent: 0.85, contract_signed: 0.95, completed: 1.0, }; // Allowed transitions out of each stage. Used by changeInterestStage to guard // against accidental skips (e.g. dragging a card from Completed back to Open, // or jumping Open straight to Completed). Forward moves of 1-2 stages are // permitted; backward moves are limited to the immediate predecessor unless // the lifecycle (EOI/contract chain) needs an explicit rewind. export const STAGE_TRANSITIONS: Record = { open: ['details_sent', 'in_communication', 'eoi_sent', 'eoi_signed'], details_sent: ['open', 'in_communication', 'eoi_sent', 'eoi_signed'], in_communication: ['open', 'details_sent', 'eoi_sent', 'eoi_signed'], eoi_sent: ['in_communication', 'eoi_signed', 'deposit_10pct'], eoi_signed: ['eoi_sent', 'deposit_10pct', 'contract_sent', 'contract_signed'], deposit_10pct: ['eoi_signed', 'contract_sent', 'contract_signed'], contract_sent: ['eoi_signed', 'deposit_10pct', 'contract_signed'], contract_signed: ['contract_sent', 'deposit_10pct', 'completed'], completed: ['contract_signed'], }; export function canTransitionStage(from: string, to: string): boolean { if (from === to) return true; const fromStage = safeStage(from); const toStage = safeStage(to); return STAGE_TRANSITIONS[fromStage].includes(toStage); } export function safeStage(value: string | null | undefined): PipelineStage { return PIPELINE_STAGES.includes(value as PipelineStage) ? (value as PipelineStage) : 'open'; } export function stageLabel(stage: string | null | undefined): string { return STAGE_LABELS[safeStage(stage)]; } export function stageBadgeClass(stage: string | null | undefined): string { return STAGE_BADGE[safeStage(stage)]; } export function stageDotClass(stage: string | null | undefined): string { return STAGE_DOT[safeStage(stage)]; } // ─── Berth Statuses ────────────────────────────────────────────────────────── export const BERTH_STATUSES = ['available', 'under_offer', 'sold'] as const; export type BerthStatus = (typeof BERTH_STATUSES)[number]; // ─── Lead Categories ───────────────────────────────────────────────────────── export const LEAD_CATEGORIES = ['general_interest', 'specific_qualified', 'hot_lead'] as const; export type LeadCategory = (typeof LEAD_CATEGORIES)[number]; // ─── Document Types ────────────────────────────────────────────────────────── export const DOCUMENT_TYPES = ['eoi', 'contract', 'nda', 'reservation_agreement', 'other'] as const; export type DocumentType = (typeof DOCUMENT_TYPES)[number]; // ─── Document Statuses ─────────────────────────────────────────────────────── export const DOCUMENT_STATUSES = [ 'draft', 'sent', 'partially_signed', 'completed', 'expired', 'cancelled', ] as const; export type DocumentStatus = (typeof DOCUMENT_STATUSES)[number]; // ─── Expense Categories ────────────────────────────────────────────────────── export const EXPENSE_CATEGORIES = [ 'fuel', 'maintenance', 'cleaning', 'docking', 'insurance', 'utilities', 'marina_fees', 'repairs', 'equipment', 'crew', 'administration', 'marketing', 'travel', 'entertainment', 'other', ] as const; export type ExpenseCategory = (typeof EXPENSE_CATEGORIES)[number]; // ─── Payment Methods ───────────────────────────────────────────────────────── export const PAYMENT_METHODS = [ 'bank_transfer', 'credit_card', 'debit_card', 'cash', 'cheque', 'crypto', 'other', ] as const; export type PaymentMethod = (typeof PAYMENT_METHODS)[number]; // ─── Notification Types ────────────────────────────────────────────────────── export const NOTIFICATION_TYPES = [ // Interest / pipeline 'interest_stage_changed', 'interest_created', 'interest_assigned', // Documents 'document_sent', 'document_signed', 'document_completed', 'document_expired', 'document_reminder', // Reminders 'reminder_due', 'reminder_overdue', 'reminder_assigned', // Financial 'invoice_sent', 'invoice_paid', 'invoice_overdue', // Notes 'mention', // Email 'email_received', // System 'system_alert', 'job_failed', 'bulk_operation_complete', 'export_ready', // Berths 'berth_status_changed', 'berth_waiting_list_update', ] as const; export type NotificationType = (typeof NOTIFICATION_TYPES)[number];