1<!doctype html> 2<html lang="fr"> 3 <head> 4 <meta charset="UTF-8" /> 5 <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> 6 <link rel="canonical" href="https://labatutgroup.com/suivre-ma-commande" /> 7 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 8 <title>Suivre ma commande | Labatut Group</title> 9 <meta name="description" content="Suivez votre commande en temps réel. Saisissez votre numéro de commande et votre code postal pour consulter le statut de votre livraison Labatut Group." /> 10 <meta name="robots" content="index, follow" /> 11 <meta property="og:title" content="Suivre ma commande | Labatut Group" /> 12 <meta property="og:description" content="Suivez votre commande en temps réel. Saisissez votre numéro de commande et votre code postal pour consulter le statut de votre livraison." /> 13 <meta property="og:type" content="website" /> 14 <meta property="og:url" content="https://labatutgroup.com/suivre-ma-commande" /> 15 <meta property="og:image" content="https://labatutgroup.com/camion_scania_labatut_routier_final.png" /> 16 <meta property="og:locale" content="fr_FR" /> 17
17<script type="application/ld+json"> 18 { 19 "@context": "https://schema.org", 20 "@type": "WebPage", 21 "name": "Suivre ma commande â Labatut Group", 22 "description": "Suivez votre commande en temps réel avec Labatut Group.", 23 "url": "https://labatutgroup.com/suivre-ma-commande", 24 "publisher": { 25 "@type": "Organization", 26 "name": "Labatut Group", 27 "url": "https://labatutgroup.com" 28 } 29 } 30 </script>
30 31 <style> 32 * { margin: 0; padding: 0; box-sizing: border-box; } 33 body { 34 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, sans-serif; 35 background: #f5f7f3; 36 color: #333; 37 min-height: 100vh; 38 } 39 .header { 40 background: white; 41 border-bottom: 3px solid #70a752; 42 padding: 1rem 2rem; 43 display: flex; 44 align-items: center; 45 justify-content: space-between; 46 } 47 .header a { 48 text-decoration: none; 49 color: #70a752; 50 font-weight: 700; 51 font-size: 1.25rem; 52 } 53 .header nav a { 54 color: #555; 55 font-weight: 500; 56 font-size: 0.95rem; 57 margin-left: 1.5rem; 58 } 59 .container { 60 max-width: 600px; 61 margin: 3rem auto; 62 padding: 0 1rem; 63 } 64 h1 { 65 font-size: 1.75rem; 66 font-weight: 700; 67 color: #70a752; 68 text-align: center; 69 margin-bottom: 0.5rem; 70 } 71 .subtitle { 72 text-align: center; 73 color: #666; 74 margin-bottom: 2rem; 75 font-size: 0.95rem; 76 } 77 form { 78 display: flex; 79 flex-direction: column; 80 gap: 1rem; 81 } 82 label { 83 display: block; 84 font-weight: 600; 85 margin-bottom: 0.4rem; 86 font-size: 0.9rem; 87 color: #333; 88 } 89 input { 90 width: 100%; 91 padding: 0.75rem; 92 border: 1px solid #ddd; 93 border-radius: 8px; 94 font-size: 1rem; 95 transition: border-color 0.2s; 96 } 97 input:focus { 98 outline: none; 99 border-color: #70a752; 100 } 101 button { 102 background: #70a752; 103 color: white; 104 border: none; 105 padding: 0.85rem 1.5rem; 106 border-radius: 8px; 107 font-size: 1rem; 108 font-weight: 600; 109 cursor: pointer; 110 transition: opacity 0.2s; 111 } 112 button:hover { opacity: 0.9; } 113 button:disabled { opacity: 0.6; cursor: not-allowed; } 114 .error { 115 margin-top: 1.5rem; 116 padding: 1rem; 117 background: #fee; 118 border: 1px solid #f5c6cb; 119 border-radius: 8px; 120 color: #c0392b; 121 text-align: center; 122 } 123 .result { 124 margin-top: 1.5rem; 125 padding: 1.5rem; 126 background: #f8faf8; 127 border: 1px solid #70a752; 128 border-radius: 12px; 129 } 130 .result-header { 131 display: flex; 132 align-items: center; 133 justify-content: space-between; 134 margin-bottom: 1rem; 135 padding-bottom: 1rem; 136 border-bottom: 1px solid #e0e0e0; 137 } 138 .result-ref { font-weight: 700; font-size: 1.1rem; } 139 .result-status { font-size: 1.1rem; font-weight: 700; color: #70a752; } 140 .result-info { margin-bottom: 0.5rem; font-size: 0.95rem; } 141 .result-info strong { color: #333; } 142 .rdv-box { 143 margin-bottom: 1rem; 144 padding: 0.75rem 1rem; 145 background: #e8f5e9; 146 border-radius: 8px; 147 font-size: 0.95rem; 148 } 149 .rdv-box strong { color: #2e7d32; } 150 .product-box { 151 margin-bottom: 1rem; 152 padding: 0.75rem 1rem; 153 background: #f0f4fa; 154 border-radius: 8px; 155 font-size: 0.9rem; 156 } 157 .product-box strong { color: #1565c0; } 158 .info-section { 159 margin-bottom: 1rem; 160 } 161 .info-section h3 { 162 font-size: 0.8rem; 163 font-weight: 600; 164 color: #888; 165 margin-bottom: 0.4rem; 166 text-transform: uppercase; 167 letter-spacing: 0.5px; 168 } 169 .info-section .info-content { 170 font-size: 0.95rem; 171 color: #333; 172 } 173 .info-section .info-content div { margin-bottom: 0.15rem; } 174 .info-section .info-content .name { font-weight: 600; } 175 .info-section .info-content .sub { color: #888; font-size: 0.85rem; } 176 .badges { 177 margin-bottom: 1rem; 178 display: flex; 179 gap: 0.5rem; 180 flex-wrap: wrap; 181 } 182 .badge { 183 padding: 0.4rem 0.75rem; 184 background: #f0f0f0; 185 border-radius: 6px; 186 font-size: 0.85rem; 187 }
188 .timeline { margin-top: 1rem; } 189 .timeline h3 { font-size: 1rem; font-weight: 600; margin-bottom: 0.75rem; } 190 .timeline-list { position: relative; padding-left: 1.5rem; } 191 .timeline-item { position: relative; padding-bottom: 1rem; padding-left: 1rem; } 192 .timeline-item:not(:last-child) { border-left: 2px solid #70a752; } 193 .timeline-dot { 194 position: absolute; left: -7px; top: 0; 195 width: 12px; height: 12px; border-radius: 50%; 196 background: #70a752; 197 } 198 .timeline-label { font-weight: 600; font-size: 0.9rem; } 199 .timeline-date { font-size: 0.85rem; color: #888; } 200 .timeline-location { font-size: 0.85rem; color: #aaa; } 201 .timeline-remark { 202 font-size: 0.82rem; 203 color: #555; 204 margin-top: 0.2rem; 205 padding: 0.3rem 0.5rem; 206 background: #f5f5f5; 207 border-radius: 4px; 208 font-style: italic; 209 } 210 .footer { 211 text-align: center; 212 padding: 2rem; 213 color: #888; 214 font-size: 0.85rem; 215 } 216 .footer a { color: #70a752; text-decoration: none; } 217 218 .contact-btn { 219 display: inline-block; 220 margin-top: 1rem; 221 padding: 0.7rem 1.5rem; 222 background: #70a752; 223 color: #fff; 224 text-decoration: none; 225 font-size: 0.95rem; 226 font-weight: 600; 227 border-radius: 8px; 228 transition: opacity 0.2s; 229 text-align: center; 230 } 231 .contact-btn:hover { opacity: 0.9; } 232 .contact-btn svg { 233 vertical-align: middle; 234 margin-right: 0.4rem; 235 width: 18px; 236 height: 18px; 237 } 238 </style> 239 </head> 240 <body> 241 <div class="header"> 242 <a href="/">Labatut Group</a> 243 <nav> 244 <a href="/">Accueil</a> 245 <a href="/blog">Blog</a> 246 <a href="/suivre-ma-commande" style="display:inline-block;padding:0.5rem 1rem;background:#70a752;color:#fff;font-size:0.875rem;font-weight:600;border-radius:9999px;white-space:nowrap;text-decoration:none;transition:background 0.2s;box-shadow:0 1px 3px rgba(0,0,0,0.1);">Suivre ma commande</a> 247 </nav> 248 </div> 249 250 <div class="container"> 251 <h1>Suivre ma commande</h1> 252 <p class="subtitle">Saisissez votre numéro de commande (bon de livraison, référence expéditeur ou destinataire) et le code postal de livraison pour suivre votre colis.</p> 253 254 <form id="trackForm"> 255 <div> 256 <label for="orderRef">Numéro de commande</label> 257 <input type="text" id="orderRef" name="orderRef" placeholder="ex. S123456789" required maxlength="100" /> 258 </div> 259 <div> 260 <label for="postalCode">Code postal de livraison</label> 261 <input type="text" id="postalCode" name="postalCode" placeholder="ex. 75001" required maxlength="10" /> 262 </div> 263 <button type="submit" id="submitBtn">Suivre ma commande</button> 264 </form> 265 266 <div id="errorBox" style="display:none;" class="error"></div> 267 <div id="resultBox" style="display:none;"></div> 268 </div> 269 270 <div class="footer"> 271 <p>© 2026 Labatut Group â <a href="https://labatutgroup.com">labatutgroup.com</a></p> 272 </div> 273 274
274<script> 275 const form = document.getElementById('trackForm'); 276 const errorBox = document.getElementById('errorBox'); 277 const resultBox = document.getElementById('resultBox'); 278 const submitBtn = document.getElementById('submitBtn'); 279 280 function formatDate(dateStr) { 281 if (!dateStr) return ''; 282 try { 283 const d = new Date(dateStr); 284 var opts = { day: '2-digit', month: 'long', year: 'numeric' }; 285 if (d.getHours() !== 0 || d.getMinutes() !== 0) { 286 opts.hour = '2-digit'; 287 opts.minute = '2-digit'; 288 } 289 return d.toLocaleDateString('fr-FR', opts); 290 } catch { return dateStr; } 291 } 292 293 function escapeHtml(str) { 294 if (!str) return ''; 295 return String(str) 296 .replace(/&/g, '&') 297 .replace(/</g, '<') 298 .replace(/>/g, '>') 299 .replace(/"/g, '"'); 300 } 301 302 form.addEventListener('submit', async (e) => { 303 e.preventDefault(); 304 const orderRef = document.getElementById('orderRef').value.trim(); 305 const postalCode = document.getElementById('postalCode').value.trim(); 306 if (!orderRef || !postalCode) return; 307 308 submitBtn.disabled = true; 309 submitBtn.textContent = 'Recherche en cours...'; 310 errorBox.style.display = 'none'; 311 resultBox.style.display = 'none'; 312 313 try { 314 const response = await fetch('/api/track.php', { 315 method: 'POST', 316 headers: { 'Content-Type': 'application/json' }, 317 body: JSON.stringify({ orderRef, postalCode }), 318 }); 319 const data = await response.json(); 320 321 if (!response.ok) { 322 errorBox.textContent = data.error || 'Une erreur est survenue. Veuillez réessayer.'; 323 errorBox.style.display = 'block'; 324 } else { 325 let html = '<div class="result">'; 326 327 // En-tête : référence + statut 328 html += '<div class="result-header">'; 329 html += '<div><div style="font-size:0.85rem;color:#888">Commande</div><div class="result-ref">' + escapeHtml(data.reference || '') + '</div></div>'; 330 html += '<div class="result-status">' + escapeHtml(data.status || 'Statut inconnu') + '</div>'; 331 html += '</div>'; 332 333 // Date de rendez-vous de livraison (mise en avant) 334 if (data.appointmentDate) { 335 html += '<div class="rdv-box"><strong>Rendez-vous de livraison :</strong> ' + formatDate(data.appointmentDate) + '</div>'; 336 } 337 338 // Code produit 339 if (data.productCode) { 340 html += '<div class="product-box"><strong>Service :</strong> ' + escapeHtml(data.productCode) + '</div>'; 341 } 342 343 // Infos destinataire 344 if (data.consignee && (data.consignee.name || data.consignee.city)) { 345 html += '<div class="info-section">'; 346 html += '<h3>Destinataire</h3>'; 347 html += '<div class="info-content">'; 348 if (data.consignee.name) html += '<div class="name">' + escapeHtml(data.consignee.name) + '</div>'; 349 if (data.consignee.address1) html += '<div>' + escapeHtml(data.consignee.address1) + '</div>'; 350 if (data.consignee.zip || data.consignee.city) html += '<div>' + escapeHtml(data.consignee.zip || '') + ' ' + escapeHtml(data.consignee.city || '') + '</div>'; 351 if (data.consignee.country) html += '<div class="sub">' + escapeHtml(data.consignee.country) + '</div>'; 352 html += '</div></div>'; 353 } 354 355 // Infos expéditeur 356 if (data.consignor && data.consignor.name) { 357 html += '<div class="info-section">'; 358 html += '<h3>Expéditeur</h3>'; 359 html += '<div class="info-content">'; 360 if (data.consignor.name) html += '<div class="name">' + escapeHtml(data.consignor.name) + '</div>'; 361 if (data.consignor.city) html += '<div class="sub">' + escapeHtml(data.consignor.city) + '</div>'; 362 html += '</div></div>'; 363 } 364 365 // Badges infos colis 366 if (data.handlingUnits || data.grossWeight) { 367 html += '<div class="badges">'; 368 if (data.handlingUnits) html += '<span class="badge">
368' + data.handlingUnits + ' unité' + (data.handlingUnits > 1 ? 's' : '') + ' de manutention</span>'; 369 if (data.grossWeight) html += '<span class="badge">Poids : ' + escapeHtml(data.grossWeight) + '</span>'; 370 html += '</div>'; 371 } 372 373 // Timeline 374 if (data.timeline && data.timeline.length > 0) { 375 html += '<div class="timeline"><h3>Historique du suivi</h3><div class="timeline-list">'; 376 data.timeline.forEach(function(event) { 377 html += '<div class="timeline-item">'; 378 html += '<div class="timeline-dot"></div>'; 379 html += '<div class="timeline-label">' + escapeHtml(event.label || 'Ãvénement') + '</div>'; 380 if (event.date) html += '<div class="timeline-date">' + formatDate(event.date) + '</div>'; 381 if (event.location) html += '<div class="timeline-location">' + escapeHtml(event.location) + '</div>'; 382 if (event.remark) html += '<div class="timeline-remark">' + escapeHtml(event.remark) + '</div>'; 383 html += '</div>'; 384 }); 385 html += '</div></div>'; 386 } else { 387 html += '<div style="color:#888;font-size:0.9rem">Aucun événement de suivi disponible pour le moment.</div>'; 388 } 389 390 // Bouton contacter le service client 391 var mailtoLink = 'mailto:[email protected]?subject=' + encodeURIComponent('Suivi commande ' + (data.reference || '')); 392 html += '<a href="' + mailtoLink + '" class="contact-btn"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" /></svg>Contacter le service client</a>'; 393 394 html += '</div>'; 395 resultBox.innerHTML = html; 396 resultBox.style.display = 'block'; 397 } 398 } catch (err) { 399 errorBox.textContent = 'Service temporairement indisponible. Veuillez réessayer dans un instant.'; 400 errorBox.style.display = 'block'; 401 } finally { 402 submitBtn.disabled = false; 403 submitBtn.textContent = 'Suivre ma commande'; 404 } 405 }); 406 </script>
406 407 </body> 408</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.