Advertisement
julienpierre

SNCF Code vendeur final

Apr 27th, 2025 (edited)
273
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 5 12.04 KB | Source Code | 0 0
  1. <div id="sncf-vendeur" style="font-family: Arial, sans-serif; background: #f7f7f7; padding: 20px; max-width: 600px; margin: auto; border-radius: 10px;">
  2.     <h2 style="text-align: center; color: #0099cc;">Mon Billet Étudiant SNCF</h2>
  3.  
  4.     <div id="main-menu" style="display: flex; flex-wrap: wrap; justify-content: center; gap: 20px; margin-top: 20px;">
  5.         <div onclick="startBuying()" style="background: #0099cc; width: 280px; height: 160px; color: white; display: flex; flex-direction: column; align-items: center; justify-content: center; border-radius: 10px; cursor: pointer;">
  6.             <div style="font-size: 18px; font-weight: bold;">Acheter un billet</div>
  7.         </div>
  8.     </div>
  9.  
  10.     <div id="buy-ticket" style="display:none; margin-top: 30px; text-align: center;">
  11.         <h2 style="color: #0099cc;">Acheter un billet</h2>
  12.  
  13.         <div style="margin-bottom: 15px;">
  14.             <select id="destination" style="padding: 10px; font-size: 16px; width: 80%;">
  15.                 <option value="">-- Choisir une destination --</option>
  16.                 <option value="Rennes">Rennes</option>
  17.                 <option value="Lille">Lille</option>
  18.                 <option value="Strasbourg">Strasbourg</option>
  19.                 <option value="Marseille">Marseille</option>
  20.                 <option value="Biarritz">Biarritz</option>
  21.                 <option value="Toulouse">Toulouse</option>
  22.                 <option value="Nice">Nice</option>
  23.                 <option value="Bordeaux">Bordeaux</option>
  24.                 <option value="Lyon">Lyon</option>
  25.                 <option value="Nantes">Nantes</option>
  26.             </select>
  27.         </div>
  28.  
  29.         <div style="display: flex; justify-content: center; gap: 10px; margin-bottom: 20px;">
  30.             <button onclick="setTripType('AS')" style="padding: 12px 20px; border: none; background: #0099cc; color: white; border-radius: 8px;">Aller-simple</button>
  31.             <button onclick="setTripType('AR')" style="padding: 12px 20px; border: none; background: #0099cc; color: white; border-radius: 8px;">Aller-retour</button>
  32.         </div>
  33.  
  34.         <div id="next-steps" style="display:none;"></div>
  35.  
  36.         <div style="margin-top: 20px;">
  37.             <button onclick="backToMenu()" style="padding: 10px 20px; background: #ccc; border: none; border-radius: 8px;">Retour au menu</button>
  38.         </div>
  39.     </div>
  40. </div>
  41.  
  42. <script>
  43.     let trajetType = "";
  44.     let classeChoisie = null;
  45.     let nbPassagers = 1;
  46.     let horaireAller = null;
  47.     let horaireRetour = null;
  48.     let prixBase1 = 0;
  49.     let prixBase2 = 0;
  50.     let dayDepart = null;
  51.     let dayRetour = null;
  52.  
  53.     const distances = {
  54.         Rennes: 350,
  55.         Lille: 220,
  56.         Strasbourg: 490,
  57.         Marseille: 775,
  58.         Biarritz: 685,
  59.         Toulouse: 680,
  60.         Nice: 930,
  61.         Bordeaux: 580,
  62.         Lyon: 465,
  63.         Nantes: 385
  64.     };
  65.     const prixKm = 0.095;
  66.     const joursSemaine = ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"];
  67.  
  68.     function startBuying() {
  69.         document.getElementById('main-menu').style.display = 'none';
  70.         document.getElementById('buy-ticket').style.display = 'block';
  71.     }
  72.  
  73.     function backToMenu() {
  74.         document.getElementById('buy-ticket').style.display = 'none';
  75.         document.getElementById('main-menu').style.display = 'flex';
  76.         document.getElementById('next-steps').style.display = 'none';
  77.         resetAll();
  78.     }
  79.  
  80.     function resetAll() {
  81.         trajetType = "";
  82.         classeChoisie = null;
  83.         nbPassagers = 1;
  84.         horaireAller = null;
  85.         horaireRetour = null;
  86.         prixBase1 = prixBase2 = 0;
  87.         dayDepart = dayRetour = null;
  88.         document.getElementById('next-steps').innerHTML = '';
  89.     }
  90.  
  91.     function setTripType(type) {
  92.         trajetType = type;
  93.         const dest = document.getElementById('destination').value;
  94.         if (!dest) {
  95.             alert("Choisissez d'abord une destination.");
  96.             return;
  97.         }
  98.  
  99.         let html = `<div style="margin-bottom:15px;">
  100.       <label><strong>Jour de départ :</strong></label><br>
  101.       <select id="day-depart-select" style="padding:10px;font-size:16px;width:80%;margin-top:5px;">`;
  102.         joursSemaine.forEach(j => html += `<option>${j}</option>`);
  103.         html += `</select></div>`;
  104.  
  105.         if (type === 'AR') {
  106.             html += `<div style="margin-bottom:15px;">
  107.         <label><strong>Jour de retour :</strong></label><br>
  108.         <select id="day-retour-select" style="padding:10px;font-size:16px;width:80%;margin-top:5px;">`;
  109.             joursSemaine.forEach(j => html += `<option>${j}</option>`);
  110.             html += `</select></div>`;
  111.         }
  112.  
  113.         html += '<button onclick="confirmDays()" style="padding:10px 20px;background:#0099cc;color:white;border:none;border-radius:8px;">Valider les jours</button>';
  114.  
  115.         const next = document.getElementById('next-steps');
  116.         next.innerHTML = html;
  117.         next.style.display = 'block';
  118.     }
  119.  
  120.     function confirmDays() {
  121.         const dest = document.getElementById('destination').value;
  122.         const dist = distances[dest];
  123.         prixBase1 = Math.round(dist * prixKm + 30 + Math.random() * 10);
  124.         prixBase2 = Math.round(dist * prixKm + Math.random() * 10);
  125.  
  126.         dayDepart = document.getElementById('day-depart-select').value;
  127.         if (trajetType === 'AR') {
  128.             dayRetour = document.getElementById('day-retour-select').value;
  129.         }
  130.  
  131.         document.getElementById('next-steps').innerHTML = generateHorairesHTML();
  132.     }
  133.  
  134.     function randomHorairePair(minH, maxH) {
  135.         const h1 = minH + Math.floor(Math.random() * (maxH - minH + 1));
  136.         const m1 = Math.floor(Math.random() * 60);
  137.         let d1 = new Date(2000, 0, 1, h1, m1);
  138.         let delay = 45 + Math.floor(Math.random() * (120 - 45 + 1));
  139.         let d2 = new Date(d1.getTime() + delay * 60000);
  140.         let latest = new Date(2000, 0, 1, maxH, 0);
  141.         if (d2 > latest) d2 = latest;
  142.         const toStr = d => `${d.getHours()}h${d.getMinutes().toString().padStart(2,'0')}`;
  143.         return [toStr(d1), toStr(d2)];
  144.     }
  145.  
  146.     function generateHorairesHTML() {
  147.         const mAller = randomHorairePair(6, 9),
  148.             aAller = randomHorairePair(13, 16),
  149.             mRetour = randomHorairePair(6, 9),
  150.             aRetour = randomHorairePair(13, 16);
  151.         let html = `<p><strong>Jour départ :</strong> ${dayDepart}</p>
  152.       <h3 style="color:#0099cc;">Départ :</h3>`;
  153.         html += buildHorairesSection(mAller, 'aller', 'Matin');
  154.         html += buildHorairesSection(aAller, 'aller', 'Après-midi');
  155.  
  156.         if (trajetType === 'AR') {
  157.             html += `<p><strong>Jour retour :</strong> ${dayRetour}</p>
  158.              <h3 style="color:#0099cc;">Retour :</h3>`;
  159.             html += buildHorairesSection(mRetour, 'retour', 'Matin');
  160.             html += buildHorairesSection(aRetour, 'retour', 'Après-midi');
  161.         }
  162.  
  163.         html += buildClasseAndPassagers();
  164.         return html;
  165.     }
  166.  
  167.     function buildHorairesSection(hs, type, label) {
  168.         let sec = `<div style='margin-bottom:10px;'><strong>${label} :</strong></div>
  169.              <div style='display:flex;justify-content:center;gap:10px;margin-bottom:20px;'>`;
  170.         hs.forEach(h => {
  171.             sec += `<div onclick="selectHoraire(this,'${type}')" style="background:#eee;padding:20px 15px;border-radius:10px;width:100px;text-align:center;cursor:pointer;">
  172.               ${h}<br><small>${type==='aller'?'Aller':'Retour'}</small>
  173.             </div>`;
  174.         });
  175.         sec += '</div>';
  176.         return sec;
  177.     }
  178.  
  179.     function selectHoraire(el, type) {
  180.         if (type === 'aller') {
  181.             if (horaireAller) {
  182.                 horaireAller.style.background = '#eee';
  183.                 horaireAller.style.color = 'black';
  184.             }
  185.             horaireAller = (horaireAller === el ? null : el);
  186.         } else {
  187.             if (horaireRetour) {
  188.                 horaireRetour.style.background = '#eee';
  189.                 horaireRetour.style.color = 'black';
  190.             }
  191.             horaireRetour = (horaireRetour === el ? null : el);
  192.         }
  193.         if (horaireAller === el || horaireRetour === el) {
  194.             el.style.background = '#c55a11';
  195.             el.style.color = 'white';
  196.         }
  197.         updatePrixEtCode();
  198.     }
  199.  
  200.     function buildClasseAndPassagers() {
  201.         let html = '<h3 style="color:#0099cc;">Classe :</h3><div style="display:flex;justify-content:center;gap:10px;margin-bottom:20px;">';
  202.         html += '<button class="classe-btn" onclick="chooseClasse(1)" style="background:#eee;padding:10px;border:none;border-radius:5px;">1ère</button>';
  203.         html += '<button class="classe-btn" onclick="chooseClasse(2)" style="background:#eee;padding:10px;border:none;border-radius:5px;">2e</button>';
  204.         html += `</div><h3 style="color:#0099cc;">Passagers :</h3><div style="display:flex;justify-content:center;gap:10px;margin-bottom:20px;">`;
  205.         for (let i = 1; i <= 4; i++) {
  206.            html += `<button class="perso-btn" onclick="choosePassagers(${i})" style="background:#eee;padding:10px;border:none;border-radius:5px;">${i}</button>`;
  207.         }
  208.         html += `</div>
  209.            <div id="prix-affiche" style="font-weight:bold;text-align:center;margin-bottom:10px;"></div>
  210.            <div id="code-affiche" style="font-weight:bold;color:#c55a11;text-align:center;margin-bottom:15px;"></div>
  211.            <div style="text-align:center;"><button onclick="resetAll()" style="padding:10px 20px;background:#ccc;border:none;border-radius:8px;">Réinitialiser</button></div>`;
  212.         return html;
  213.     }
  214.  
  215.     function chooseClasse(c) {
  216.         classeChoisie = c;
  217.         document.querySelectorAll('.classe-btn').forEach(b => {
  218.             b.style.background = '#eee';
  219.             b.style.color = 'black';
  220.         });
  221.         document.querySelectorAll('.classe-btn')[c - 1].style.background = '#0099cc';
  222.         document.querySelectorAll('.classe-btn')[c - 1].style.color = 'white';
  223.         updatePrixEtCode();
  224.     }
  225.  
  226.     function choosePassagers(n) {
  227.         nbPassagers = n;
  228.         document.querySelectorAll('.perso-btn').forEach(b => {
  229.             b.style.background = '#eee';
  230.             b.style.color = 'black';
  231.         });
  232.         document.querySelectorAll('.perso-btn')[n - 1].style.background = '#0099cc';
  233.         updatePrixEtCode();
  234.     }
  235.  
  236.     // ---- Correction : identique à l'acheteur (jour inclus, même hash) ----
  237.     function updatePrixEtCode() {
  238.         if (!horaireAller || (trajetType === 'AR' && !horaireRetour) || !classeChoisie) return;
  239.  
  240.         // horaires triés
  241.         const horaires = [horaireAller.innerText.split('\n')[0]];
  242.         if (trajetType === 'AR') {
  243.             horaires.push(horaireRetour.innerText.split('\n')[0]);
  244.         }
  245.         horaires.sort();
  246.  
  247.         // calcul prix inchangé
  248.         const base = (classeChoisie === 1 ? prixBase1 : prixBase2);
  249.         let multDay = 1;
  250.         if (['Vendredi', 'Dimanche'].includes(dayDepart)) multDay = 1.2;
  251.         if (['Mardi', 'Mercredi'].includes(dayDepart)) multDay = 0.9;
  252.         const h = parseInt(horaireAller.innerText);
  253.         let multPeriod = 1;
  254.         if (h >= 6 && h <= 9) multPeriod = 1.1;
  255.         else if (h >= 13 && h <= 16) multPeriod = 0.95;
  256.         const prix = Math.round(base * multDay * multPeriod) * nbPassagers;
  257.         document.getElementById('prix-affiche').innerText = `Tarif : ${prix} €`;
  258.  
  259.         // génération du hash
  260.         const parts = [
  261.             trajetType === 'AS' ? 'ALLER SIMPLE' : 'ALLER-RETOUR',
  262.             dayDepart.toUpperCase(),
  263.             ...(trajetType === 'AR' ? [dayRetour.toUpperCase()] : []),
  264.             horaires.join('-'),
  265.             classeChoisie,
  266.             prix,
  267.             nbPassagers
  268.         ];
  269.         const str = parts.join('|');
  270.  
  271.         let hash = 0;
  272.         for (let i = 0; i < str.length; i++) {
  273.            hash = (hash * 31 + str.charCodeAt(i)) % 100000000;
  274.        }
  275.        document.getElementById('code-affiche').innerText = `Numéro de réservation : ${hash.toString(36).toUpperCase()}`;
  276.    }
  277. </script>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement