|
| 1 | +--- |
| 2 | +import "../styles/global.css" |
| 3 | +import ProConsTable from "./ProConsTable.astro" |
| 4 | +import GtagHead from "./GtagHead.astro" |
| 5 | +import CookieConsent from "./CookieConsent.astro" |
| 6 | +
|
| 7 | +interface Benefit { |
| 8 | + icon: string; |
| 9 | + title: string; |
| 10 | + description: string; |
| 11 | +} |
| 12 | +
|
| 13 | +interface PricingTier { |
| 14 | + name: string; |
| 15 | + price: string; |
| 16 | + period: string; |
| 17 | + features: string[]; |
| 18 | + highlighted?: boolean; |
| 19 | +} |
| 20 | +
|
| 21 | +interface TableRow { |
| 22 | + label: string; |
| 23 | + notifuse: string; |
| 24 | + competitor: string; |
| 25 | +} |
| 26 | +
|
| 27 | +interface Props { |
| 28 | + lang: string; |
| 29 | + metaTitle: string; |
| 30 | + metaDescription: string; |
| 31 | + h1: string; |
| 32 | + subheadline: string; |
| 33 | + ctaText: string; |
| 34 | + ctaUrl: string; |
| 35 | + trustBadges: string[]; |
| 36 | + benefits: Benefit[]; |
| 37 | + competitor?: string; |
| 38 | + proConsRows?: TableRow[]; |
| 39 | + pricingTiers: PricingTier[]; |
| 40 | + pricingTitle?: string; |
| 41 | + finalCtaTitle?: string; |
| 42 | + finalCtaDescription?: string; |
| 43 | +} |
| 44 | +
|
| 45 | +const { |
| 46 | + lang, |
| 47 | + metaTitle, |
| 48 | + metaDescription, |
| 49 | + h1, |
| 50 | + subheadline, |
| 51 | + ctaText, |
| 52 | + ctaUrl, |
| 53 | + trustBadges, |
| 54 | + benefits, |
| 55 | + competitor, |
| 56 | + proConsRows, |
| 57 | + pricingTiers, |
| 58 | + pricingTitle = "Tarifs", |
| 59 | + finalCtaTitle = "Prêt à reprendre le contrôle de vos emails ?", |
| 60 | + finalCtaDescription = "Essai gratuit 30 jours. Sans carte bancaire. Toutes les fonctionnalités.", |
| 61 | +} = Astro.props; |
| 62 | +--- |
| 63 | + |
| 64 | +<html lang={lang}> |
| 65 | + <head> |
| 66 | + <meta charset="utf-8" /> |
| 67 | + <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> |
| 68 | + <meta name="viewport" content="width=device-width, initial-scale=1" /> |
| 69 | + <meta name="robots" content="noindex, nofollow" /> |
| 70 | + |
| 71 | + <title>{metaTitle}</title> |
| 72 | + <meta name="description" content={metaDescription} /> |
| 73 | + <meta name="theme-color" content="#7763F1" /> |
| 74 | + |
| 75 | + <meta property="og:title" content={metaTitle} /> |
| 76 | + <meta property="og:description" content={metaDescription} /> |
| 77 | + <meta property="og:type" content="website" /> |
| 78 | + |
| 79 | + <!-- Consent Mode V2 defaults + GA4 (MUST load before Plausible to ensure consent fires first) --> |
| 80 | + <GtagHead /> |
| 81 | + |
| 82 | + <!-- Plausible — privacy-friendly, no consent needed, loads independently --> |
| 83 | + <script defer data-domain="notifuse.com" src="https://plausible.notifuse.com/js/script.js"></script> |
| 84 | + </head> |
| 85 | + |
| 86 | + <body class="bg-white-98 text-gray-900"> |
| 87 | + <main class="max-w-3xl mx-auto px-4 py-8 sm:py-12"> |
| 88 | + |
| 89 | + <!-- Logo --> |
| 90 | + <div class="text-center mb-8"> |
| 91 | + <a href="https://notifuse.com" class="inline-flex items-center gap-2 text-xl font-bold text-slate-900"> |
| 92 | + <svg width="28" height="28" viewBox="0 0 32 32" fill="none"> |
| 93 | + <rect width="32" height="32" rx="8" fill="#7763F1"/> |
| 94 | + <path d="M8 10h16v2H8zm0 5h12v2H8zm0 5h14v2H8z" fill="white"/> |
| 95 | + </svg> |
| 96 | + Notifuse |
| 97 | + </a> |
| 98 | + </div> |
| 99 | + |
| 100 | + <!-- Hero --> |
| 101 | + <section class="text-center mb-10"> |
| 102 | + <h1 class="text-3xl sm:text-4xl font-bold text-slate-900 mb-4 leading-tight"> |
| 103 | + {h1} |
| 104 | + </h1> |
| 105 | + <p class="text-lg text-gray-600 mb-8 max-w-xl mx-auto"> |
| 106 | + {subheadline} |
| 107 | + </p> |
| 108 | + <a |
| 109 | + href={ctaUrl} |
| 110 | + data-cta |
| 111 | + class="inline-block bg-primary text-white px-8 py-4 rounded-lg text-lg font-semibold hover:bg-primary/90 transition-colors shadow-lg shadow-primary/25" |
| 112 | + > |
| 113 | + {ctaText} |
| 114 | + </a> |
| 115 | + </section> |
| 116 | + |
| 117 | + <!-- Trust bar --> |
| 118 | + <section class="flex flex-wrap justify-center gap-4 mb-12"> |
| 119 | + {trustBadges.map((badge) => ( |
| 120 | + <span class="inline-flex items-center gap-1.5 text-sm text-gray-600 bg-white border border-gray-200 rounded-full px-4 py-2"> |
| 121 | + <svg class="w-4 h-4 text-green-500 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20"> |
| 122 | + <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/> |
| 123 | + </svg> |
| 124 | + {badge} |
| 125 | + </span> |
| 126 | + ))} |
| 127 | + </section> |
| 128 | + |
| 129 | + <!-- Benefits --> |
| 130 | + <section class="grid grid-cols-1 sm:grid-cols-2 gap-6 mb-12"> |
| 131 | + {benefits.map((b) => ( |
| 132 | + <div class="bg-white border border-gray-200 rounded-xl p-6"> |
| 133 | + <div class="text-2xl mb-3">{b.icon}</div> |
| 134 | + <h3 class="font-semibold text-slate-900 mb-2">{b.title}</h3> |
| 135 | + <p class="text-sm text-gray-600">{b.description}</p> |
| 136 | + </div> |
| 137 | + ))} |
| 138 | + </section> |
| 139 | + |
| 140 | + <!-- Comparison table --> |
| 141 | + {competitor && proConsRows && ( |
| 142 | + <section class="mb-12"> |
| 143 | + <h2 class="text-2xl font-bold text-slate-900 mb-6 text-center"> |
| 144 | + Notifuse vs {competitor} |
| 145 | + </h2> |
| 146 | + <div class="bg-white border border-gray-200 rounded-xl p-4 sm:p-6 overflow-hidden"> |
| 147 | + <ProConsTable competitor={competitor} rows={proConsRows} /> |
| 148 | + </div> |
| 149 | + </section> |
| 150 | + )} |
| 151 | + |
| 152 | + <!-- Pricing --> |
| 153 | + <section class="mb-12"> |
| 154 | + <h2 class="text-2xl font-bold text-slate-900 mb-6 text-center"> |
| 155 | + {pricingTitle} |
| 156 | + </h2> |
| 157 | + <div class="grid grid-cols-2 sm:grid-cols-4 gap-3"> |
| 158 | + {pricingTiers.map((tier) => ( |
| 159 | + <div class={`rounded-xl p-4 text-center ${tier.highlighted ? 'bg-primary text-white ring-2 ring-primary' : 'bg-white border border-gray-200'}`}> |
| 160 | + <div class={`text-xs font-medium mb-1 ${tier.highlighted ? 'text-white/80' : 'text-gray-500'}`}> |
| 161 | + {tier.name} |
| 162 | + </div> |
| 163 | + <div class="text-xl font-bold mb-1">{tier.price}</div> |
| 164 | + <div class={`text-xs ${tier.highlighted ? 'text-white/70' : 'text-gray-400'}`}> |
| 165 | + {tier.period} |
| 166 | + </div> |
| 167 | + </div> |
| 168 | + ))} |
| 169 | + </div> |
| 170 | + <p class="text-center text-xs text-gray-500 mt-3"> |
| 171 | + Emails illimités inclus. Facturation par contacts actifs uniquement. |
| 172 | + </p> |
| 173 | + </section> |
| 174 | + |
| 175 | + <!-- Final CTA --> |
| 176 | + <section class="bg-gradient-to-br from-gray-50 to-orange-50 border border-gray-200 rounded-xl p-8 text-center mb-8"> |
| 177 | + <h2 class="text-2xl font-bold text-slate-900 mb-3"> |
| 178 | + {finalCtaTitle} |
| 179 | + </h2> |
| 180 | + <p class="text-gray-600 mb-6"> |
| 181 | + {finalCtaDescription} |
| 182 | + </p> |
| 183 | + <a |
| 184 | + href={ctaUrl} |
| 185 | + data-cta |
| 186 | + class="inline-block bg-primary text-white px-8 py-4 rounded-lg text-lg font-semibold hover:bg-primary/90 transition-colors shadow-lg shadow-primary/25" |
| 187 | + > |
| 188 | + {ctaText} |
| 189 | + </a> |
| 190 | + </section> |
| 191 | + |
| 192 | + <!-- Minimal footer --> |
| 193 | + <footer class="text-center text-xs text-gray-400 py-4 border-t border-gray-200"> |
| 194 | + <p class="mb-2"> |
| 195 | + © {new Date().getFullYear()} Notifuse. |
| 196 | + <a href="/privacy" class="hover:underline">Politique de confidentialité</a> · |
| 197 | + <a href="/terms" class="hover:underline">CGU</a> · |
| 198 | + <a href="#" id="cookie-manage" class="hover:underline">Cookies</a> |
| 199 | + </p> |
| 200 | + <p> |
| 201 | + <a id="lang-en" href="/" class="text-gray-400 hover:text-gray-600">English</a> |
| 202 | + <span class="text-gray-300">·</span> |
| 203 | + <a id="lang-fr" href="/fr/" class="text-gray-400 hover:text-gray-600">Français</a> |
| 204 | + </p> |
| 205 | + </footer> |
| 206 | + </main> |
| 207 | + |
| 208 | + <!-- Language switcher logic --> |
| 209 | + <script is:inline> |
| 210 | + (function() { |
| 211 | + var path = window.location.pathname.replace(/\/+$/, '') || '/'; |
| 212 | + var isFr = path === '/fr' || path.startsWith('/fr/'); |
| 213 | + var enLink = document.getElementById('lang-en'); |
| 214 | + var frLink = document.getElementById('lang-fr'); |
| 215 | + if (!enLink || !frLink) return; |
| 216 | + var slugMap = { '/pricing': '/fr/tarifs', '/fr/tarifs': '/pricing' }; |
| 217 | + function addSlash(p) { return p === '/' ? '/' : p + '/'; } |
| 218 | + var enPath, frPath; |
| 219 | + if (isFr) { frPath = path; enPath = slugMap[path] || path.replace(/^\/fr/, '') || '/'; } |
| 220 | + else { enPath = path; frPath = slugMap[path] || '/fr' + (path === '/' ? '' : path); } |
| 221 | + enLink.href = addSlash(enPath); |
| 222 | + frLink.href = addSlash(frPath); |
| 223 | + if (isFr) { frLink.classList.remove('text-gray-400'); frLink.classList.add('text-gray-600', 'font-semibold'); } |
| 224 | + else { enLink.classList.remove('text-gray-400'); enLink.classList.add('text-gray-600', 'font-semibold'); } |
| 225 | + })(); |
| 226 | + </script> |
| 227 | + |
| 228 | + <!-- Cookie consent banner --> |
| 229 | + <CookieConsent /> |
| 230 | + |
| 231 | + <!-- GCLID / WBRAID / GBRAID passthrough to CTA links --> |
| 232 | + <script is:inline> |
| 233 | + (function() { |
| 234 | + var p = new URLSearchParams(window.location.search); |
| 235 | + var ids = { gclid: p.get('gclid'), wbraid: p.get('wbraid'), gbraid: p.get('gbraid') }; |
| 236 | + var hasId = ids.gclid || ids.wbraid || ids.gbraid; |
| 237 | + if (!hasId) return; |
| 238 | + document.querySelectorAll('a[data-cta]').forEach(function(a) { |
| 239 | + var u = new URL(a.href); |
| 240 | + for (var k in ids) { if (ids[k]) u.searchParams.set(k, ids[k]); } |
| 241 | + a.href = u.toString(); |
| 242 | + }); |
| 243 | + })(); |
| 244 | + </script> |
| 245 | + </body> |
| 246 | +</html> |
0 commit comments