templates/Accueil/checkout_boite_vocale.html.twig line 1

Open in your IDE?
  1. <!DOCTYPE html>
  2. <html lang="fr">
  3. <head>
  4.   <meta charset="utf-8">
  5.   <meta name="viewport" content="width=device-width, initial-scale=1">
  6.   <title>Commander une Boîte Vocale — 5sur5Séjour</title>
  7.   <link rel="preconnect" href="https://fonts.googleapis.com">
  8.   <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  9.   <link href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap" rel="stylesheet">
  10.   <link href="{{ asset('Accueil/vendors/bootstrap/bootstrap.min.css') }}" rel="stylesheet">
  11.   <link href="{{ asset('Accueil/vendors/bootstrap-icons/font/bootstrap-icons.min.css') }}" rel="stylesheet">
  12.   
  13.   <style>
  14.     :root {
  15.       --orange5sur5: #FF6B35;
  16.       --orange-dark: #e65a2a;
  17.       --teal5sur5: #41A2AA;
  18.       --teal-dark: #369da6;
  19.       --ink: #0E1726;
  20.       --muted: #6c757d;
  21.       --soft: #f8f9fa;
  22.     }
  23.     
  24.     body {
  25.       font-family: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial;
  26.       background: linear-gradient(135deg, #fff5f2 0%, #e3f2f3 100%);
  27.       min-height: 100vh;
  28.       padding: 20px 0;
  29.     }
  30.     
  31.     .checkout-container {
  32.       max-width: 1200px;
  33.       margin: 0 auto;
  34.     }
  35.     
  36.     .checkout-header {
  37.       text-align: center;
  38.       margin-bottom: 40px;
  39.       color: var(--ink);
  40.     }
  41.     
  42.     .checkout-header .logo {
  43.       max-width: 180px;
  44.       margin-bottom: 20px;
  45.     }
  46.     
  47.     .checkout-header h1 {
  48.       font-size: 2rem;
  49.       font-weight: 800;
  50.       margin-bottom: 8px;
  51.       color: var(--ink);
  52.     }
  53.     
  54.     .checkout-header .subtitle {
  55.       color: var(--muted);
  56.       font-size: 1rem;
  57.     }
  58.     
  59.     .checkout-card {
  60.       background: #fff;
  61.       border-radius: 20px;
  62.       box-shadow: 0 8px 32px rgba(0,0,0,.08);
  63.       padding: 40px;
  64.       margin-bottom: 24px;
  65.     }
  66.     
  67.     .step-indicator {
  68.       display: flex;
  69.       justify-content: center;
  70.       align-items: center;
  71.       gap: 12px;
  72.       margin-bottom: 40px;
  73.       flex-wrap: wrap;
  74.     }
  75.     
  76.     .step {
  77.       display: flex;
  78.       align-items: center;
  79.       gap: 8px;
  80.       padding: 8px 16px;
  81.       border-radius: 999px;
  82.       background: #e9ecef;
  83.       color: #6c757d;
  84.       font-size: 0.9rem;
  85.       font-weight: 600;
  86.     }
  87.     
  88.     .step.active {
  89.       background: var(--orange5sur5);
  90.       color: #fff;
  91.     }
  92.     
  93.     .step.completed {
  94.       background: var(--teal5sur5);
  95.       color: #fff;
  96.     }
  97.     
  98.     .step-number {
  99.       display: inline-flex;
  100.       align-items: center;
  101.       justify-content: center;
  102.       width: 24px;
  103.       height: 24px;
  104.       border-radius: 50%;
  105.       background: rgba(255,255,255,.25);
  106.       font-size: 0.85rem;
  107.       font-weight: 700;
  108.     }
  109.     
  110.     .section-title {
  111.       font-size: 1.5rem;
  112.       font-weight: 700;
  113.       color: var(--ink);
  114.       margin-bottom: 24px;
  115.       display: flex;
  116.       align-items: center;
  117.       gap: 12px;
  118.     }
  119.     
  120.     .section-title i {
  121.       color: var(--orange5sur5);
  122.     }
  123.     
  124.     .form-label {
  125.       font-weight: 600;
  126.       color: var(--ink);
  127.       margin-bottom: 8px;
  128.     }
  129.     
  130.     .form-control, .form-select {
  131.       border: 2px solid #e9ecef;
  132.       border-radius: 10px;
  133.       padding: 12px 16px;
  134.       font-size: 0.95rem;
  135.       transition: all 0.2s;
  136.     }
  137.     
  138.     .form-control:focus, .form-select:focus {
  139.       border-color: var(--orange5sur5);
  140.       box-shadow: 0 0 0 0.2rem rgba(255,107,53,0.15);
  141.     }
  142.     
  143.     .payment-option {
  144.       border: 3px solid #e9ecef;
  145.       border-radius: 16px;
  146.       padding: 24px;
  147.       cursor: pointer;
  148.       transition: all 0.25s;
  149.       position: relative;
  150.       height: 100%;
  151.     }
  152.     
  153.     .payment-option:hover {
  154.       border-color: var(--orange5sur5);
  155.       transform: translateY(-2px);
  156.       box-shadow: 0 8px 20px rgba(255,107,53,0.15);
  157.     }
  158.     
  159.     .payment-option input[type="radio"] {
  160.       position: absolute;
  161.       top: 20px;
  162.       right: 20px;
  163.       width: 24px;
  164.       height: 24px;
  165.       cursor: pointer;
  166.     }
  167.     
  168.     .payment-option.selected {
  169.       border-color: var(--orange5sur5);
  170.       background: rgba(255,107,53,0.03);
  171.     }
  172.     
  173.     .payment-option .badge-recommended {
  174.       position: absolute;
  175.       top: -12px;
  176.       left: 20px;
  177.       background: linear-gradient(135deg, var(--orange5sur5) 0%, var(--orange-dark) 100%);
  178.       color: #fff;
  179.       padding: 4px 12px;
  180.       border-radius: 999px;
  181.       font-size: 0.75rem;
  182.       font-weight: 700;
  183.     }
  184.     
  185.     .payment-title {
  186.       font-size: 1.25rem;
  187.       font-weight: 700;
  188.       color: var(--ink);
  189.       margin-bottom: 8px;
  190.     }
  191.     
  192.     .payment-subtitle {
  193.       color: var(--muted);
  194.       font-size: 0.9rem;
  195.       margin-bottom: 16px;
  196.     }
  197.     
  198.     .payment-features {
  199.       list-style: none;
  200.       padding: 0;
  201.       margin: 0;
  202.     }
  203.     
  204.     .payment-features li {
  205.       display: flex;
  206.       align-items: start;
  207.       gap: 8px;
  208.       margin: 8px 0;
  209.       font-size: 0.9rem;
  210.       color: #495057;
  211.     }
  212.     
  213.     .payment-features i {
  214.       color: var(--teal5sur5);
  215.       margin-top: 2px;
  216.       font-size: 1rem;
  217.     }
  218.     
  219.     .summary-card {
  220.       background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  221.       border-radius: 16px;
  222.       padding: 24px;
  223.       position: sticky;
  224.       top: 20px;
  225.     }
  226.     
  227.     .summary-title {
  228.       font-size: 1.25rem;
  229.       font-weight: 700;
  230.       color: var(--ink);
  231.       margin-bottom: 20px;
  232.     }
  233.     
  234.     .summary-row {
  235.       display: flex;
  236.       justify-content: space-between;
  237.       align-items: center;
  238.       padding: 12px 0;
  239.       border-bottom: 1px solid #dee2e6;
  240.     }
  241.     
  242.     .summary-row:last-child {
  243.       border-bottom: none;
  244.       padding-top: 16px;
  245.       font-size: 1.25rem;
  246.       font-weight: 700;
  247.     }
  248.     
  249.     .summary-label {
  250.       color: #6c757d;
  251.       font-size: 0.95rem;
  252.     }
  253.     
  254.     .summary-value {
  255.       font-weight: 600;
  256.       color: var(--ink);
  257.     }
  258.     
  259.     .btn-primary-custom {
  260.       background: linear-gradient(135deg, var(--orange5sur5) 0%, var(--orange-dark) 100%);
  261.       border: none;
  262.       color: #fff;
  263.       padding: 16px 32px;
  264.       border-radius: 14px;
  265.       font-weight: 700;
  266.       font-size: 1.1rem;
  267.       width: 100%;
  268.       transition: all 0.25s;
  269.     }
  270.     
  271.     .btn-primary-custom:hover {
  272.       transform: translateY(-2px);
  273.       box-shadow: 0 12px 28px rgba(255,107,53,0.3);
  274.       color: #fff;
  275.     }
  276.     
  277.     .btn-primary-custom:disabled {
  278.       opacity: 0.6;
  279.       cursor: not-allowed;
  280.       transform: none;
  281.     }
  282.     
  283.     .btn-secondary-custom {
  284.       background: transparent;
  285.       border: 2px solid #dee2e6;
  286.       color: var(--muted);
  287.       padding: 14px 32px;
  288.       border-radius: 14px;
  289.       font-weight: 600;
  290.       transition: all 0.2s;
  291.     }
  292.     
  293.     .btn-secondary-custom:hover {
  294.       border-color: var(--orange5sur5);
  295.       color: var(--orange5sur5);
  296.     }
  297.     
  298.     .security-badge {
  299.       display: flex;
  300.       align-items: center;
  301.       justify-content: center;
  302.       gap: 8px;
  303.       padding: 12px;
  304.       background: rgba(65, 162, 170, 0.1);
  305.       border-radius: 10px;
  306.       margin-top: 20px;
  307.       font-size: 0.85rem;
  308.       color: var(--teal5sur5);
  309.       font-weight: 600;
  310.     }
  311.     
  312.     .form-check-input:checked {
  313.       background-color: var(--orange5sur5);
  314.       border-color: var(--orange5sur5);
  315.     }
  316.     
  317.     .info-box {
  318.       background: #e7f3ff;
  319.       border-left: 4px solid #0066cc;
  320.       padding: 16px;
  321.       border-radius: 8px;
  322.       margin: 20px 0;
  323.     }
  324.     
  325.     .info-box i {
  326.       color: #0066cc;
  327.       margin-right: 8px;
  328.     }
  329.     
  330.     .loader {
  331.       display: inline-block;
  332.       width: 20px;
  333.       height: 20px;
  334.       border: 3px solid rgba(255,255,255,.3);
  335.       border-radius: 50%;
  336.       border-top-color: #fff;
  337.       animation: spin 1s ease-in-out infinite;
  338.     }
  339.     
  340.     @keyframes spin {
  341.       to { transform: rotate(360deg); }
  342.     }
  343.     
  344.     @media (max-width: 768px) {
  345.       .checkout-card {
  346.         padding: 24px;
  347.       }
  348.       
  349.       .section-title {
  350.         font-size: 1.25rem;
  351.       }
  352.       
  353.       .summary-card {
  354.         position: static;
  355.         margin-top: 24px;
  356.       }
  357.     }
  358.     
  359.     /* Style du bouton personnalisé */
  360.     .btn-boite-vocale {
  361.       background: color-mix(in srgb, var(--bs-secondary), transparent 70%);
  362.       color: #41a2aa;
  363.       border: none;
  364.       padding: 16px 32px;
  365.       border-radius: 14px;
  366.       font-weight: 700;
  367.       font-size: 1.1rem;
  368.       width: 100%;
  369.       transition: all 0.25s;
  370.       display: inline-flex;
  371.       align-items: center;
  372.       justify-content: center;
  373.     }
  374.     
  375.     .btn-boite-vocale:hover {
  376.       background: color-mix(in srgb, var(--bs-secondary), transparent 50%);
  377.       color: #41a2aa;
  378.       transform: translateY(-2px);
  379.       box-shadow: 0 8px 20px rgba(65, 162, 170, 0.2);
  380.     }
  381.     
  382.     .btn-boite-vocale svg {
  383.       margin-left: 8px;
  384.     }
  385.   </style>
  386. </head>
  387. <body>
  388.   <div class="checkout-container">
  389.     <!-- Header -->
  390.     <div class="checkout-header">
  391.       <img src="{{ asset('/Accueil/imagesAccueil/logoHeader.svg') }}" alt="5sur5 Séjour" class="logo">
  392.       <h1><i class="bi bi-mic-fill"></i> Commander une Boîte Vocale</h1>
  393.       <p class="subtitle">Remplissez vos informations pour activer votre boîte vocale</p>
  394.     </div>
  395.     
  396.     <!-- Step Indicator -->
  397.     <div class="step-indicator">
  398.       <div class="step active" id="step1-indicator">
  399.         <span class="step-number">1</span>
  400.         <span>Informations</span>
  401.       </div>
  402.       <i class="bi bi-chevron-right text-muted"></i>
  403.       <div class="step" id="step2-indicator">
  404.         <span class="step-number">2</span>
  405.         <span>Paiement</span>
  406.       </div>
  407.       <i class="bi bi-chevron-right text-muted"></i>
  408.       <div class="step" id="step3-indicator">
  409.         <span class="step-number">3</span>
  410.         <span>Confirmation</span>
  411.       </div>
  412.     </div>
  413.     
  414.     <form id="checkoutForm" method="post" action="{{ path('checkout_process_boite_vocale') }}">
  415.       <div class="row g-4">
  416.         <!-- Main Content -->
  417.         <div class="col-lg-8">
  418.           <!-- Step 1: Account Information -->
  419.           <div class="checkout-card" id="step1">
  420.             <div class="section-title">
  421.               <i class="bi bi-building"></i>
  422.               Informations de la structure
  423.             </div>
  424.             
  425.             <div class="row g-3">
  426.               <div class="col-md-6">
  427.                 <label class="form-label">Nom de la structure *</label>
  428.                 <input type="text" class="form-control" name="company_name" required placeholder="Ex: Association des Voyageurs">
  429.               </div>
  430.               
  431.               <div class="col-md-6">
  432.                 <label class="form-label">Type de structure *</label>
  433.                 <select class="form-select" name="company_type" required>
  434.                   <option value="">Sélectionnez...</option>
  435.                   <option value="ecole_publique">École publique</option>
  436.                   <option value="ecole_privee">École privée</option>
  437.                   <option value="college">Collège</option>
  438.                   <option value="lycee">Lycée</option>
  439.                   <option value="association">Association</option>
  440.                   <option value="collectivite">Collectivité</option>
  441.                   <option value="centre_loisirs">Centre de loisirs</option>
  442.                   <option value="autre">Autre</option>
  443.                 </select>
  444.               </div>
  445.               
  446.               <div class="col-md-6">
  447.                 <label class="form-label">SIREN / SIRET</label>
  448.                 <input type="text" class="form-control" name="siren" placeholder="Ex: 123 456 789 00012">
  449.                 <small class="text-muted">Optionnel, pour la facturation</small>
  450.               </div>
  451.               
  452.               <div class="col-md-6">
  453.                 <label class="form-label">Téléphone *</label>
  454.                 <input type="tel" class="form-control" name="phone" required placeholder="06 12 34 56 78">
  455.               </div>
  456.               
  457.               <div class="col-12">
  458.                 <label class="form-label">Adresse *</label>
  459.                 <input type="text" class="form-control" name="address" required placeholder="12 rue de la République">
  460.               </div>
  461.               
  462.               <div class="col-md-4">
  463.                 <label class="form-label">Code postal *</label>
  464.                 <input type="text" class="form-control" name="postal_code" required placeholder="75001">
  465.               </div>
  466.               
  467.               <div class="col-md-8">
  468.                 <label class="form-label">Ville *</label>
  469.                 <input type="text" class="form-control" name="city" required placeholder="Paris">
  470.               </div>
  471.             </div>
  472.             
  473.             <hr class="my-4">
  474.             
  475.             <!-- Section Informations du séjour -->
  476.             <div class="section-title">
  477.               <i class="bi bi-calendar-event"></i>
  478.               Informations du séjour
  479.             </div>
  480.             
  481.             <div class="row g-3">
  482.               <div class="col-md-6">
  483.                 <label class="form-label">Date de début *</label>
  484.                 <input type="date" class="form-control" name="date_debut" required id="date_debut">
  485.               </div>
  486.               
  487.               <div class="col-md-6">
  488.                 <label class="form-label">Date de fin *</label>
  489.                 <input type="date" class="form-control" name="date_fin" required id="date_fin">
  490.               </div>
  491.               
  492.               <div class="col-md-6">
  493.                 <label class="form-label">Nombre de participants *</label>
  494.                 <input type="number" class="form-control" name="nombre_participants" required id="nombre_participants" min="1" placeholder="Nombre de participants">
  495.                 <small class="text-muted" id="participants_hint"></small>
  496.               </div>
  497.               
  498.               <div class="col-md-6">
  499.                 <label class="form-label">Thème du séjour *</label>
  500.                 <input type="text" class="form-control" name="theme_sejour" required placeholder="Ex: Classe verte, Camp d'été, Séjour ski">
  501.               </div>
  502.               
  503.               <div class="col-12">
  504.                 <label class="form-label">Adresse du séjour *</label>
  505.                 <input type="text" class="form-control" name="adresse_sejour" required placeholder="Adresse complète du lieu du séjour">
  506.               </div>
  507.             </div>
  508.             
  509.             <hr class="my-4">
  510.             
  511.             <div class="section-title">
  512.               <i class="bi bi-person-badge"></i>
  513.               Contact principal
  514.             </div>
  515.             
  516.             <div class="row g-3">
  517.               <div class="col-md-6">
  518.                 <label class="form-label">Prénom *</label>
  519.                 <input type="text" class="form-control" name="first_name" required placeholder="Jean">
  520.               </div>
  521.               
  522.               <div class="col-md-6">
  523.                 <label class="form-label">Nom *</label>
  524.                 <input type="text" class="form-control" name="last_name" required placeholder="Dupont">
  525.               </div>
  526.               
  527.               <div class="col-md-6">
  528.                 <label class="form-label">Email *</label>
  529.                 <input type="email" class="form-control" name="email" required placeholder="j.dupont@structure.fr">
  530.                 <small class="text-muted">Utilisé pour la confirmation</small>
  531.               </div>
  532.               
  533.               <div class="col-md-6">
  534.                 <label class="form-label">Fonction / Rôle *</label>
  535.                 <input type="text" class="form-control" name="role" required placeholder="Ex: Directeur, Animateur">
  536.               </div>
  537.             </div>
  538.             
  539.             <div class="info-box mt-4">
  540.               <i class="bi bi-shield-lock-fill"></i>
  541.               <strong>Sécurisé :</strong> Vos informations sont protégées et utilisées uniquement pour la commande.
  542.             </div>
  543.             
  544.             <div class="d-flex justify-content-end mt-4">
  545.               <button type="button" class="btn btn-primary-custom" id="nextStepBtn">
  546.                 Continuer vers le paiement <i class="bi bi-arrow-right ms-2"></i>
  547.               </button>
  548.             </div>
  549.           </div>
  550.           
  551.           <!-- Step 2: Payment Method -->
  552.           <div class="checkout-card" id="step2" style="display: none;">
  553.             <div class="section-title">
  554.               <i class="bi bi-credit-card-2-front"></i>
  555.               Choisissez votre mode de paiement
  556.             </div>
  557.             
  558.             <p class="text-muted mb-4">Sélectionnez le mode de règlement qui convient le mieux à votre structure</p>
  559.             
  560.             <div class="row g-4">
  561.               <!-- Option 1: Paiement en ligne -->
  562.               <div class="col-md-6">
  563.                 <div class="payment-option" data-payment="online">
  564.                   <span class="badge-recommended">Recommandé</span>
  565.                   <input type="radio" name="payment_method" value="online" id="payment-online" required>
  566.                   <div class="payment-title">Payer en ligne</div>
  567.                   <div class="payment-subtitle">CB / SEPA — activation immédiate</div>
  568.                   <ul class="payment-features">
  569.                     <li><i class="bi bi-check-circle-fill"></i> Paiement sécurisé Stripe</li>
  570.                     <li><i class="bi bi-check-circle-fill"></i> Facture automatique</li>
  571.                     <li><i class="bi bi-check-circle-fill"></i> Activation immédiate</li>
  572.                     <li><i class="bi bi-check-circle-fill"></i> Configuration incluse</li>
  573.                   </ul>
  574.                 </div>
  575.               </div>
  576.               
  577.               <!-- Option 2: Virement bancaire -->
  578.               <div class="col-md-6">
  579.                 <div class="payment-option" data-payment="bank">
  580.                   <input type="radio" name="payment_method" value="bank" id="payment-bank" required>
  581.                   <div class="payment-title">Virement bancaire</div>
  582.                   <div class="payment-subtitle">Paiement par virement — activation sous 48h</div>
  583.                   <ul class="payment-features">
  584.                     <li><i class="bi bi-check-circle-fill"></i> RIB fourni automatiquement</li>
  585.                     <li><i class="bi bi-check-circle-fill"></i> Facture proforma envoyée</li>
  586.                     <li><i class="bi bi-check-circle-fill"></i> Activation après réception</li>
  587.                   </ul>
  588.                 </div>
  589.               </div>
  590.             </div>
  591.             
  592.             <div class="mt-4">
  593.               <div class="form-check">
  594.                 <input class="form-check-input" type="checkbox" id="acceptTerms" required>
  595.                 <label class="form-check-label" for="acceptTerms">
  596.                   J'accepte les conditions générales d'utilisation et la politique de confidentialité *
  597.                 </label>
  598.               </div>
  599.             </div>
  600.             
  601.             <div id="submitWarning" class="alert alert-warning mt-3" style="display: none;">
  602.               <i class="bi bi-exclamation-triangle me-2"></i>
  603.               <strong>Pour continuer :</strong> Sélectionnez un mode de paiement et acceptez les conditions générales.
  604.             </div>
  605.             
  606.             <div class="d-flex justify-content-between mt-4">
  607.               <button type="button" class="btn btn-secondary-custom" id="prevStepBtn">
  608.                 <i class="bi bi-arrow-left me-2"></i>Retour
  609.               </button>
  610.               <button type="submit" class="btn btn-primary-custom" id="submitBtn" disabled>
  611.                 <span id="submitText">Finaliser la commande</span>
  612.                 <span id="submitLoader" class="loader" style="display: none;"></span>
  613.               </button>
  614.             </div>
  615.           </div>
  616.         </div>
  617.         
  618.         <!-- Sidebar: Summary -->
  619.         <div class="col-lg-4">
  620.           <div class="summary-card">
  621.             <div class="summary-title">
  622.               <i class="bi bi-receipt"></i> Récapitulatif
  623.             </div>
  624.             
  625.             <div class="summary-row">
  626.               <div>
  627.                 <div class="fw-bold" id="pack-name">Boîte Vocale</div>
  628.                 <small class="text-muted" id="pack-subtitle">Pack sélectionné</small>
  629.               </div>
  630.               <div class="summary-value" id="pack-price">- </div>
  631.             </div>
  632.             
  633.             <div class="summary-row">
  634.               <div class="summary-label">Configuration incluse</div>
  635.               <div class="summary-value text-success">Inclus</div>
  636.             </div>
  637.             
  638.             <div class="summary-row">
  639.               <div class="summary-label">Support</div>
  640.               <div class="summary-value text-success">Inclus</div>
  641.             </div>
  642.             
  643.             <div class="summary-row">
  644.               <div class="summary-label">Total HT</div>
  645.               <div class="summary-value text-success" id="total-price">-</div>
  646.             </div>
  647.             
  648.             <hr class="my-3">
  649.             
  650.             <div style="font-size: 0.85rem; color: var(--muted);">
  651.               <p class="mb-2"><i class="bi bi-check-circle text-success me-2"></i> Messages illimités</p>
  652.               <p class="mb-2"><i class="bi bi-check-circle text-success me-2"></i> Appels automatiques</p>
  653.               <p class="mb-2"><i class="bi bi-check-circle text-success me-2"></i> Configuration par notre équipe</p>
  654.               <p class="mb-2"><i class="bi bi-check-circle text-success me-2"></i> Support pendant le séjour</p>
  655.             </div>
  656.             
  657.             <div class="alert alert-info mt-3 small mb-0">
  658.               <i class="bi bi-info-circle me-2"></i>
  659.               La boîte vocale sera activée dès réception du paiement.
  660.             </div>
  661.           </div>
  662.         </div>
  663.       </div>
  664.       
  665.       <input type="hidden" name="pack_type" id="pack_type" value="{{ pack_type|default('35') }}">
  666.     </form>
  667.   </div>
  668.   
  669.   <script src="{{ asset('Accueil/vendors/bootstrap/bootstrap.bundle.min.js') }}"></script>
  670.   <script>
  671.     document.addEventListener('DOMContentLoaded', function() {
  672.       const form = document.getElementById('checkoutForm');
  673.       const step1 = document.getElementById('step1');
  674.       const step2 = document.getElementById('step2');
  675.       const step1Indicator = document.getElementById('step1-indicator');
  676.       const step2Indicator = document.getElementById('step2-indicator');
  677.       const nextStepBtn = document.getElementById('nextStepBtn');
  678.       const prevStepBtn = document.getElementById('prevStepBtn');
  679.       const submitBtn = document.getElementById('submitBtn');
  680.       const acceptTerms = document.getElementById('acceptTerms');
  681.       const nombreParticipants = document.getElementById('nombre_participants');
  682.       const participantsHint = document.getElementById('participants_hint');
  683.       const packType = document.getElementById('pack_type').value;
  684.       
  685.       // Configuration des packs selon le type
  686.       const packConfigs = {
  687.         '35': { name: 'Pack 35 enfants', price: 40, max: 35 },
  688.         '70': { name: 'Pack 70 enfants', price: 70, max: 70 },
  689.         'plus': { name: 'Grand séjour', price: 0, max: null }
  690.       };
  691.       
  692.       // Initialiser selon le pack sélectionné (depuis le serveur ou par défaut)
  693.       const currentPack = packConfigs[packType] || packConfigs['35'];
  694.       document.getElementById('pack-name').textContent = currentPack.name;
  695.       document.getElementById('pack-price').textContent = currentPack.price > 0 ? currentPack.price + ' € HT' : 'Sur devis';
  696.       document.getElementById('total-price').textContent = currentPack.price > 0 ? currentPack.price + ' € HT' : 'Sur devis';
  697.       
  698.       if (currentPack.max) {
  699.         nombreParticipants.setAttribute('max', currentPack.max);
  700.         nombreParticipants.setAttribute('placeholder', 'Jusqu\'à ' + currentPack.max + ' participants');
  701.         participantsHint.textContent = 'Maximum ' + currentPack.max + ' participants pour ce pack';
  702.       } else {
  703.         nombreParticipants.removeAttribute('max');
  704.         nombreParticipants.setAttribute('placeholder', 'Nombre de participants');
  705.         participantsHint.textContent = 'Plus de 70 participants - devis personnalisé';
  706.       }
  707.       
  708.       // Validation de la date de fin après la date de début
  709.       const dateDebut = document.getElementById('date_debut');
  710.       const dateFin = document.getElementById('date_fin');
  711.       
  712.       dateDebut.addEventListener('change', function() {
  713.         if (this.value) {
  714.           dateFin.setAttribute('min', this.value);
  715.         }
  716.       });
  717.       
  718.       // Payment option selection
  719.       const paymentOptions = document.querySelectorAll('.payment-option');
  720.       const paymentRadios = document.querySelectorAll('input[name="payment_method"]');
  721.       
  722.       paymentOptions.forEach(option => {
  723.         option.addEventListener('click', function() {
  724.           const radio = this.querySelector('input[type="radio"]');
  725.           radio.checked = true;
  726.           
  727.           paymentOptions.forEach(opt => opt.classList.remove('selected'));
  728.           this.classList.add('selected');
  729.           
  730.           updateSubmitButton();
  731.         });
  732.       });
  733.       
  734.       // Step navigation
  735.       nextStepBtn.addEventListener('click', function() {
  736.         if (!validateStep1()) {
  737.           return;
  738.         }
  739.         
  740.         step1.style.display = 'none';
  741.         step2.style.display = 'block';
  742.         
  743.         step1Indicator.classList.remove('active');
  744.         step1Indicator.classList.add('completed');
  745.         step2Indicator.classList.add('active');
  746.         
  747.         window.scrollTo({ top: 0, behavior: 'smooth' });
  748.       });
  749.       
  750.       prevStepBtn.addEventListener('click', function() {
  751.         step2.style.display = 'none';
  752.         step1.style.display = 'block';
  753.         step1Indicator.classList.add('active');
  754.         step1Indicator.classList.remove('completed');
  755.         step2Indicator.classList.remove('active');
  756.         window.scrollTo({ top: 0, behavior: 'smooth' });
  757.       });
  758.       
  759.       // Validate step 1
  760.       function validateStep1() {
  761.         const requiredFields = step1.querySelectorAll('[required]');
  762.         let isValid = true;
  763.         
  764.         requiredFields.forEach(field => {
  765.           if (!field.value.trim()) {
  766.             field.classList.add('is-invalid');
  767.             isValid = false;
  768.           } else {
  769.             field.classList.remove('is-invalid');
  770.           }
  771.         });
  772.         
  773.         // Validation spécifique pour le nombre de participants
  774.         if (currentPack.max && parseInt(nombreParticipants.value) > currentPack.max) {
  775.           nombreParticipants.classList.add('is-invalid');
  776.           alert('Le nombre de participants ne peut pas dépasser ' + currentPack.max + ' pour ce pack.');
  777.           isValid = false;
  778.         }
  779.         
  780.         // Validation des dates
  781.         if (dateDebut.value && dateFin.value && dateFin.value < dateDebut.value) {
  782.           dateFin.classList.add('is-invalid');
  783.           alert('La date de fin doit être postérieure à la date de début.');
  784.           isValid = false;
  785.         }
  786.         
  787.         if (!isValid) {
  788.           alert('Veuillez remplir tous les champs obligatoires (*) correctement');
  789.         }
  790.         
  791.         return isValid;
  792.       }
  793.       
  794.       // Update submit button state
  795.       function updateSubmitButton() {
  796.         const paymentSelected = document.querySelector('input[name="payment_method"]:checked');
  797.         const termsAccepted = acceptTerms.checked;
  798.         const submitWarning = document.getElementById('submitWarning');
  799.         
  800.         const canSubmit = paymentSelected && termsAccepted;
  801.         submitBtn.disabled = !canSubmit;
  802.         
  803.         if (!canSubmit && (step2.style.display !== 'none')) {
  804.           submitWarning.style.display = 'block';
  805.         } else {
  806.           submitWarning.style.display = 'none';
  807.         }
  808.       }
  809.       
  810.       acceptTerms.addEventListener('change', updateSubmitButton);
  811.       paymentRadios.forEach(radio => radio.addEventListener('change', updateSubmitButton));
  812.       
  813.       // Form submission
  814.       form.addEventListener('submit', function(e) {
  815.         e.preventDefault();
  816.         
  817.         const submitText = document.getElementById('submitText');
  818.         const submitLoader = document.getElementById('submitLoader');
  819.         
  820.         submitBtn.disabled = true;
  821.         submitText.style.display = 'none';
  822.         submitLoader.style.display = 'inline-block';
  823.         
  824.         // Récupérer les données du formulaire
  825.         const formData = new FormData(form);
  826.         
  827.         // Envoyer la requête AJAX
  828.         fetch(form.action, {
  829.           method: 'POST',
  830.           body: formData
  831.         })
  832.         .then(response => response.json())
  833.         .then(data => {
  834.           if (data.success) {
  835.             if (data.paymentType === 'stripe' && data.redirectUrl) {
  836.               // Redirection vers Payplug
  837.               window.location.href = data.redirectUrl;
  838.             } else if (data.paymentType === 'rib') {
  839.               // Afficher popup de confirmation pour RIB
  840.               showSuccessModal(data.message);
  841.               // Rediriger après 3 secondes
  842.               setTimeout(() => {
  843.                 if (data.redirectUrl) {
  844.                   window.location.href = data.redirectUrl;
  845.                 }
  846.               }, 3000);
  847.             } else if (data.redirectUrl) {
  848.               window.location.href = data.redirectUrl;
  849.             }
  850.           } else {
  851.             alert(data.error || 'Une erreur est survenue. Veuillez réessayer.');
  852.             submitBtn.disabled = false;
  853.             submitText.style.display = 'inline';
  854.             submitLoader.style.display = 'none';
  855.           }
  856.         })
  857.         .catch(error => {
  858.           console.error('Erreur:', error);
  859.           alert('Une erreur est survenue lors de l\'envoi de votre demande. Veuillez réessayer.');
  860.           submitBtn.disabled = false;
  861.           submitText.style.display = 'inline';
  862.           submitLoader.style.display = 'none';
  863.         });
  864.       });
  865.       
  866.       // Fonction pour afficher le modal de succès
  867.       function showSuccessModal(message) {
  868.         // Créer le modal si il n'existe pas
  869.         let modal = document.getElementById('successModal');
  870.         if (!modal) {
  871.           modal = document.createElement('div');
  872.           modal.id = 'successModal';
  873.           modal.className = 'modal fade';
  874.           modal.innerHTML = `
  875.             <div class="modal-dialog modal-dialog-centered">
  876.               <div class="modal-content">
  877.                 <div class="modal-body text-center p-5">
  878.                   <div class="mb-3">
  879.                     <i class="bi bi-check-circle-fill text-success" style="font-size: 4rem;"></i>
  880.                   </div>
  881.                   <h4 class="mb-3">Commande prise en compte</h4>
  882.                   <p class="mb-4">${message}</p>
  883.                   <button type="button" class="btn btn-primary" data-bs-dismiss="modal">Fermer</button>
  884.                 </div>
  885.               </div>
  886.             </div>
  887.           `;
  888.           document.body.appendChild(modal);
  889.         }
  890.         
  891.         // Mettre à jour le message
  892.         const modalBody = modal.querySelector('.modal-body p');
  893.         if (modalBody) {
  894.           modalBody.textContent = message;
  895.         }
  896.         
  897.         // Afficher le modal
  898.         const bsModal = new bootstrap.Modal(modal);
  899.         bsModal.show();
  900.       }
  901.     });
  902.   </script>
  903. </body>
  904. </html>