gigafibre-fsm/services/targo-hub/scripts/templates-spec/gift-email-native-reminder-fr.js
louispaulb 2919fa86af feat(campaigns/templates): native-block reminder template (proof of concept)
Until now, every Unlayer-edited template stored as a single giant
"Custom HTML" block (~37 KB). The operator couldn't manipulate the
greeting, the CTA, or the expiry badge independently — they had to
edit raw HTML inside one block.

New scripts/build-native-template.js generates matched .json
(Unlayer design tree) + .html (compiled output) from a JS template
spec under scripts/templates-spec/. Each block becomes a separate
entry in the design tree with its own type:
  - 9 text blocks  : greeting, urgency, body, expiry, prorata,
                     Option 2 text, signature, contact, dark footer
  - 2 image blocks : header logo, footer logo
  - 1 button block : the CTA (🎁 {{amount}})
  - 4 html blocks  : view-in-browser, Option 1 chip, brand-logo
                     card, Option 2 chip (kept as raw HTML — too
                     custom for native equivalents)

gift-email-native-reminder-fr ships as the proof of concept:
- Compiled HTML: 30,867 bytes (vs 39,484 for the MJML-compiled
  reminder-fr — saves 22%)
- JSON: 42,274 bytes (essentially same as before, but now broken into
  16 individually-editable blocks instead of 1 monster Custom HTML)

What this unlocks in Unlayer:
- Click any text → font / color / size / padding / alignment in the
  right panel
- Click the CTA → button-specific controls (corner radius, hover
  color, padding)
- Drag-reorder blocks within the email
- Mobile preview reflects each block's responsive defaults
- Save a block to the personal library for reuse in other campaigns

Limitations on the 4 html blocks:
- Chips (Option 1 / Option 2) require raw HTML edit because the
  rounded badge styling has no native equivalent
- Brand-logo strip needs precise inline img widths Unlayer can't set

Once the operator validates rendering across Gmail/Outlook/Apple
Mail, we'll port the rest: gift-email-fr/en + the existing reminder
templates can all migrate using the same build script.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 15:31:15 -04:00

163 lines
10 KiB
JavaScript

'use strict'
/**
* gift-email-native-reminder-fr — proof-of-concept reminder template built
* entirely from Unlayer NATIVE blocks (text / image / button) wherever
* possible, with strategic html blocks for the chips and the brand-logo
* strip (too custom for native).
*
* Operator can edit each text/button/image block individually in the
* Unlayer canvas (rich panel on the right with font, color, padding,
* alignment controls). The 4 html blocks (Option 1 chip, brand-logo card,
* Option 2 chip, dark footer band) still need raw HTML edits.
*/
module.exports = {
preheader: "Comme toi, on aime les connexions stables et les relations durables.",
ariaLabel: "Une offre exclusive de TARGO",
// rows() receives the block factories from build-native-template.js
rows: ({ textBlock, imageBlock, buttonBlock, htmlBlock, row }) => [
// ── 1 · Optional "View in browser" line (collapses if view_url empty) ──
row([
htmlBlock({
html: `{{#view_url}}<div style="text-align:center;padding:4px 0;"><a href="{{view_url}}" style="font-family:Plus Jakarta Sans,sans-serif;font-size:11px;color:#94a3b8;text-decoration:underline;">Affichage incorrect ? Voir dans le navigateur</a></div>{{/view_url}}`,
padding: '0',
}),
], { padding: '8px 0 0' }),
// ── 2 · Header logo (white rounded card top) ─────────────────────────
row([
imageBlock({
src: 'https://xqy3m.mjt.lu/img2/xqy3m/eed4d18c-8065-4c5f-b47c-58af63171cd0/content',
alt: 'TARGO', width: 140, padding: '28px 36px 22px', textAlign: 'center',
}),
], { backgroundColor: '#ffffff', border: '1px solid #e5e7eb', borderRadius: '12px 12px 0 0' }),
// ── 3 · Greeting (text block — fully editable) ───────────────────────
row([
textBlock({
html: 'Petit rappel pour {{firstname}},',
padding: '20px 36px 8px', fontSize: '16px', color: '#374151',
}),
], { backgroundColor: '#ffffff', border: '1px solid #e5e7eb', borderRadius: '0' }),
// ── 4 · Urgency line (text block, bold dark green) ───────────────────
row([
textBlock({
html: '🎁 Ton cadeau de {{amount}} reste disponible jusqu\'au {{expires_at_date}}.',
padding: '4px 36px 14px', fontSize: '17px', fontWeight: 600, color: '#1B2E24',
}),
], { backgroundColor: '#ffffff', border: '1px solid #e5e7eb', borderRadius: '0' }),
// ── 5 · Body paragraph (text block, justify) ─────────────────────────
row([
textBlock({
html: 'On voulait juste s\'assurer que tu ne l\'as pas manqué. La carte-cadeau qu\'on t\'a envoyée pour te remercier peut s\'utiliser chez des centaines de marques canadiennes, en quelques clics.<br/><br/>Si tu préfères ne pas l\'utiliser, aucun souci, pas besoin de répondre à ce courriel.',
padding: '0 36px 18px', fontSize: '16px', color: '#374151', textAlign: 'justify',
}),
], { backgroundColor: '#ffffff', border: '1px solid #e5e7eb', borderRadius: '0' }),
// ── 6 · Option 1 chip (html block — too custom for native text) ──────
row([
htmlBlock({
html: '<div style="font-family:Plus Jakarta Sans,sans-serif;font-size:16px;text-align:left;color:#1B2E24;"><span style="display:inline-block;background:#E6F9EE;color:#00C853;font-size:13px;font-weight:700;padding:5px 12px;border-radius:6px;">✅ Option 1</span></div>',
padding: '8px 36px 4px',
}),
], { backgroundColor: '#ffffff', border: '1px solid #e5e7eb', borderRadius: '0' }),
// ── 7 · Compact info card with brand logos (html block) ──────────────
row([
htmlBlock({
html: `<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="border-collapse:separate;">
<tr><td style="background-color:#F5FAF7;border-radius:10px;padding:18px 22px;">
<div style="font-family:Plus Jakarta Sans,sans-serif;font-size:16px;font-weight:700;color:#1B2E24;line-height:1.5;">
🎁 {{amount}} chez des centaines de marques<br><br>
<span style="display:inline-block;">
<img src="https://xqy3m.mjt.lu/img2/xqy3m/4b0b2a4a-5f99-416c-8873-8d3e4389b6f7/content" width="32" alt="Tim Hortons" style="width:32px;max-width:32px;height:auto;display:inline-block;border:0;margin-right:6px;vertical-align:middle;">
<img src="https://xqy3m.mjt.lu/img2/xqy3m/14df433d-583c-4602-a403-d47ee84966a6/content" width="32" alt="Walmart" style="width:32px;max-width:32px;height:auto;display:inline-block;border:0;margin-right:6px;vertical-align:middle;">
<img src="https://xqy3m.mjt.lu/img2/xqy3m/b8d3db5a-d39e-43ce-a84a-2f5dddbf0192/content" width="32" alt="Home Depot" style="width:32px;max-width:32px;height:auto;display:inline-block;border:0;margin-right:6px;vertical-align:middle;">
<img src="https://xqy3m.mjt.lu/img2/xqy3m/9c9dfa18-2a3a-414a-b5ad-16d490c961b5/content" width="32" alt="IGA" style="width:32px;max-width:32px;height:auto;display:inline-block;border:0;margin-right:6px;vertical-align:middle;">
<img src="https://xqy3m.mjt.lu/img2/xqy3m/a1e5f032-a192-4499-97ba-53b939712fa9/content" width="32" alt="Home Hardware" style="width:32px;max-width:32px;height:auto;display:inline-block;border:0;margin-right:6px;vertical-align:middle;">
<span style="font-size:13px;color:#64748B;vertical-align:middle;font-weight:400;">et plus</span>
</span>
</div>
<div style="font-family:Plus Jakarta Sans,sans-serif;font-size:14px;color:#64748B;margin-top:8px;">⚡ Disponible instantanément sur Giftbit en cliquant sur ton montant</div>
<div style="font-family:Plus Jakarta Sans,sans-serif;font-size:14px;color:#64748B;">🤝 Condition : Maintenir l'abonnement {{commitment_months}} mois ou +</div>
</td></tr>
</table>`,
padding: '0 36px 22px',
}),
], { backgroundColor: '#ffffff', border: '1px solid #e5e7eb', borderRadius: '0' }),
// ── 8 · Big green CTA button (NATIVE button block!) ──────────────────
row([
buttonBlock({
text: '🎁 &nbsp;&nbsp;{{amount}}',
href: '{{gift_url}}',
padding: '8px 36px',
buttonPadding: '30px 24px',
bgColor: '#00C853', color: '#FFFFFF', borderRadius: '12px',
fontSize: '32px', fontWeight: 700,
}),
], { backgroundColor: '#ffffff', border: '1px solid #e5e7eb', borderRadius: '0' }),
// ── 9 · Expiry badge (text block) ────────────────────────────────────
row([
textBlock({
html: '⏰ Cadeau valide jusqu\'au <strong style="color:#1B2E24;">{{expires_at_date}}</strong>',
padding: '0 36px 4px', fontSize: '13px', color: '#64748B', textAlign: 'center', lineHeight: '140%',
}),
], { backgroundColor: '#ffffff', border: '1px solid #e5e7eb', borderRadius: '0' }),
// ── 10 · Prorata disclaimer (text block) ─────────────────────────────
row([
textBlock({
html: '🪂 Annulation avant {{commitment_months}} mois : seulement à rembourser au prorata des mois restants.',
padding: '10px 36px 22px', fontSize: '14px', color: '#6b7280',
}),
], { backgroundColor: '#ffffff', border: '1px solid #e5e7eb', borderRadius: '0' }),
// ── 11 · Option 2 chip + text ────────────────────────────────────────
row([
htmlBlock({
html: '<div style="font-family:Plus Jakarta Sans,sans-serif;font-size:16px;text-align:left;color:#1B2E24;"><span style="display:inline-block;background:#F5FAF7;color:#6b7280;font-size:13px;font-weight:700;padding:5px 12px;border-radius:6px;">⏭️ Option 2</span></div>',
padding: '8px 36px 4px',
}),
textBlock({
html: 'Ne rien faire. Aucun changement à ton abonnement actuel.',
padding: '0 36px 22px', fontSize: '15px', color: '#4b5563', lineHeight: '155%',
}),
], { backgroundColor: '#ffffff', border: '1px solid #e5e7eb', borderRadius: '0' }),
// ── 12 · Signature (text block) ──────────────────────────────────────
row([
textBlock({
html: '🤝 Merci de faire rouler l\'économie de notre région avec nous !<br/><span style="color:#64748B;font-size:14px;">L\'équipe TARGO</span>',
padding: '18px 36px 28px', fontSize: '15px', color: '#1B2E24',
}),
], { backgroundColor: '#ffffff', border: '1px solid #e5e7eb', borderRadius: '0 0 12px 12px' }),
// ── 13 · Contact info (text block, outside the card) ─────────────────
row([
textBlock({
html: 'Tu reçois ce courriel parce que tu es client(e) TARGO à <strong style="color:#1B2E24;">{{description}}</strong>.<br/>Une question ? N\'hésite pas à nous écrire à <a href="mailto:support@targo.ca" style="color:#00C853;text-decoration:none;">support@targo.ca</a> ou nous appeler au <a href="tel:5144480773" style="color:#00C853;text-decoration:none;">514-448-0773</a>.',
padding: '18px 36px 8px', fontSize: '12px', color: '#64748B', textAlign: 'center', lineHeight: '155%',
}),
], {}),
// ── 14 · Dark footer band (image + text on #1C1E26) ──────────────────
row([
imageBlock({
src: 'https://xqy3m.mjt.lu/img2/xqy3m/eed4d18c-8065-4c5f-b47c-58af63171cd0/content',
alt: 'TARGO', width: 120, padding: '26px 36px 0', textAlign: 'center',
}),
textBlock({
html: '<a href="https://www.targo.ca" style="color:rgba(255,255,255,0.7);text-decoration:none;">www.targo.ca</a> · 1867 ch. de la rivière, Ste-Clotilde, QC<br/>© {{year}} TARGO Communications · Tous droits réservés.',
padding: '12px 36px 22px', fontSize: '11px', color: 'rgba(255,255,255,0.55)', textAlign: 'center', lineHeight: '155%',
}),
], { backgroundColor: '#1C1E26', borderRadius: '12px' }),
],
}