Auto-format all files modified during the documents-hub-split feature branch that were not yet aligned with the project's Prettier config (single quotes, semicolons, trailing commas). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
87 lines
2.4 KiB
TypeScript
87 lines
2.4 KiB
TypeScript
import type { Template } from '@pdfme/common';
|
|
|
|
import type { OccupancyData } from '@/lib/services/report-generators';
|
|
|
|
export const occupancyReportTemplate: Template = {
|
|
basePdf: 'BLANK_PDF' as unknown as string,
|
|
schemas: [
|
|
[
|
|
{
|
|
name: 'reportTitle',
|
|
type: 'text',
|
|
position: { x: 20, y: 15 },
|
|
width: 170,
|
|
height: 12,
|
|
fontSize: 20,
|
|
},
|
|
{
|
|
name: 'portName',
|
|
type: 'text',
|
|
position: { x: 20, y: 30 },
|
|
width: 130,
|
|
height: 8,
|
|
fontSize: 11,
|
|
},
|
|
{
|
|
name: 'generatedAt',
|
|
type: 'text',
|
|
position: { x: 140, y: 30 },
|
|
width: 50,
|
|
height: 8,
|
|
fontSize: 9,
|
|
},
|
|
{
|
|
name: 'occupancyRate',
|
|
type: 'text',
|
|
position: { x: 20, y: 50 },
|
|
width: 170,
|
|
height: 20,
|
|
fontSize: 16,
|
|
},
|
|
{
|
|
name: 'statusBreakdown',
|
|
type: 'text',
|
|
position: { x: 20, y: 80 },
|
|
width: 170,
|
|
height: 80,
|
|
fontSize: 10,
|
|
},
|
|
],
|
|
],
|
|
};
|
|
|
|
export function buildOccupancyInputs(
|
|
data: OccupancyData,
|
|
portName?: string,
|
|
): Record<string, string>[] {
|
|
const statusLabels: Record<string, string> = {
|
|
available: 'Available',
|
|
under_offer: 'Under Offer',
|
|
sold: 'Sold / Occupied',
|
|
};
|
|
|
|
const breakdownLines = ['Berth Status Breakdown', '─────────────────────'];
|
|
const allStatuses = ['available', 'under_offer', 'sold'];
|
|
const unknownStatuses = Object.keys(data.statusCounts).filter((s) => !allStatuses.includes(s));
|
|
|
|
for (const status of [...allStatuses, ...unknownStatuses]) {
|
|
const cnt = data.statusCounts[status] ?? 0;
|
|
const label =
|
|
statusLabels[status] ?? status.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
|
|
const pct = data.totalBerths > 0 ? ((cnt / data.totalBerths) * 100).toFixed(1) : '0.0';
|
|
breakdownLines.push(`${label}: ${cnt} berth(s) (${pct}%)`);
|
|
}
|
|
breakdownLines.push('─────────────────────');
|
|
breakdownLines.push(`Total Berths: ${data.totalBerths}`);
|
|
|
|
return [
|
|
{
|
|
reportTitle: 'Berth Occupancy Report',
|
|
portName: portName ?? 'Port Nimara',
|
|
generatedAt: `Generated: ${new Date(data.generatedAt).toLocaleString('en-GB')}`,
|
|
occupancyRate: `Occupancy Rate: ${data.occupancyRate}%`,
|
|
statusBreakdown: breakdownLines.join('\n'),
|
|
},
|
|
];
|
|
}
|