/** * Shared HTML shell for transactional emails. Centralises the table- * based layout + the per-port branding override surface so templates * don't each inline a different copy of the boilerplate. * * Per-port branding (R2-H15): * - logoUrl — replaces the default Port Nimara logo image * - primaryColor — used for the page-title accent color * - emailHeaderHtml / emailFooterHtml — admin-authored HTML that * appears above / below the body content (e.g. legal footer, * custom marketing strip). When unset, the existing minimal * "Thank you, {{portName}} CRM" sign-off is rendered by callers. * * Senders resolve a `BrandingShell` via `resolveBrandingShell(portId)` * (or pass `null` for no override) and forward it to the template * function. Templates call `renderShell({ title, body, branding })`. */ const DEFAULT_LOGO_URL = 'https://s3.portnimara.com/images/Port%20Nimara%20New%20Logo-Circular%20Frame_250px.png'; const DEFAULT_BACKGROUND_URL = 'https://s3.portnimara.com/images/Overhead_1_blur.png'; const DEFAULT_PRIMARY_COLOR = '#0F4C81'; export interface BrandingShell { logoUrl: string | null; primaryColor: string | null; emailHeaderHtml: string | null; emailFooterHtml: string | null; } interface ShellOpts { title: string; body: string; branding?: BrandingShell | null; } export function renderShell({ title, body, branding }: ShellOpts): string { const logoUrl = branding?.logoUrl ?? DEFAULT_LOGO_URL; const headerHtml = branding?.emailHeaderHtml ?? ''; const footerHtml = branding?.emailFooterHtml ?? ''; return ` ${title}
Port logo
${headerHtml ? `
${headerHtml}
` : ''} ${body} ${footerHtml ? `
${footerHtml}
` : ''}
`; } /** Surface the brand primary color to template bodies. */ export function brandingPrimaryColor(branding?: BrandingShell | null): string { return branding?.primaryColor ?? DEFAULT_PRIMARY_COLOR; }