feat(email): Phase 5 — branding chain ext'd with per-port background
Surface hard-coded portnimara.com background image as a per-port override: - BrandingShell gains backgroundUrl; renderShell reads from branding.backgroundUrl with the existing Port Nimara overhead URL as the fallback default. - getBrandingShell threads the value through from getPortBrandingConfig. - PortBrandingConfig gains emailBackgroundUrl; SETTING_KEYS adds brandingEmailBackgroundUrl mapped to 'branding_email_background_url'. - /admin/branding page exposes the new field as an image-upload below the logo with sizing guidance (1920x1080 JPG, pre-blurred). This closes the last hard-coded portnimara.com asset URL in the email shell — every transactional email now fully respects per-port branding when the admin uploads their own assets. Logo override path was already in place from R2-H15; the background was the missing piece. Tests: 1374/1374 passing. tsc clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,7 @@ export async function getBrandingShell(
|
||||
const cfg = await getPortBrandingConfig(portId);
|
||||
return {
|
||||
logoUrl: cfg.logoUrl,
|
||||
backgroundUrl: cfg.emailBackgroundUrl,
|
||||
primaryColor: cfg.primaryColor,
|
||||
emailHeaderHtml: cfg.emailHeaderHtml,
|
||||
emailFooterHtml: cfg.emailFooterHtml,
|
||||
|
||||
@@ -23,6 +23,10 @@ const DEFAULT_PRIMARY_COLOR = '#0F4C81';
|
||||
|
||||
export interface BrandingShell {
|
||||
logoUrl: string | null;
|
||||
/** Phase 5: blurred page-background image rendered behind the white
|
||||
* card. Defaults to the Port Nimara overhead image. Ports with
|
||||
* their own marina photography override via system_settings. */
|
||||
backgroundUrl: string | null;
|
||||
primaryColor: string | null;
|
||||
emailHeaderHtml: string | null;
|
||||
emailFooterHtml: string | null;
|
||||
@@ -36,6 +40,7 @@ interface ShellOpts {
|
||||
|
||||
export function renderShell({ title, body, branding }: ShellOpts): string {
|
||||
const logoUrl = branding?.logoUrl ?? DEFAULT_LOGO_URL;
|
||||
const backgroundUrl = branding?.backgroundUrl ?? DEFAULT_BACKGROUND_URL;
|
||||
const headerHtml = branding?.emailHeaderHtml ?? '';
|
||||
const footerHtml = branding?.emailFooterHtml ?? '';
|
||||
|
||||
@@ -52,7 +57,7 @@ export function renderShell({ title, body, branding }: ShellOpts): string {
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin:0; padding:0; background-color:#f2f2f2;">
|
||||
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="background-image: url('${DEFAULT_BACKGROUND_URL}'); background-size: cover; background-position: center; background-color:#f2f2f2;">
|
||||
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="background-image: url('${backgroundUrl}'); background-size: cover; background-position: center; background-color:#f2f2f2;">
|
||||
<tr>
|
||||
<td align="center" style="padding:30px 16px;">
|
||||
<table role="presentation" width="600" border="0" cellspacing="0" cellpadding="0" style="width:100%; max-width:600px; background-color:#ffffff; border-radius:8px; overflow:hidden; box-shadow:0 2px 4px rgba(0,0,0,0.1);">
|
||||
|
||||
Reference in New Issue
Block a user