import { Badge, DataTable, DocumentShell, KeyValueGrid, Section, type BadgeTone, } from '@/lib/pdf/brand-kit'; interface BerthRow { mooringNumber: string | null; area?: string | null; status?: string | null; nominalBoatSize?: string | null; bowFacing?: string | null; lengthFt?: string | null; lengthM?: string | null; widthFt?: string | null; widthM?: string | null; widthIsMinimum?: boolean | null; draftFt?: string | null; draftM?: string | null; waterDepth?: string | null; waterDepthM?: string | null; waterDepthIsMinimum?: boolean | null; price?: string | number | null; priceCurrency?: string | null; tenureType?: string | null; tenureYears?: string | number | null; tenureStartDate?: string | null; tenureEndDate?: string | null; mooringType?: string | null; powerCapacity?: string | number | null; voltage?: string | number | null; cleatType?: string | null; cleatCapacity?: string | null; bollardType?: string | null; bollardCapacity?: string | null; sidePontoon?: string | null; access?: string | null; } export interface BerthSpecWaitingRow { position: number | null; priority: string | null; clientName: string; notes?: string | null; } export interface BerthSpecMaintenanceRow { performedDate: string | null; category: string | null; description: string | null; cost: string | number | null; costCurrency: string | null; } export interface BerthSpecPdfProps { portName: string; logoBuffer: Buffer | null; berth: BerthRow; waitingList: BerthSpecWaitingRow[]; maintenance: BerthSpecMaintenanceRow[]; } const STATUS_TONE: Record = { available: 'success', under_offer: 'warning', sold: 'accent', reserved: 'neutral', maintenance: 'danger', }; function dim(ft?: string | null, m?: string | null, minimum?: boolean | null): string { if (!ft && !m) return '—'; const parts = [ft ? `${ft}ft` : null, m ? `${m}m` : null].filter(Boolean); return `${parts.join(' / ')}${minimum ? ' (min)' : ''}`; } function fmtPrice( v: string | number | null | undefined, currency: string | null | undefined, ): string { if (v === null || v === undefined) return 'TBD'; const n = Number(v); if (!Number.isFinite(n)) return String(v); return `${currency ?? 'USD'} ${n.toLocaleString()}`; } export function BerthSpecPdf({ portName, logoBuffer, berth, waitingList, maintenance, }: BerthSpecPdfProps) { const status = (berth.status ?? 'available').toLowerCase(); const docMeta = `Mooring ${berth.mooringNumber ?? '—'}${berth.area ? ` · ${berth.area}` : ''}`; return (
columns={[ { header: '#', flex: 0.5, render: (w) => String(w.position ?? '—') }, { header: 'Client', flex: 3, render: (w) => w.clientName }, { header: 'Priority', flex: 1, render: (w) => w.priority === 'high' ? : (w.priority ?? '—'), }, { header: 'Notes', flex: 3, render: (w) => w.notes ?? '—' }, ]} rows={waitingList} emptyMessage="No clients on waiting list." />
columns={[ { header: 'Date', flex: 1.5, render: (m) => m.performedDate ?? '—' }, { header: 'Category', flex: 1.5, render: (m) => m.category ?? '—' }, { header: 'Description', flex: 4, render: (m) => m.description ?? '—' }, { header: 'Cost', flex: 1.5, align: 'right', render: (m) => fmtPrice(m.cost, m.costCurrency), }, ]} rows={maintenance} emptyMessage="No maintenance records." />
); }