From 15e98b9c32eb020db87574c6ebe237655a595990 Mon Sep 17 00:00:00 2001 From: MVA Global Fret Date: Mon, 4 May 2026 16:28:28 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20num=C3=A9rotation=20s=C3=A9quentielle?= =?UTF-8?q?=20MVA-XXX,=20texte=20succ=C3=A8s=20corrig=C3=A9,=20message=20e?= =?UTF-8?q?mail/spam?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloudflare-worker/hubspot-proxy.js | 50 +++++++++++++++++++++++++++++- contact.html | 3 +- js/form-handler.js | 27 +++++++++++----- js/translations.js | 9 ++++-- 4 files changed, 77 insertions(+), 12 deletions(-) diff --git a/cloudflare-worker/hubspot-proxy.js b/cloudflare-worker/hubspot-proxy.js index abb5ff4..b96b53f 100644 --- a/cloudflare-worker/hubspot-proxy.js +++ b/cloudflare-worker/hubspot-proxy.js @@ -44,8 +44,56 @@ export default { : 'pat-eu1-e3c92146-bb17-45fe-8d77-0c665fc4df3b'; try { - const { email } = await request.json(); + const body = await request.json(); + const { email, action } = body; + // ── ACTION : prochain numéro de référence séquentiel ────────────────── + if (action === 'nextRef') { + const hsResponse = await fetch( + 'https://api.hubapi.com/crm/v3/objects/contacts/search', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}`, + }, + body: JSON.stringify({ + filterGroups: [{ + filters: [{ + propertyName: 'reference_client', + operator: 'HAS_PROPERTY', + value: '', + }] + }], + properties: ['reference_client'], + limit: 100, + }), + } + ); + + const data = await hsResponse.json(); + let maxNum = 0; + + if (data.results) { + data.results.forEach(contact => { + const ref = contact.properties?.reference_client || ''; + const match = ref.match(/^MVA-(\d+)$/); + if (match) { + const num = parseInt(match[1], 10); + if (num > maxNum) maxNum = num; + } + }); + } + + const nextNum = maxNum + 1; + const nextRef = 'MVA-' + String(nextNum).padStart(3, '0'); + + return new Response(JSON.stringify({ nextRef }), { + headers: { ...corsHeaders, 'Content-Type': 'application/json' }, + }); + } + + // ── ACTION : vérification doublon par email (défaut) ────────────────── if (!email || typeof email !== 'string') { return new Response( JSON.stringify({ error: 'Email requis' }), diff --git a/contact.html b/contact.html index bc567be..c0bb726 100644 --- a/contact.html +++ b/contact.html @@ -82,7 +82,8 @@

VOTRE NUMÉRO DE RÉFÉRENCE CLIENT

-

Conservez ce numéro — il vous sera demandé lors de chaque envoi.

+

Conservez ce numéro précieusement.

+

📧 Un email de confirmation vous a été envoyé. Vérifiez aussi vos spams.

diff --git a/js/form-handler.js b/js/form-handler.js index 73bfcc6..2e0e6c6 100644 --- a/js/form-handler.js +++ b/js/form-handler.js @@ -32,12 +32,25 @@ document.addEventListener('DOMContentLoaded', () => { if (form) setupContactForm(form); }); -// Génération basée sur le timestamp : impossible d'avoir deux fois le même numéro -function generateRefNumber() { - const year = new Date().getFullYear(); - // Timestamp milliseconde → 6 derniers chiffres, toujours entre 100000 et 999999 - const ts = (Date.now() % 900000) + 100000; - return `MVA-${year}-${ts}`; +// Génération séquentielle via le Worker HubSpot : MVA-001, MVA-002, etc. +// Fallback sur un timestamp court si le Worker est indisponible. +async function generateRefNumber() { + if (WORKER_PROXY_URL) { + try { + const res = await fetch(WORKER_PROXY_URL, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ action: 'nextRef' }), + }); + if (res.ok) { + const data = await res.json(); + if (data.nextRef) return data.nextRef; + } + } catch { /* fallback ci-dessous */ } + } + // Fallback : numéro aléatoire court pour éviter les doublons en cas d'indisponibilité + const rand = String(Math.floor(Math.random() * 900) + 100); + return `MVA-F${rand}`; } // Vérifie si l'email existe déjà dans HubSpot via le proxy Cloudflare Worker. @@ -82,7 +95,7 @@ function setupContactForm(form) { // ───────────────────────────────────────────────────────────────────────── // Nouveau client : génération du numéro de référence unique - const refNumber = generateRefNumber(); + const refNumber = await generateRefNumber(); const data = { firstname: form.firstname.value.trim(), diff --git a/js/translations.js b/js/translations.js index 92b5f1a..49afb25 100644 --- a/js/translations.js +++ b/js/translations.js @@ -113,7 +113,8 @@ const translations = { successTitle: "Inscription réussie !", successMsg: "Merci ! Votre inscription a bien été enregistrée.", refLabel: "VOTRE NUMÉRO DE RÉFÉRENCE CLIENT", - successNote: "Conservez ce numéro — il vous sera demandé lors de chaque envoi.", + successNote: "Conservez ce numéro précieusement.", + emailSent: "📧 Un email de confirmation vous a été envoyé. Vérifiez aussi vos spams.", alreadyTitle: "Vous êtes déjà client !", alreadyMsg: "Votre adresse email est déjà enregistrée dans notre système.", alreadyRefLabel: "VOTRE NUMÉRO DE RÉFÉRENCE EXISTANT", @@ -324,7 +325,8 @@ const translations = { successTitle: "Registration Successful!", successMsg: "Thank you! Your registration has been recorded.", refLabel: "YOUR CLIENT REFERENCE NUMBER", - successNote: "Keep this number — you will need it for every shipment.", + successNote: "Keep this number carefully.", + emailSent: "📧 A confirmation email has been sent to you. Also check your spam folder.", alreadyTitle: "You are already a client!", alreadyMsg: "Your email address is already registered in our system.", alreadyRefLabel: "YOUR EXISTING REFERENCE NUMBER", @@ -535,7 +537,8 @@ const translations = { successTitle: "Vita ny fisoratana anarana!", successMsg: "Misaotra! Voaray tsara ny fisoratana anarana.", refLabel: "NY LAHARANAO MPANJIFA", - successNote: "Tehirizo ity laharana ity — ilaina amin'ny fandefasana tsirairay.", + successNote: "Tehirizo tsara ity laharana ity.", + emailSent: "📧 Nisy email fanamafisana nalefa ho anao. Jereo koa ny spam.", alreadyTitle: "Efa mpanjifa ianao!", alreadyMsg: "Efa voasoratra ao amin'ny rafitra ny adiresy mailaka.", alreadyRefLabel: "NY LAHARANAO EFA MISY",