Skip to content

Commit c70d37c

Browse files
committed
french
1 parent 99d87e5 commit c70d37c

31 files changed

Lines changed: 12454 additions & 38 deletions

src/components/AdLandingPage.astro

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
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+
&copy; {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

Comments
 (0)