feat: numérotation séquentielle MVA-XXX, texte succès corrigé, message email/spam

This commit is contained in:
MVA Global Fret 2026-05-04 16:28:28 +02:00
parent eea5717143
commit 15e98b9c32
4 changed files with 77 additions and 12 deletions

View File

@ -44,8 +44,56 @@ export default {
: 'pat-eu1-e3c92146-bb17-45fe-8d77-0c665fc4df3b'; : 'pat-eu1-e3c92146-bb17-45fe-8d77-0c665fc4df3b';
try { 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') { if (!email || typeof email !== 'string') {
return new Response( return new Response(
JSON.stringify({ error: 'Email requis' }), JSON.stringify({ error: 'Email requis' }),

View File

@ -82,7 +82,8 @@
<p style="margin:0 0 4px; font-size:0.85rem; color: var(--gold); font-weight:600;" data-i18n="contact.refLabel">VOTRE NUMÉRO DE RÉFÉRENCE CLIENT</p> <p style="margin:0 0 4px; font-size:0.85rem; color: var(--gold); font-weight:600;" data-i18n="contact.refLabel">VOTRE NUMÉRO DE RÉFÉRENCE CLIENT</p>
<p id="refNumberDisplay" style="margin:0; font-size:1.6rem; font-weight:700; color:#fff; letter-spacing:2px;"></p> <p id="refNumberDisplay" style="margin:0; font-size:1.6rem; font-weight:700; color:#fff; letter-spacing:2px;"></p>
</div> </div>
<p style="margin-top:12px; font-size:0.9rem; color: var(--text-light);" data-i18n="contact.successNote">Conservez ce numéro — il vous sera demandé lors de chaque envoi.</p> <p style="margin-top:12px; font-size:0.9rem; color: var(--text-light);" data-i18n="contact.successNote">Conservez ce numéro précieusement.</p>
<p style="margin-top:8px; font-size:0.85rem; color: var(--text-light);" data-i18n="contact.emailSent">📧 Un email de confirmation vous a été envoyé. Vérifiez aussi vos spams.</p>
</div> </div>
<!-- DÉJÀ INSCRIT --> <!-- DÉJÀ INSCRIT -->

View File

@ -32,12 +32,25 @@ document.addEventListener('DOMContentLoaded', () => {
if (form) setupContactForm(form); if (form) setupContactForm(form);
}); });
// Génération basée sur le timestamp : impossible d'avoir deux fois le même numéro // Génération séquentielle via le Worker HubSpot : MVA-001, MVA-002, etc.
function generateRefNumber() { // Fallback sur un timestamp court si le Worker est indisponible.
const year = new Date().getFullYear(); async function generateRefNumber() {
// Timestamp milliseconde → 6 derniers chiffres, toujours entre 100000 et 999999 if (WORKER_PROXY_URL) {
const ts = (Date.now() % 900000) + 100000; try {
return `MVA-${year}-${ts}`; 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. // 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 // Nouveau client : génération du numéro de référence unique
const refNumber = generateRefNumber(); const refNumber = await generateRefNumber();
const data = { const data = {
firstname: form.firstname.value.trim(), firstname: form.firstname.value.trim(),

View File

@ -113,7 +113,8 @@ const translations = {
successTitle: "Inscription réussie !", successTitle: "Inscription réussie !",
successMsg: "Merci ! Votre inscription a bien été enregistrée.", successMsg: "Merci ! Votre inscription a bien été enregistrée.",
refLabel: "VOTRE NUMÉRO DE RÉFÉRENCE CLIENT", 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 !", alreadyTitle: "Vous êtes déjà client !",
alreadyMsg: "Votre adresse email est déjà enregistrée dans notre système.", alreadyMsg: "Votre adresse email est déjà enregistrée dans notre système.",
alreadyRefLabel: "VOTRE NUMÉRO DE RÉFÉRENCE EXISTANT", alreadyRefLabel: "VOTRE NUMÉRO DE RÉFÉRENCE EXISTANT",
@ -324,7 +325,8 @@ const translations = {
successTitle: "Registration Successful!", successTitle: "Registration Successful!",
successMsg: "Thank you! Your registration has been recorded.", successMsg: "Thank you! Your registration has been recorded.",
refLabel: "YOUR CLIENT REFERENCE NUMBER", 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!", alreadyTitle: "You are already a client!",
alreadyMsg: "Your email address is already registered in our system.", alreadyMsg: "Your email address is already registered in our system.",
alreadyRefLabel: "YOUR EXISTING REFERENCE NUMBER", alreadyRefLabel: "YOUR EXISTING REFERENCE NUMBER",
@ -535,7 +537,8 @@ const translations = {
successTitle: "Vita ny fisoratana anarana!", successTitle: "Vita ny fisoratana anarana!",
successMsg: "Misaotra! Voaray tsara ny fisoratana anarana.", successMsg: "Misaotra! Voaray tsara ny fisoratana anarana.",
refLabel: "NY LAHARANAO MPANJIFA", 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!", alreadyTitle: "Efa mpanjifa ianao!",
alreadyMsg: "Efa voasoratra ao amin'ny rafitra ny adiresy mailaka.", alreadyMsg: "Efa voasoratra ao amin'ny rafitra ny adiresy mailaka.",
alreadyRefLabel: "NY LAHARANAO EFA MISY", alreadyRefLabel: "NY LAHARANAO EFA MISY",