diff --git a/confirmation.html b/confirmation.html new file mode 100644 index 0000000..52d49ec --- /dev/null +++ b/confirmation.html @@ -0,0 +1,180 @@ + + + + + + Inscription confirmée — MVA Global Fret + + + + + + + + + + + + + + + + + + +
+ +
+
+

Confirmation en cours…

+

Nous finalisons votre inscription et préparons votre numéro de référence client.

+

Quelques secondes…

+
+ + + + + + +
+ + + + + + + + diff --git a/js/confirmation.js b/js/confirmation.js new file mode 100644 index 0000000..0aeba36 --- /dev/null +++ b/js/confirmation.js @@ -0,0 +1,110 @@ +// ============================================================ +// MVA Global Fret — Page de confirmation post-double-opt-in +// ============================================================ +// Cette page est la cible de redirection après que l'utilisateur +// a cliqué sur "Confirmer" dans l'email de validation HubSpot. +// +// HubSpot redirige vers : +// https://mva-global-fret.github.io/site-mva-global-fret/confirmation.html?email={contact.email} +// +// Étapes : +// 1. Lire l'email depuis l'URL +// 2. Demander au Cloudflare Worker la fiche du contact (incluant reference_client) +// 3. Envoyer un email de bienvenue via EmailJS contenant la référence +// 4. Afficher la référence à l'écran +// +// Si une étape échoue, on affiche un fallback poli (l'inscription +// reste valide côté HubSpot, c'est juste l'email qui ne part pas). +// ============================================================ + +const WORKER_PROXY_URL = 'https://mva-hubspot-proxy.mvaglobalfret.workers.dev'; +const EMAILJS_PUBLIC_KEY = '8KUlaQ7BDVIbkZRyP'; +const EMAILJS_SERVICE_ID = 'service_aeamo3x'; +const EMAILJS_TEMPLATE_ID = 'template_s1kr2et'; + +// Marqueur localStorage : empêche de relancer l'envoi si l'utilisateur +// recharge la page après confirmation (par sécurité ET pour ne pas +// renvoyer 3 fois le même email). +const STORAGE_KEY_PREFIX = 'mva-confirm-sent-'; + +document.addEventListener('DOMContentLoaded', async () => { + if (typeof emailjs !== 'undefined') { + emailjs.init({ publicKey: EMAILJS_PUBLIC_KEY }); + } + + const email = getEmailFromUrl(); + + if (!email) { + // Pas d'email dans l'URL : on affiche quand même un succès générique + // (l'utilisateur a bien confirmé puisqu'il atterrit ici depuis HubSpot) + showSuccess(null); + return; + } + + try { + const contact = await fetchContact(email); + + if (!contact) { + // Contact non trouvé via Worker — on affiche succès quand même + showSuccess(null); + return; + } + + const ref = contact.reference_client || null; + + // Idempotence : un seul email par confirmation + const storageKey = STORAGE_KEY_PREFIX + email.toLowerCase(); + if (!localStorage.getItem(storageKey)) { + await sendWelcomeEmail({ + firstname: contact.firstname || '', + email: email, + reference_client: ref || '', + }); + localStorage.setItem(storageKey, String(Date.now())); + } + + showSuccess(ref); + } catch (err) { + console.warn('[confirmation] flow failed:', err); + showError(); + } +}); + +function getEmailFromUrl() { + const params = new URLSearchParams(window.location.search); + const raw = params.get('email'); + if (!raw) return null; + const email = raw.trim().toLowerCase(); + return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email) ? email : null; +} + +async function fetchContact(email) { + const res = await fetch(WORKER_PROXY_URL, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email }), + }); + if (!res.ok) throw new Error('Worker error: ' + res.status); + const data = await res.json(); + if (!data.results || data.results.length === 0) return null; + return data.results[0].properties; +} + +async function sendWelcomeEmail(payload) { + if (typeof emailjs === 'undefined') return; + await emailjs.send(EMAILJS_SERVICE_ID, EMAILJS_TEMPLATE_ID, payload); +} + +function showSuccess(ref) { + document.getElementById('cardLoading').style.display = 'none'; + document.getElementById('cardSuccess').style.display = ''; + if (ref) { + document.getElementById('refDisplay').textContent = ref; + document.getElementById('refBlock').style.display = ''; + } +} + +function showError() { + document.getElementById('cardLoading').style.display = 'none'; + document.getElementById('cardError').style.display = ''; +} diff --git a/js/translations.js b/js/translations.js index e4ac8ef..d1ae64a 100644 --- a/js/translations.js +++ b/js/translations.js @@ -333,6 +333,21 @@ const translations = { ctaSubtitle: "Contactez-nous avec votre lien produit, nous vous établissons un devis sous 24h.", ctaContact: "Nous contacter", ctaMessenger: "Messenger" + }, + + confirmation: { + loadingTitle: "Confirmation en cours…", + loadingDesc: "Nous finalisons votre inscription et préparons votre numéro de référence client.", + loadingHint: "Quelques secondes…", + successTitle: "Inscription confirmée !", + successDesc: "Bienvenue chez MVA Global Fret. Votre numéro de référence client vous a été envoyé par email.", + successHint: "📧 Pensez aussi à vérifier vos spams.", + refLabel: "VOTRE NUMÉRO DE RÉFÉRENCE CLIENT", + errorTitle: "Confirmation reçue", + errorDesc: "Votre confirmation est bien enregistrée chez MVA Global Fret. En cas de question sur votre numéro de référence, contactez-nous directement.", + backHome: "Retour à l'accueil", + guide: "Guide d'envoi", + contactUs: "Nous contacter" } }, @@ -670,6 +685,21 @@ const translations = { ctaSubtitle: "Contact us with your product link, we'll send you a quote within 24h.", ctaContact: "Contact us", ctaMessenger: "Messenger" + }, + + confirmation: { + loadingTitle: "Confirming…", + loadingDesc: "We're finalising your registration and preparing your client reference number.", + loadingHint: "A few seconds…", + successTitle: "Registration confirmed!", + successDesc: "Welcome to MVA Global Fret. Your client reference number has been sent to you by email.", + successHint: "📧 Don't forget to check your spam folder.", + refLabel: "YOUR CLIENT REFERENCE NUMBER", + errorTitle: "Confirmation received", + errorDesc: "Your confirmation has been recorded with MVA Global Fret. If you have any question about your reference number, please contact us directly.", + backHome: "Back to home", + guide: "Shipping guide", + contactUs: "Contact us" } }, @@ -1007,6 +1037,21 @@ const translations = { ctaSubtitle: "Mifandraisa aminay miaraka amin'ny rohin'ny vokatra, hanome tombam-bidy izahay ao anatin'ny 24 ora.", ctaContact: "Mifandraisa aminay", ctaMessenger: "Messenger" + }, + + confirmation: { + loadingTitle: "Eo am-panamafisana…", + loadingDesc: "Mamarana ny fisoratana anaranareo izahay ary manomana ny laharanao mpanjifa.", + loadingHint: "Segondra vitsivitsy…", + successTitle: "Voamarina ny fisoratana anarana!", + successDesc: "Tongasoa eto amin'ny MVA Global Fret. Nalefa tao amin'ny mailakao ny laharanao mpanjifa.", + successHint: "📧 Jereo koa ao amin'ny spam.", + refLabel: "NY LAHARANAO MPANJIFA", + errorTitle: "Voaray ny fanamafisana", + errorDesc: "Voarakitra tsara eto amin'ny MVA Global Fret ny fanamafisanareo. Raha manana fanontaniana mikasika ny laharana, mifandraisa aminay.", + backHome: "Hiverina any am-pandraisana", + guide: "Tari-dàlana fandefasana", + contactUs: "Mifandraisa aminay" } } };