Files
pn-new-crm/src/lib/services/dashboard-report-widgets.ts
Matt adf4e2ba78 fix(reports): split PDF widget catalogue out of the DB-touching service
export-dashboard-pdf-button.tsx imported PDF_DASHBOARD_WIDGETS +
PdfDashboardWidgetId from dashboard-report-data.service.ts. JS modules
evaluate their imports eagerly, so the button transitively pulled in
that file's top-level `import { getKpis } from './dashboard.service'`,
which pulled in `@/lib/db`, which pulls in `postgres`, which crashed
the client bundle with:

  Module not found: Can't resolve 'fs'
    ./node_modules/.../postgres/src/index.js [Client Component Browser]

Split the pure data + types into the new file
src/lib/services/dashboard-report-widgets.ts and re-export from the
original service for backwards compatibility. The button now imports
from the pure file; the server-only route (reports/generate) keeps
using the resolver as before.

tsc clean, dashboard loads.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 13:03:44 +02:00

62 lines
1.9 KiB
TypeScript

/**
* Pure data + types for the dashboard-PDF report's widget catalogue.
*
* Lives in its own file so client-side surfaces (the "Export as PDF"
* dialog) can import the catalogue without dragging the server-side
* resolver — which imports the DB layer — into the client bundle.
* Before this split, `export-dashboard-pdf-button.tsx` pulled
* `PDF_DASHBOARD_WIDGETS` from `dashboard-report-data.service.ts`,
* whose top-level `import { getKpis } from './dashboard.service'`
* dragged in `postgres` and crashed the client build with
* "Module not found: Can't resolve 'fs'".
*/
export const PDF_DASHBOARD_WIDGET_IDS = [
'kpi_overview',
'pipeline_funnel',
'berth_status',
'source_conversion',
'hot_deals',
] as const;
export type PdfDashboardWidgetId = (typeof PDF_DASHBOARD_WIDGET_IDS)[number];
export interface PdfDashboardWidgetOption {
id: PdfDashboardWidgetId;
label: string;
description: string;
}
/**
* Public widget list (label + description) for the export dialog.
* Mirrored from the on-screen widget-registry but with PDF-friendly
* copy: a "Berth heat" chart is "Berth demand ranking" in print.
*/
export const PDF_DASHBOARD_WIDGETS: readonly PdfDashboardWidgetOption[] = [
{
id: 'kpi_overview',
label: 'Key metrics',
description: 'Total clients, active interests, pipeline value, occupancy %.',
},
{
id: 'pipeline_funnel',
label: 'Pipeline funnel',
description: 'Active interests grouped by pipeline stage.',
},
{
id: 'berth_status',
label: 'Berth status distribution',
description: 'Available / under offer / reserved / sold counts.',
},
{
id: 'source_conversion',
label: 'Source conversion',
description: 'Inquiries → Clients → Interests → Won, by lead source.',
},
{
id: 'hot_deals',
label: 'Hot deals',
description: 'Top 5 active interests by deal-health score.',
},
];