// Landing, CTA + Footer + App
const BackToTop = () => {
const [show, setShow] = React.useState(false);
React.useEffect(() => {
const onScroll = () => setShow(window.scrollY > 600);
onScroll();
window.addEventListener('scroll', onScroll, { passive: true });
return () => window.removeEventListener('scroll', onScroll);
}, []);
return (
);
};
const SocialBtn = ({ href, label, children }) => (
{ e.currentTarget.style.background = 'rgba(232,247,243,.2)'; e.currentTarget.style.transform = 'translateY(-2px)'; e.currentTarget.style.borderColor = 'rgba(207,238,231,.4)'; }}
onMouseLeave={e => { e.currentTarget.style.background = 'rgba(232,247,243,.1)'; e.currentTarget.style.transform = ''; e.currentTarget.style.borderColor = 'rgba(207,238,231,.22)'; }}>
{children}
);
const NEWSLETTER_BY_ROLE = {
default: {
eyebrow: 'Quatre fois par an',
titleA: 'Quatre fois par an,',
titleB: 'au rythme des saisons.',
pitch: "Une lettre de saison qui raconte ce qui pousse dans l'écosystème : les nouveaux lieux, les quêtes en cours, ce qu'on a appris, ce qui se sème. Lent, soigné, sans tracker.",
btn: "🌱 S'inscrire à la newsletter",
socialTitle: 'Suivez-nous,',
socialItalic: 'écrivez-nous.',
},
pilote: {
eyebrow: 'Pour votre lieu',
titleA: 'Pour votre lieu,',
titleB: 'un rendez-vous saisonnier.',
pitch: "Recevez chaque saison les nouveaux modules, fiches techniques et retours d'expérience d'autres lieux. De quoi nourrir vos chantiers et faire grandir votre projet sans bruit.",
btn: "🏡 Recevoir la lettre des lieux",
socialTitle: 'Rejoignez les autres pilotes,',
socialItalic: 'partagez vos réussites.',
},
batisseur: {
eyebrow: 'Pour passer à l\'action',
titleA: 'Vos quêtes de saison,',
titleB: 'directement dans votre boîte.',
pitch: "Recevez les quêtes ouvertes près de chez vous, les nouveaux lieux à découvrir et les bons plans graines. Un email par saison, sans tracker.",
btn: "🌿 Recevoir mes quêtes",
socialTitle: 'Vibrez avec la communauté,',
socialItalic: 'suivez les chantiers du réseau.',
},
semeur: {
eyebrow: 'Pour suivre l\'impact',
titleA: 'Le rapport saisonnier,',
titleB: "pour mesurer l'impact.",
pitch: "Recevez chaque saison les chiffres du réseau : graines en circulation, quêtes accomplies, preuves validées, scores REGEN. De quoi orienter vos financements en toute connaissance.",
btn: "🌾 Recevoir le rapport d'impact",
socialTitle: 'Suivez les projets que vous soutenez,',
socialItalic: 'partagez avec votre réseau.',
},
};
// ─────────── Newsletter : inscription Brevo via fonction Supabase ───────────
// La clé API Brevo reste SECRÈTE côté serveur (variable BREVO_API_KEY dans la
// fonction Edge « brevo-subscribe »). Le site n'appelle que cette fonction.
// → Voir INSTALLATION-newsletter-brevo.md.
const NL_SUPABASE_URL = 'https://lmhhrccmgebztioesmik.supabase.co';
const NL_SUPABASE_ANON = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImxtaGhyY2NtZ2VienRpb2VzbWlrIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjUzMjIyOTgsImV4cCI6MjA4MDg5ODI5OH0.epfoBIsZJHLqj96dYE7AvImK_EgjMW9PFtvLk4VwlDc';
const NL_ENDPOINT = NL_SUPABASE_URL + '/functions/v1/brevo-subscribe';
const CTASection = ({ role }) => {
const copy = (role && NEWSLETTER_BY_ROLE[role]) || NEWSLETTER_BY_ROLE.default;
const [prenom, setPrenom] = React.useState('');
const [email, setEmail] = React.useState('');
const [consent, setConsent] = React.useState(false);
const [status, setStatus] = React.useState('idle'); // idle | loading | ok | error
const [errMsg, setErrMsg] = React.useState('');
const submit = async (e) => {
if (e) e.preventDefault();
if (status === 'loading') return;
const mail = email.trim();
if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(mail)) {
setStatus('error'); setErrMsg('Merci d’indiquer un email valide.');
return;
}
if (!consent) {
setStatus('error'); setErrMsg('Merci de cocher la case pour accepter de recevoir la newsletter.');
return;
}
setStatus('loading'); setErrMsg('');
try {
const res = await fetch(NL_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + NL_SUPABASE_ANON,
'apikey': NL_SUPABASE_ANON,
},
body: JSON.stringify({ email: mail, prenom: prenom.trim(), role: role || null, consent: true }),
});
if (!res.ok) {
let msg = 'Une erreur est survenue. Réessayez dans un instant.';
let raw = '';
try { raw = await res.text(); const j = JSON.parse(raw); if (j && j.error) msg = j.error; } catch {}
console.error('[newsletter] HTTP', res.status, 'depuis', NL_ENDPOINT, '→', raw);
setStatus('error'); setErrMsg(msg);
return;
}
setStatus('ok'); setPrenom(''); setEmail(''); setConsent(false);
} catch {
setStatus('error'); setErrMsg('Connexion impossible. Vérifiez votre réseau.');
}
};
return (
{copy.pitch}
{copy.titleA}
{copy.titleB}