feat(ops/campaigns): group merge tags by category + add toolbar hint

Improvements to the variable insertion UX in the Unlayer editor:

1. Reorganized mergeTags from a flat object into 3 logical groups so
   Unlayer's "Merge Tags" dropdown shows them under sub-headers
   instead of a long flat list:

     • Client (firstname, lastname, email, description)
     • Offre (amount, gift_url, expiry, commitment_months)
     • Système (year)

   Format switched from { id: {name, value} } to grouped array
   format (Unlayer accepts both, but groups give better UX).

2. Added `sample` field to each merge tag — Unlayer renders these
   as the visible content while editing, so the canvas shows
   "Louis Tremblay" / "60 $" / "https://gft.link/abc" instead of
   literal "{{firstname}} {{lastname}}". Makes the live preview
   look like real content during edit. Substitution still happens
   server-side at send time via Mustache.

3. New toolbar hint button (code icon, grey) explaining where to
   find merge tags in the Unlayer UI:
   "Insertion : clic dans un texte → barre flottante → icône {}
   Merge Tags. Marche aussi dans les champs URL (boutons, images,
   mailto)."

   This addresses a common discoverability issue: users don't
   always realize variables work in URL fields too (e.g. setting
   a button's "Action URL" to {{gift_url}} so each recipient gets
   their own Giftbit link).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
louispaulb 2026-05-22 06:16:16 -04:00
parent a11fe5a115
commit 9dcd32ef6a

View File

@ -10,6 +10,13 @@
<q-chip v-if="lastSavedTs" dense size="sm" color="grey-2" text-color="grey-9" class="q-ml-sm" icon="cloud_done">
Sauvegardé · {{ lastSavedLabel }}
</q-chip>
<q-btn flat dense icon="code" class="q-ml-sm" color="grey-7">
<q-tooltip max-width="320px">
<strong>9 variables disponibles</strong> (Client / Offre / Système).
Insertion : clic dans un texte barre flottante icône <code>{}</code> Merge Tags.
Marche aussi dans les champs URL (boutons, images, mailto).
</q-tooltip>
</q-btn>
<q-space />
<q-btn flat color="primary" icon="visibility" label="Aperçu inbox" class="q-mr-sm" @click="openPreview">
<q-tooltip>Voir le HTML rendu (substitué) tel que reçu par le destinataire</q-tooltip>
@ -116,17 +123,38 @@ const editorOptions = {
tools: { dock: 'left' },
},
},
mergeTags: {
firstname: { name: 'Prénom', value: '{{firstname}}' },
lastname: { name: 'Nom', value: '{{lastname}}' },
email: { name: 'Courriel', value: '{{email}}' },
amount: { name: 'Montant', value: '{{amount}}' },
gift_url: { name: 'Lien cadeau', value: '{{gift_url}}' },
description: { name: 'Adresse service', value: '{{description}}' },
expiry: { name: "Date d'expiry", value: '{{expiry}}' },
commitment_months: { name: 'Engagement (mois)', value: '{{commitment_months}}' },
year: { name: 'Année', value: '{{year}}' },
},
// Merge tags organized by category Unlayer shows these in a dropdown
// when editing a text block (click into text toolbar {} icon) and
// ALSO in URL fields (Button "Action URL", Image "Source", mailto links).
// The `sample` field is what Unlayer shows as a preview (so the user sees
// realistic content while editing); on send, the hub's Mustache renderer
// substitutes the actual value.
mergeTags: [
{
name: 'Client',
mergeTags: [
{ name: 'Prénom', value: '{{firstname}}', sample: 'Louis' },
{ name: 'Nom de famille', value: '{{lastname}}', sample: 'Tremblay' },
{ name: 'Courriel', value: '{{email}}', sample: 'louis@targo.ca' },
{ name: 'Adresse service', value: '{{description}}', sample: '123 Rue de la Rivière, Ste-Clotilde' },
],
},
{
name: 'Offre',
mergeTags: [
{ name: 'Montant', value: '{{amount}}', sample: '60 $' },
{ name: 'Lien cadeau (URL)', value: '{{gift_url}}', sample: 'https://gft.link/abc' },
{ name: "Date d'expiration", value: '{{expiry}}', sample: '31 décembre 2026' },
{ name: 'Engagement (mois)', value: '{{commitment_months}}', sample: '3' },
],
},
{
name: 'Système',
mergeTags: [
{ name: 'Année courante', value: '{{year}}', sample: '2026' },
],
},
],
// Display mode: 'email' (default, with mobile preview), 'web' for landing pages
displayMode: 'email',
// Locale for built-in strings