Fix out-of-stock CTA regressions: grid alignment, preview accuracy, label length

- Replace the invisible reserved-space trick with items-start on every
  product grid (ProductGrid/MerklisteGrid/RelatedProducts) — the
  reservation looked worse in practice (visible dead space under
  in-stock cards' buttons) than letting an out-of-stock card simply be
  taller than its siblings.
- New renderBackInStockHtml() in lib/emailTemplates.ts, used by the
  Live Preview instead of the generic order-status renderer — that one
  showed a fake order number and "Bestellung ansehen", neither of
  which apply to a back-in-stock mail (no order exists). CTA is now
  "Zum Produkt", matching the real backend send.
- Shortened NotifyMeForm's button label ("Benachrichtigen") — the
  longer version wrapped to two lines on narrow single-column cards.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Marco
2026-08-01 20:12:23 +00:00
parent 70ee518e1d
commit 87388479de
9 changed files with 99 additions and 106 deletions
+23
View File
@@ -361,6 +361,29 @@ export function renderOrderStatusHtml(
return emailShell(icon, escapeHtml(template.heading), body, template.footerText, buildLegalFooterLines(seller));
}
// Separate from renderOrderStatusHtml — a back-in-stock mail has no order
// at all (it fires from a "notify me" signup, not a purchase), so no
// "Bestellnummer" line, and the CTA points at the product page, not
// /konto/bestellungen. Mirrors lib/jobs/sendBackInStockEmails.ts on the
// Payload backend, which is where the real send actually happens (see
// this file's own top-of-file comment on why the two aren't literally
// shared code).
export function renderBackInStockHtml(template: EmailTemplateContent, productLabel: string, productUrl: string, seller: CompanySettings | null): string {
const body = `
${paragraphs(template.bodyText, "center")}
<p style="text-align:center;font-size:13px;color:${TEXT_MUTED};margin:0 0 12px;">${escapeHtml(productLabel)}</p>
<table role="presentation" cellpadding="0" cellspacing="0" style="margin:20px auto 8px;">
<tr>
<td style="background:${BRAND};border-radius:6px;">
<a href="${productUrl}" style="display:inline-block;padding:13px 28px;font-weight:700;font-size:15px;color:${TEXT_PRIMARY};text-decoration:none;">Zum Produkt</a>
</td>
</tr>
</table>
`;
return emailShell("🔔", escapeHtml(template.heading), body, template.footerText, buildLegalFooterLines(seller));
}
export function renderPasswordResetHtml(template: EmailTemplateContent, resetUrl: string, seller: CompanySettings | null): string {
const body = `
${paragraphs(template.bodyText, "center")}