brand identity cleanup
Build and Push Docker Image / build (push) Successful in 2m17s

This commit is contained in:
Jason Stedwell
2026-07-03 10:35:42 -05:00
parent 497d54de3c
commit f315ddabc6
+58 -28
View File
@@ -147,43 +147,72 @@ export function generateReportHTML(report: ReportWithRelations) {
const plannedTasks = report.tasks.filter((t) => t.type === 'PLANNED'); const plannedTasks = report.tasks.filter((t) => t.type === 'PLANNED');
const completedTasks = report.tasks.filter((t) => t.type === 'COMPLETED'); const completedTasks = report.tasks.filter((t) => t.type === 'COMPLETED');
// MPM brand palette // MPM brand palette (matches the hex values used across MPM technical docs)
const GOLD_DARK = '#998643'; // titles on light backgrounds const GOLD_DARK = '#998643'; // document titles, section headings
const GOLD_MID = '#DCBB4F'; // accent lines, dividers const GOLD_MID = '#DCBB4F'; // accent rules / dividers
const SHADE_DARK = '#232022'; // body text / table header background const SHADE_DARK = '#232022'; // body text / table header background
const SHADE_LIGHT = '#F5F1EC'; // section panels / table header text const SHADE_LIGHT = '#F5F1EC'; // key-column / table header text fill
const OFF_WHITE = '#FAF7F2'; // alternating table rows const OFF_WHITE = '#FAF7F2'; // alternating data-table rows
const ACCENT = '#849698'; // secondary / muted text const ACCENT = '#849698'; // secondary / muted text
const BORDER = '#E7E0D5'; // hairline cell borders (warm gray)
const bodyFont = "'Open Sans', Arial, sans-serif"; const bodyFont = "'Open Sans', Arial, sans-serif";
const headingFont = "'Montserrat', 'Open Sans', Arial, sans-serif"; const headingFont = "'Montserrat', 'Open Sans', Arial, sans-serif";
const cellStyle = `padding: 10px; border-bottom: 1px solid #E7E0D5; font-family: ${bodyFont}; font-size: 11pt; color: ${SHADE_DARK};`; const statusLabel = (report.status || 'DRAFT').charAt(0) + (report.status || 'DRAFT').slice(1).toLowerCase();
const headerStyle = `padding: 12px 10px; background-color: ${SHADE_DARK}; font-family: ${headingFont}; font-size: 11pt; font-weight: 600; text-align: left; color: ${SHADE_LIGHT};`; const docRef = `WFH-${new Date(report.date).toISOString().slice(0, 10)}`;
// Data-table cell styles
const cellStyle = `padding: 8px 12px; border: 1px solid ${BORDER}; font-family: ${bodyFont}; font-size: 10.5pt; color: ${SHADE_DARK}; vertical-align: top;`;
const headerStyle = `padding: 9px 12px; background-color: ${SHADE_DARK}; border: 1px solid ${SHADE_DARK}; font-family: ${headingFont}; font-size: 10pt; font-weight: 600; text-align: left; color: ${SHADE_LIGHT};`;
const rowBg = (i: number) => (i % 2 === 1 ? ` background-color: ${OFF_WHITE};` : '');
// Document Control-style key/value row
const metaKey = `width: 26%; padding: 8px 12px; background-color: ${SHADE_LIGHT}; border: 1px solid ${BORDER}; font-family: ${headingFont}; font-weight: 600; font-size: 10pt; color: ${SHADE_DARK};`;
const metaVal = `padding: 8px 12px; border: 1px solid ${BORDER}; background-color: #FFFFFF; font-size: 10.5pt; color: ${SHADE_DARK};`;
const metaRow = (k: string, v: string) =>
`<tr><td style="${metaKey}">${k}</td><td style="${metaVal}">${v}</td></tr>`;
// Section label styled like the technical docs' "Document Control" heading.
const sectionLabel = (text: string) =>
`<p style="font-family: ${headingFont}; font-weight: 600; font-size: 10.5pt; letter-spacing: 1.5px; text-transform: uppercase; color: ${GOLD_DARK}; margin: 0 0 8px 0;">${text}</p>`;
const sectionHeading = (text: string) =>
`<h2 style="font-family: ${headingFont}; font-weight: 600; font-size: 14pt; color: ${GOLD_DARK}; margin: 26px 0 10px 0;">${text}</h2>`;
// A gold rule rendered as a filled 1-row table (survives Google Docs conversion,
// where border-bottom on headings/divs does not).
const goldRule = `<table role="presentation" style="width: 100%; border-collapse: collapse; margin: 12px 0 22px 0;"><tr><td style="height: 3px; line-height: 3px; font-size: 0; padding: 0; background-color: ${GOLD_MID};">&nbsp;</td></tr></table>`;
const emptyNote = (text: string) =>
`<p style="font-style: italic; color: ${ACCENT}; font-family: ${bodyFont}; margin: 0 0 8px 0;">${text}</p>`;
// Embed the logo inline so it survives conversion without a reachable host. // Embed the logo inline so it survives conversion without a reachable host.
const logoDataUri = getLogoDataUri(); const logoDataUri = getLogoDataUri();
const logoHtml = logoDataUri const logoHtml = logoDataUri
? `<img src="${logoDataUri}" alt="Message Point Media" style="height: 44px; margin-bottom: 16px;" />` ? `<img src="${logoDataUri}" alt="Message Point Media" style="height: 40px; margin-bottom: 14px;" />`
: ''; : '';
const rowBg = (i: number) => (i % 2 === 1 ? ` background-color: ${OFF_WHITE};` : '');
return ` return `
<html> <html>
<body style="font-family: ${bodyFont}; color: ${SHADE_DARK}; line-height: 1.6; max-width: 800px; margin: 0 auto; padding: 20px;"> <body style="font-family: ${bodyFont}; color: ${SHADE_DARK}; line-height: 1.5; max-width: 760px; margin: 0 auto; padding: 16px 24px;">
${logoHtml} ${logoHtml}
<h1 style="color: ${GOLD_DARK}; border-bottom: 3px solid ${GOLD_MID}; padding-bottom: 10px; font-family: ${headingFont}; font-weight: 700; margin-bottom: 20px;">WFH Daily Report</h1> <p style="font-family: ${headingFont}; font-weight: 600; font-size: 9pt; letter-spacing: 2px; text-transform: uppercase; color: ${SHADE_DARK}; margin: 0 0 2px 0;">Message Point Media</p>
<h1 style="font-family: ${headingFont}; font-weight: 700; font-size: 23pt; color: ${GOLD_DARK}; margin: 0 0 4px 0;">WFH Daily Report</h1>
<p style="font-size: 10.5pt; color: ${ACCENT}; margin: 0;">Daily Work-From-Home Status &nbsp;|&nbsp; ${escapeHtml(report.user.name)} &nbsp;|&nbsp; ${dateStr}</p>
${goldRule}
<div style="background-color: ${SHADE_LIGHT}; padding: 20px; border-left: 4px solid ${GOLD_MID}; border-radius: 4px; margin-bottom: 30px; font-family: ${bodyFont};"> ${sectionLabel('Report Details')}
<p style="margin: 0 0 8px 0; font-size: 11pt;"><strong>Date:</strong> ${dateStr}</p> <table style="width: 100%; border-collapse: collapse; margin-bottom: 4px;">
<p style="margin: 0 0 8px 0; font-size: 11pt;"><strong>Employee:</strong> ${escapeHtml(report.user.name)}</p> ${metaRow('Employee', escapeHtml(report.user.name))}
<p style="margin: 0; font-size: 11pt;"><strong>Manager:</strong> ${escapeHtml(report.managerName || 'N/A')}</p> ${metaRow('Date', dateStr)}
</div> ${metaRow('Manager', escapeHtml(report.managerName || 'N/A'))}
${metaRow('Status', statusLabel)}
${metaRow('Reference', docRef)}
</table>
<h2 style="color: ${GOLD_DARK}; margin-top: 30px; margin-bottom: 15px; font-family: ${headingFont}; font-weight: 600;">Planned Tasks</h2> ${sectionHeading('1. Planned Tasks')}
${plannedTasks.length > 0 ? ` ${plannedTasks.length > 0 ? `
<table style="width: 100%; border-collapse: collapse; margin-bottom: 30px;"> <table style="width: 100%; border-collapse: collapse; margin-bottom: 6px;">
<tr> <tr>
<th style="${headerStyle} width: 45%;">Description</th> <th style="${headerStyle} width: 45%;">Description</th>
<th style="${headerStyle} width: 20%;">Estimate</th> <th style="${headerStyle} width: 20%;">Estimate</th>
@@ -197,11 +226,11 @@ export function generateReportHTML(report: ReportWithRelations) {
</tr> </tr>
`).join('')} `).join('')}
</table> </table>
` : `<p style="font-style: italic; color: ${ACCENT}; font-family: ${bodyFont}; margin-bottom: 30px;">No planned tasks for today.</p>`} ` : emptyNote('No planned tasks for today.')}
<h2 style="color: ${GOLD_DARK}; margin-top: 30px; margin-bottom: 15px; font-family: ${headingFont}; font-weight: 600;">Completed Tasks</h2> ${sectionHeading('2. Completed Tasks')}
${completedTasks.length > 0 ? ` ${completedTasks.length > 0 ? `
<table style="width: 100%; border-collapse: collapse; margin-bottom: 30px;"> <table style="width: 100%; border-collapse: collapse; margin-bottom: 6px;">
<tr> <tr>
<th style="${headerStyle} width: 40%;">Description</th> <th style="${headerStyle} width: 40%;">Description</th>
<th style="${headerStyle} width: 20%;">Status</th> <th style="${headerStyle} width: 20%;">Status</th>
@@ -212,18 +241,19 @@ export function generateReportHTML(report: ReportWithRelations) {
return ` return `
<tr> <tr>
<td style="${cellStyle}${rowBg(i)}">${escapeHtml(t.description)}</td> <td style="${cellStyle}${rowBg(i)}">${escapeHtml(t.description)}</td>
<td style="${cellStyle}${rowBg(i)} font-weight: bold; color: ${GOLD_DARK};">${escapeHtml(t.status || 'Done')}</td> <td style="${cellStyle}${rowBg(i)} font-weight: 600; color: ${GOLD_DARK};">${escapeHtml(t.status || 'Done')}</td>
<td style="${cellStyle}${rowBg(i)}">${link ? `<a href="${escapeHtml(link)}" style="color: ${GOLD_DARK}; text-decoration: none;">${escapeHtml(link)}</a>` : '-'}</td> <td style="${cellStyle}${rowBg(i)}">${link ? `<a href="${escapeHtml(link)}" style="color: ${GOLD_DARK}; text-decoration: none;">${escapeHtml(link)}</a>` : '-'}</td>
</tr> </tr>
`; `;
}).join('')} }).join('')}
</table> </table>
` : `<p style="font-style: italic; color: ${ACCENT}; font-family: ${bodyFont}; margin-bottom: 30px;">No completed tasks reported today.</p>`} ` : emptyNote('No completed tasks reported today.')}
<div style="margin-top: 50px; font-size: 9pt; color: ${ACCENT}; text-align: center; border-top: 1px solid ${GOLD_MID}; padding-top: 20px; font-family: ${bodyFont};"> ${goldRule}
<p style="margin: 0 0 4px 0; font-family: ${headingFont}; font-weight: 600; color: ${GOLD_DARK}; letter-spacing: 0.5px;">Born to Innovate. Built to Last.</p> <p style="font-family: ${headingFont}; font-weight: 600; font-size: 10pt; color: ${SHADE_DARK}; margin: 0 0 2px 0;">Prepared by ${escapeHtml(report.user.name)}</p>
<p style="margin: 0;">Message Point Media &middot; Generated automatically by the WFH Daily Report app</p> <p style="font-size: 9pt; color: ${ACCENT}; margin: 0 0 10px 0;">Message Point Media &nbsp;&middot;&nbsp; ${docRef} &nbsp;&middot;&nbsp; Generated by the WFH Daily Report app</p>
</div> <p style="font-family: ${headingFont}; font-weight: 600; font-size: 9.5pt; letter-spacing: 0.5px; color: ${GOLD_DARK}; margin: 0 0 2px 0;">Born to Innovate. Built to Last.</p>
<p style="font-size: 8.5pt; font-style: italic; color: ${ACCENT}; margin: 0;">Compelling&hellip; Affordable&hellip; Dynamic&hellip; Messaging&hellip; It&rsquo;s What We Do!</p>
</body> </body>
</html> </html>
`; `;