chore(style): codebase em-dash sweep + minor layout polish
Replaces every em-dash and en-dash with regular ASCII hyphens across comments, JSX strings, and dev-facing logs. Mostly cosmetic but stops the inconsistent mix that crept in over the last few months (some files used em-dashes in comments, others didn't, some used both). Bundles two small dashboard-layout tweaks that touch a couple of already-modified files: - (dashboard)/layout.tsx main padding goes from p-6 to pt-3 px-6 pb-6 so page content sits closer to the topbar. - Sidebar now receives the ports list it needs for the footer port switcher. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -42,7 +42,7 @@ function setText(form: ReturnType<PDFDocument['getForm']>, name: string, value:
|
||||
try {
|
||||
form.getTextField(name).setText(value);
|
||||
} catch {
|
||||
// Field absent or wrong type — skip silently so a slightly different PDF
|
||||
// Field absent or wrong type - skip silently so a slightly different PDF
|
||||
// template still produces output. Missing field issues surface in QA, not
|
||||
// at runtime as a 500.
|
||||
}
|
||||
@@ -80,7 +80,7 @@ export async function fillEoiFormFields(
|
||||
setText(form, 'Name', context.client.fullName);
|
||||
setText(form, 'Email', context.client.primaryEmail ?? '');
|
||||
setText(form, 'Address', formatAddress(context.client.address));
|
||||
// Yacht + berth (EOI Section 3) are optional — leave the AcroForm fields
|
||||
// Yacht + berth (EOI Section 3) are optional - leave the AcroForm fields
|
||||
// blank when the interest hasn't been linked to either.
|
||||
setText(form, 'Yacht Name', context.yacht?.name ?? '');
|
||||
setText(form, 'Length', context.yacht?.lengthFt ?? '');
|
||||
|
||||
@@ -4,16 +4,86 @@ export const berthSpecTemplate: Template = {
|
||||
basePdf: 'BLANK_PDF' as unknown as string,
|
||||
schemas: [
|
||||
[
|
||||
{ name: 'portName', type: 'text', position: { x: 20, y: 15 }, width: 100, height: 10, fontSize: 16 },
|
||||
{ name: 'title', type: 'text', position: { x: 20, y: 30 }, width: 170, height: 8, fontSize: 14 },
|
||||
{ name: 'berthInfo', type: 'text', position: { x: 20, y: 45 }, width: 80, height: 25, fontSize: 9 },
|
||||
{ name: 'dimensions', type: 'text', position: { x: 110, y: 45 }, width: 80, height: 25, fontSize: 9 },
|
||||
{ name: 'pricing', type: 'text', position: { x: 20, y: 75 }, width: 80, height: 20, fontSize: 9 },
|
||||
{ name: 'tenure', type: 'text', position: { x: 110, y: 75 }, width: 80, height: 20, fontSize: 9 },
|
||||
{ name: 'infrastructure', type: 'text', position: { x: 20, y: 100 }, width: 170, height: 25, fontSize: 9 },
|
||||
{ name: 'waitingList', type: 'text', position: { x: 20, y: 130 }, width: 170, height: 50, fontSize: 8 },
|
||||
{ name: 'maintenanceLog', type: 'text', position: { x: 20, y: 185 }, width: 170, height: 75, fontSize: 8 },
|
||||
{ name: 'generatedAt', type: 'text', position: { x: 20, y: 275 }, width: 170, height: 6, fontSize: 7 },
|
||||
{
|
||||
name: 'portName',
|
||||
type: 'text',
|
||||
position: { x: 20, y: 15 },
|
||||
width: 100,
|
||||
height: 10,
|
||||
fontSize: 16,
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
position: { x: 20, y: 30 },
|
||||
width: 170,
|
||||
height: 8,
|
||||
fontSize: 14,
|
||||
},
|
||||
{
|
||||
name: 'berthInfo',
|
||||
type: 'text',
|
||||
position: { x: 20, y: 45 },
|
||||
width: 80,
|
||||
height: 25,
|
||||
fontSize: 9,
|
||||
},
|
||||
{
|
||||
name: 'dimensions',
|
||||
type: 'text',
|
||||
position: { x: 110, y: 45 },
|
||||
width: 80,
|
||||
height: 25,
|
||||
fontSize: 9,
|
||||
},
|
||||
{
|
||||
name: 'pricing',
|
||||
type: 'text',
|
||||
position: { x: 20, y: 75 },
|
||||
width: 80,
|
||||
height: 20,
|
||||
fontSize: 9,
|
||||
},
|
||||
{
|
||||
name: 'tenure',
|
||||
type: 'text',
|
||||
position: { x: 110, y: 75 },
|
||||
width: 80,
|
||||
height: 20,
|
||||
fontSize: 9,
|
||||
},
|
||||
{
|
||||
name: 'infrastructure',
|
||||
type: 'text',
|
||||
position: { x: 20, y: 100 },
|
||||
width: 170,
|
||||
height: 25,
|
||||
fontSize: 9,
|
||||
},
|
||||
{
|
||||
name: 'waitingList',
|
||||
type: 'text',
|
||||
position: { x: 20, y: 130 },
|
||||
width: 170,
|
||||
height: 50,
|
||||
fontSize: 8,
|
||||
},
|
||||
{
|
||||
name: 'maintenanceLog',
|
||||
type: 'text',
|
||||
position: { x: 20, y: 185 },
|
||||
width: 170,
|
||||
height: 75,
|
||||
fontSize: 8,
|
||||
},
|
||||
{
|
||||
name: 'generatedAt',
|
||||
type: 'text',
|
||||
position: { x: 20, y: 275 },
|
||||
width: 170,
|
||||
height: 6,
|
||||
fontSize: 7,
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
@@ -35,22 +105,23 @@ export function buildBerthSpecInputs(
|
||||
.filter(Boolean)
|
||||
.join('\n');
|
||||
|
||||
const dimensions = [
|
||||
berth.lengthFt
|
||||
? `Length: ${berth.lengthFt}ft${berth.lengthM ? ` / ${berth.lengthM}m` : ''}`
|
||||
: null,
|
||||
berth.widthFt
|
||||
? `Beam: ${berth.widthFt}ft${berth.widthM ? ` / ${berth.widthM}m` : ''}${berth.widthIsMinimum ? ' (min)' : ''}`
|
||||
: null,
|
||||
berth.draftFt
|
||||
? `Draft: ${berth.draftFt}ft${berth.draftM ? ` / ${berth.draftM}m` : ''}`
|
||||
: null,
|
||||
berth.waterDepth
|
||||
? `Water depth: ${berth.waterDepth}ft${berth.waterDepthM ? ` / ${berth.waterDepthM}m` : ''}${berth.waterDepthIsMinimum ? ' (min)' : ''}`
|
||||
: null,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join('\n') || 'Dimensions not specified';
|
||||
const dimensions =
|
||||
[
|
||||
berth.lengthFt
|
||||
? `Length: ${berth.lengthFt}ft${berth.lengthM ? ` / ${berth.lengthM}m` : ''}`
|
||||
: null,
|
||||
berth.widthFt
|
||||
? `Beam: ${berth.widthFt}ft${berth.widthM ? ` / ${berth.widthM}m` : ''}${berth.widthIsMinimum ? ' (min)' : ''}`
|
||||
: null,
|
||||
berth.draftFt
|
||||
? `Draft: ${berth.draftFt}ft${berth.draftM ? ` / ${berth.draftM}m` : ''}`
|
||||
: null,
|
||||
berth.waterDepth
|
||||
? `Water depth: ${berth.waterDepth}ft${berth.waterDepthM ? ` / ${berth.waterDepthM}m` : ''}${berth.waterDepthIsMinimum ? ' (min)' : ''}`
|
||||
: null,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join('\n') || 'Dimensions not specified';
|
||||
|
||||
const pricing = berth.price
|
||||
? `Price: ${berth.priceCurrency ?? 'USD'} ${Number(berth.price).toLocaleString()}`
|
||||
@@ -65,25 +136,30 @@ export function buildBerthSpecInputs(
|
||||
.filter(Boolean)
|
||||
.join('\n');
|
||||
|
||||
const infrastructure = [
|
||||
berth.mooringType ? `Mooring type: ${berth.mooringType}` : null,
|
||||
berth.powerCapacity ? `Power: ${berth.powerCapacity}${berth.voltage ? ` / ${berth.voltage}V` : ''}` : null,
|
||||
berth.cleatType ? `Cleat: ${berth.cleatType}${berth.cleatCapacity ? ` (${berth.cleatCapacity})` : ''}` : null,
|
||||
berth.bollardType
|
||||
? `Bollard: ${berth.bollardType}${berth.bollardCapacity ? ` (${berth.bollardCapacity})` : ''}`
|
||||
: null,
|
||||
berth.sidePontoon ? `Side pontoon: ${berth.sidePontoon}` : null,
|
||||
berth.access ? `Access: ${berth.access}` : null,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' | ') || 'Infrastructure details not specified';
|
||||
const infrastructure =
|
||||
[
|
||||
berth.mooringType ? `Mooring type: ${berth.mooringType}` : null,
|
||||
berth.powerCapacity
|
||||
? `Power: ${berth.powerCapacity}${berth.voltage ? ` / ${berth.voltage}V` : ''}`
|
||||
: null,
|
||||
berth.cleatType
|
||||
? `Cleat: ${berth.cleatType}${berth.cleatCapacity ? ` (${berth.cleatCapacity})` : ''}`
|
||||
: null,
|
||||
berth.bollardType
|
||||
? `Bollard: ${berth.bollardType}${berth.bollardCapacity ? ` (${berth.bollardCapacity})` : ''}`
|
||||
: null,
|
||||
berth.sidePontoon ? `Side pontoon: ${berth.sidePontoon}` : null,
|
||||
berth.access ? `Access: ${berth.access}` : null,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' | ') || 'Infrastructure details not specified';
|
||||
|
||||
const waitingListText =
|
||||
waitingList.length > 0
|
||||
? waitingList
|
||||
.map(
|
||||
(w) =>
|
||||
`${w.position}. ${w.clientName ?? 'Unknown'}${w.priority === 'high' ? ' [HIGH]' : ''}${w.notes ? ` — ${w.notes}` : ''}`,
|
||||
`${w.position}. ${w.clientName ?? 'Unknown'}${w.priority === 'high' ? ' [HIGH]' : ''}${w.notes ? ` - ${w.notes}` : ''}`,
|
||||
)
|
||||
.join('\n')
|
||||
: 'No clients on waiting list';
|
||||
@@ -100,7 +176,7 @@ export function buildBerthSpecInputs(
|
||||
|
||||
return {
|
||||
portName: (port?.name as string) ?? 'Port Nimara',
|
||||
title: `Berth Specification — Mooring ${berth.mooringNumber}`,
|
||||
title: `Berth Specification - Mooring ${berth.mooringNumber}`,
|
||||
berthInfo,
|
||||
dimensions,
|
||||
pricing,
|
||||
|
||||
@@ -130,7 +130,7 @@ export function buildClientSummaryInputs(
|
||||
? interestList
|
||||
.map(
|
||||
(i) =>
|
||||
`• ${i.pipelineStage ?? 'open'}${i.berthMooringNumber ? ` — Berth ${i.berthMooringNumber}` : ''}${i.leadCategory ? ` [${i.leadCategory}]` : ''} (${new Date(i.createdAt as string | Date).toLocaleDateString('en-GB')})`,
|
||||
`• ${i.pipelineStage ?? 'open'}${i.berthMooringNumber ? ` - Berth ${i.berthMooringNumber}` : ''}${i.leadCategory ? ` [${i.leadCategory}]` : ''} (${new Date(i.createdAt as string | Date).toLocaleDateString('en-GB')})`,
|
||||
)
|
||||
.join('\n')
|
||||
: 'No pipeline interests on file';
|
||||
@@ -147,7 +147,7 @@ export function buildClientSummaryInputs(
|
||||
|
||||
return {
|
||||
portName: (port?.name as string) ?? 'Port Nimara',
|
||||
title: `Client Summary — ${client.fullName ?? ''}`,
|
||||
title: `Client Summary - ${client.fullName ?? ''}`,
|
||||
clientInfo,
|
||||
contacts: contactsText,
|
||||
yachts: yachtsText,
|
||||
|
||||
@@ -61,7 +61,7 @@ export function getStandardEoiTemplateHtml(): string {
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Expression of Interest — Letter of Intent</title>
|
||||
<title>Expression of Interest - Letter of Intent</title>
|
||||
<style>
|
||||
@page {
|
||||
size: letter;
|
||||
@@ -165,7 +165,7 @@ export function getStandardEoiTemplateHtml(): string {
|
||||
<body>
|
||||
<div class="header">
|
||||
<div class="port-name">{{port.name}}</div>
|
||||
<div class="doc-title">Expression of Interest — Letter of Intent</div>
|
||||
<div class="doc-title">Expression of Interest - Letter of Intent</div>
|
||||
</div>
|
||||
|
||||
<div class="meta">
|
||||
@@ -317,7 +317,7 @@ export function getStandardEoiTemplateHtml(): string {
|
||||
<div class="signatures">
|
||||
<div class="slot">
|
||||
<div class="sig-line">
|
||||
Applicant — {{client.fullName}}
|
||||
Applicant - {{client.fullName}}
|
||||
</div>
|
||||
<div class="muted" style="font-size:10pt; margin-top:2pt;">Date: __________________</div>
|
||||
</div>
|
||||
|
||||
@@ -152,7 +152,7 @@ export function buildInterestSummaryInputs(
|
||||
|
||||
return {
|
||||
portName: (port?.name as string) ?? 'Port Nimara',
|
||||
title: `Interest Summary — ${client?.fullName ?? 'Unknown Client'}`,
|
||||
title: `Interest Summary - ${client?.fullName ?? 'Unknown Client'}`,
|
||||
clientInfo,
|
||||
berthInfo,
|
||||
stageAndCategory,
|
||||
|
||||
Reference in New Issue
Block a user