Checkout Steps Finaliser Commande Tailwind CSS

Extraits & Composants HTML 10/04/2026 16:00:00 angularforall.com
Tailwind Css Checkout Stepper E Commerce Formulaire Multi Etapes Template Html Css Js

Tunnel de commande multi-étapes Tailwind CSS : stepper animé, progress bar, validation champs en temps réel et design moderne pour e-commerce.

<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8" />
  <meta name="copyright" content="AngularForAll" />
  <meta name="author" content="AngularForAll" />
  <meta name="robots" content="noindex, nofollow" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="Cache-Control" content="public, max-age=604800" />
  <title>Snippets Checkout Step Tailwind 2026 05020023 | AngularForAll</title>
<!-- Tailwind CSS CDN -->
  <script src="https://cdn.tailwindcss.com"></script>
  
  <!-- Configuration Tailwind -->
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: {
            brand: {
              50: '#f0f4ff',
              100: '#dbe4ff',
              200: '#bac8ff',
              300: '#91a7ff',
              400: '#748ffc',
              500: '#5c7cfa',
              600: '#4c6ef5',
              700: '#4263eb',
              800: '#3b5bdb',
              900: '#364fc7',
            },
            accent: {
              50: '#fff0f6',
              100: '#ffdeeb',
              200: '#fcc2d7',
              300: '#faa2c1',
              400: '#f783ac',
              500: '#f06595',
              600: '#e64980',
              700: '#d6336c',
            },
            success: {
              400: '#69db7c',
              500: '#51cf66',
              600: '#40c057',
            },
            surface: '#fafbfc',
            card: '#ffffff',
          },
          fontFamily: {
            sans: ['Inter', 'system-ui', '-apple-system', 'sans-serif'],
            display: ['Plus Jakarta Sans', 'Inter', 'sans-serif'],
          },
          borderRadius: {
            '2.5xl': '1.25rem',
            '3.5xl': '1.75rem',
          },
          boxShadow: {
            'soft': '0 2px 15px rgba(0, 0, 0, 0.03), 0 8px 30px rgba(0, 0, 0, 0.04)',
            'medium': '0 4px 20px rgba(0, 0, 0, 0.05), 0 12px 40px rgba(0, 0, 0, 0.06)',
            'glow': '0 0 0 6px rgba(92, 124, 250, 0.12), 0 4px 16px rgba(92, 124, 250, 0.15)',
            'success-glow': '0 0 0 6px rgba(81, 207, 102, 0.1), 0 4px 12px rgba(81, 207, 102, 0.15)',
          },
          animation: {
            'slide-in': 'slideIn 0.4s cubic-bezier(0.16, 1, 0.3, 1)',
            'pulse-soft': 'pulseSoft 2s ease-in-out infinite',
            'bounce-in': 'bounceIn 0.5s cubic-bezier(0.16, 1, 0.3, 1)',
            'checkmark': 'checkmark 0.3s ease-out forwards',
          },
          keyframes: {
            slideIn: {
              '0%': { opacity: '0', transform: 'translateY(8px)' },
              '100%': { opacity: '1', transform: 'translateY(0)' },
            },
            pulseSoft: {
              '0%, 100%': { boxShadow: '0 0 0 0 rgba(92, 124, 250, 0.2)' },
              '50%': { boxShadow: '0 0 0 10px rgba(92, 124, 250, 0)' },
            },
            bounceIn: {
              '0%': { opacity: '0', transform: 'scale(0.9)' },
              '50%': { transform: 'scale(1.02)' },
              '100%': { opacity: '1', transform: 'scale(1)' },
            },
            checkmark: {
              '0%': { transform: 'scale(0) rotate(-45deg)', opacity: '0' },
              '50%': { transform: 'scale(1.2) rotate(0deg)', opacity: '1' },
              '100%': { transform: 'scale(1) rotate(0deg)', opacity: '1' },
            },
          },
        },
      },
    };
  </script>
  
  <!-- Google Fonts -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
  
  <!-- Font Awesome 6 -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
  
  <style>
    body {
      background-color: #f5f6fa;
      background-image: 
        radial-gradient(circle at 20% 10%, rgba(92, 124, 250, 0.03) 0%, transparent 50%),
        radial-gradient(circle at 80% 90%, rgba(240, 101, 149, 0.03) 0%, transparent 50%);
      min-height: 100vh;
    }
    
    /* Ligne de progression entre les étapes */
    .steps-connector {
      position: absolute;
      top: 50%;
      left: 0;
      right: 0;
      height: 3px;
      transform: translateY(-50%);
      z-index: 0;
    }
    
    /* Animation de transition du contenu */
    .step-content-enter {
      animation: slideIn 0.35s cubic-bezier(0.16, 1, 0.3, 1) forwards;
    }
    
    /* Effet de carte de crédit */
    .credit-card-preview {
      background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
      border-radius: 16px;
      padding: 1.5rem;
      color: white;
      position: relative;
      overflow: hidden;
    }
    
    .credit-card-preview::before {
      content: '';
      position: absolute;
      top: -50%;
      right: -30%;
      width: 200px;
      height: 200px;
      background: radial-gradient(circle, rgba(255,255,255,0.05) 0%, transparent 70%);
      border-radius: 50%;
    }
    
    /* Checkbox et radio personnalisés */
    .custom-radio:checked + label {
      border-color: #5c7cfa;
      background-color: #f0f4ff;
    }
    
    /* Scrollbar personnalisée */
    ::-webkit-scrollbar {
      width: 5px;
    }
    ::-webkit-scrollbar-track {
      background: transparent;
    }
    ::-webkit-scrollbar-thumb {
      background: #d1d5db;
      border-radius: 3px;
    }
  </style>
</head>
<body class="font-sans antialiased text-gray-800">

  <!-- Conteneur principal -->
  <div class="min-h-screen flex items-center justify-center p-4 sm:p-6 lg:p-8">
    <div class="w-full max-w-2xl">
      
      <!-- ========== CARTE PRINCIPALE ========== -->
      <div class="bg-white rounded-3.5xl shadow-medium overflow-hidden">
        
        <!-- En-tête -->
        <div class="relative bg-gradient-to-r from-brand-600 to-brand-800 px-6 sm:px-8 py-6 sm:py-8">
          <div class="relative z-10">
            <div class="flex items-center gap-3 mb-2">
              <div class="w-10 h-10 bg-white/20 backdrop-blur-sm rounded-xl flex items-center justify-center">
                <i class="fa-solid fa-bag-shopping text-white"></i>
              </div>
              <div>
                <h2 class="text-white font-display font-bold text-xl sm:text-2xl">Finaliser la commande</h2>
                <p class="text-white/60 text-sm">Complétez les étapes ci-dessous</p>
              </div>
            </div>
          </div>
          <!-- Cercle décoratif -->
          <div class="absolute top-0 right-0 w-40 h-40 bg-white/5 rounded-full -translate-y-1/2 translate-x-1/4"></div>
          <div class="absolute bottom-0 left-1/2 w-60 h-60 bg-white/3 rounded-full translate-y-1/2 -translate-x-1/2"></div>
        </div>
        
        <!-- Corps -->
        <div class="px-6 sm:px-8 py-6 sm:py-8">
          
          <!-- ========== INDICATEUR D'ÉTAPES ========== -->
          <div class="relative mb-8">
            <!-- Étapes -->
            <div class="flex items-center justify-between relative z-10" id="stepsContainer">
              <!-- Étape 1 : Panier -->
              <div class="step-item flex flex-col items-center cursor-pointer group" data-step="1" onclick="navigateToStep(1)">
                <div class="step-circle w-12 h-12 sm:w-14 sm:h-14 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300 relative
                           bg-brand-600 text-white shadow-glow animate-pulse-soft" id="circle1">
                  <span class="step-number">1</span>
                  <span class="step-check hidden"><i class="fa-solid fa-check"></i></span>
                </div>
                <span class="step-label mt-2 text-xs sm:text-sm font-semibold text-brand-600" id="label1">
                  <i class="fa-solid fa-cart-shopping mr-1"></i>Panier
                </span>
                <span class="text-[10px] text-gray-400 mt-0.5">Vérifier</span>
              </div>
              
              <!-- Étape 2 : Livraison -->
              <div class="step-item flex flex-col items-center cursor-pointer group" data-step="2" onclick="navigateToStep(2)">
                <div class="step-circle w-12 h-12 sm:w-14 sm:h-14 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300 relative
                           bg-gray-200 text-gray-500" id="circle2">
                  <span class="step-number">2</span>
                  <span class="step-check hidden"><i class="fa-solid fa-check"></i></span>
                </div>
                <span class="step-label mt-2 text-xs sm:text-sm font-semibold text-gray-500" id="label2">
                  <i class="fa-solid fa-truck mr-1"></i>Livraison
                </span>
                <span class="text-[10px] text-gray-400 mt-0.5">Adresse</span>
              </div>
              
              <!-- Étape 3 : Paiement -->
              <div class="step-item flex flex-col items-center cursor-pointer group" data-step="3" onclick="navigateToStep(3)">
                <div class="step-circle w-12 h-12 sm:w-14 sm:h-14 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300 relative
                           bg-gray-200 text-gray-500" id="circle3">
                  <span class="step-number">3</span>
                  <span class="step-check hidden"><i class="fa-solid fa-check"></i></span>
                </div>
                <span class="step-label mt-2 text-xs sm:text-sm font-semibold text-gray-500" id="label3">
                  <i class="fa-solid fa-credit-card mr-1"></i>Paiement
                </span>
                <span class="text-[10px] text-gray-400 mt-0.5">Finaliser</span>
              </div>
            </div>
            
            <!-- Ligne de progression -->
            <div class="steps-connector bg-gray-200 rounded-full mx-8 sm:mx-12" style="top: 28px; z-index: 0;">
              <div class="h-full bg-gradient-to-r from-brand-500 to-brand-600 rounded-full transition-all duration-500 ease-out" 
                   id="progressLine" 
                   style="width: 0%;"></div>
            </div>
          </div>
          
          <!-- ========== CONTENU DYNAMIQUE ========== -->
          <div id="stepContent" class="min-h-[280px] step-content-enter">
            <!-- Rempli dynamiquement -->
          </div>
          
          <!-- ========== BOUTONS DE NAVIGATION ========== -->
          <div class="flex items-center justify-between mt-6 pt-4 border-t border-gray-100" id="navButtons">
            <button 
              id="btnPrev"
              onclick="previousStep()"
              disabled
              class="flex items-center gap-2 px-4 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200
                     bg-gray-100 text-gray-400 cursor-not-allowed border border-gray-200"
            >
              <i class="fa-solid fa-arrow-left text-xs"></i>
              Précédent
            </button>
            
            <span class="text-xs text-gray-400 font-medium" id="stepCounter">Étape 1/3</span>
            
            <button 
              id="btnNext"
              onclick="nextStep()"
              class="flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200
                     bg-brand-600 text-white shadow-lg shadow-brand-200 hover:bg-brand-700 hover:shadow-brand-300 
                     active:scale-95"
            >
              Suivant
              <i class="fa-solid fa-arrow-right text-xs"></i>
            </button>
          </div>
          
        </div>
      </div>
      
      <!-- Indicateur de sécurité -->
      <div class="text-center mt-4">
        <span class="inline-flex items-center gap-2 text-xs text-gray-400 bg-white/60 backdrop-blur-sm px-4 py-2 rounded-full shadow-sm">
          <i class="fa-solid fa-lock text-success-500"></i>
          Paiement 100% sécurisé • Données cryptées SSL
        </span>
      </div>
    </div>
  </div>
  
  <!-- Script CheckoutSteps -->
  <script>
    (function() {
      // ============ ÉTAT ============
      const TOTAL_STEPS = 3;
      let currentStep = 1;
      const completedSteps = new Set();
      
      // ============ ÉLÉMENTS DOM ============
      const progressLine = document.getElementById('progressLine');
      const stepContent = document.getElementById('stepContent');
      const btnPrev = document.getElementById('btnPrev');
      const btnNext = document.getElementById('btnNext');
      const stepCounter = document.getElementById('stepCounter');
      
      // ============ CONTENUS DES ÉTAPES ============
      const contents = {
        1: `
          <div class="step-content-enter">
            <div class="flex items-center gap-3 mb-5">
              <div class="w-10 h-10 bg-brand-50 rounded-xl flex items-center justify-center">
                <i class="fa-solid fa-cart-shopping text-brand-600"></i>
              </div>
              <div>
                <h3 class="font-display font-bold text-lg text-gray-800">Votre Panier</h3>
                <p class="text-sm text-gray-400">Vérifiez vos articles avant de continuer</p>
              </div>
            </div>
            
            <!-- Article 1 -->
            <div class="flex items-center gap-4 p-4 bg-gray-50 rounded-2xl mb-3 hover:bg-gray-100 transition-colors group">
              <div class="w-16 h-16 bg-white rounded-xl flex items-center justify-center shadow-sm flex-shrink-0">
                <i class="fa-solid fa-shoe-prints text-2xl text-gray-300"></i>
              </div>
              <div class="flex-1 min-w-0">
                <p class="font-semibold text-gray-800 truncate">Chaussures Air Max Neon</p>
                <p class="text-xs text-gray-400">Taille 42 • Noir/Blanc</p>
              </div>
              <div class="text-right flex-shrink-0">
                <p class="font-bold text-gray-800">129,99 €</p>
                <button class="text-xs text-red-400 hover:text-red-600 transition-colors">
                  <i class="fa-solid fa-trash-can"></i>
                </button>
              </div>
            </div>
            
            <!-- Article 2 -->
            <div class="flex items-center gap-4 p-4 bg-gray-50 rounded-2xl mb-4 hover:bg-gray-100 transition-colors group">
              <div class="w-16 h-16 bg-white rounded-xl flex items-center justify-center shadow-sm flex-shrink-0">
                <i class="fa-solid fa-clock text-2xl text-gray-300"></i>
              </div>
              <div class="flex-1 min-w-0">
                <p class="font-semibold text-gray-800 truncate">Montre FitPro X200</p>
                <p class="text-xs text-gray-400">Bracelet silicone • Noir</p>
              </div>
              <div class="text-right flex-shrink-0">
                <p class="font-bold text-gray-800">249,99 €</p>
                <button class="text-xs text-red-400 hover:text-red-600 transition-colors">
                  <i class="fa-solid fa-trash-can"></i>
                </button>
              </div>
            </div>
            
            <!-- Total -->
            <div class="flex justify-between items-center p-4 bg-brand-50 rounded-2xl">
              <span class="text-sm text-gray-600">Total (2 articles)</span>
              <span class="font-display font-bold text-xl text-brand-700">379,98 €</span>
            </div>
          </div>
        `,
        
        2: `
          <div class="step-content-enter">
            <div class="flex items-center gap-3 mb-5">
              <div class="w-10 h-10 bg-brand-50 rounded-xl flex items-center justify-center">
                <i class="fa-solid fa-truck text-brand-600"></i>
              </div>
              <div>
                <h3 class="font-display font-bold text-lg text-gray-800">Adresse de livraison</h3>
                <p class="text-sm text-gray-400">Où souhaitez-vous recevoir votre commande ?</p>
              </div>
            </div>
            
            <div class="grid grid-cols-1 sm:grid-cols-2 gap-3 mb-4">
              <div>
                <label class="block text-xs font-semibold text-gray-500 mb-1.5 uppercase tracking-wide">Prénom</label>
                <input type="text" value="Thomas" class="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-sm focus:outline-none focus:border-brand-400 focus:ring-2 focus:ring-brand-100 transition-all">
              </div>
              <div>
                <label class="block text-xs font-semibold text-gray-500 mb-1.5 uppercase tracking-wide">Nom</label>
                <input type="text" value="Martin" class="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-sm focus:outline-none focus:border-brand-400 focus:ring-2 focus:ring-brand-100 transition-all">
              </div>
              <div class="sm:col-span-2">
                <label class="block text-xs font-semibold text-gray-500 mb-1.5 uppercase tracking-wide">Adresse</label>
                <input type="text" value="15 Avenue des Champs-Élysées" class="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-sm focus:outline-none focus:border-brand-400 focus:ring-2 focus:ring-brand-100 transition-all">
              </div>
              <div>
                <label class="block text-xs font-semibold text-gray-500 mb-1.5 uppercase tracking-wide">Code Postal</label>
                <input type="text" value="75008" class="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-sm focus:outline-none focus:border-brand-400 focus:ring-2 focus:ring-brand-100 transition-all">
              </div>
              <div>
                <label class="block text-xs font-semibold text-gray-500 mb-1.5 uppercase tracking-wide">Ville</label>
                <input type="text" value="Paris" class="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-sm focus:outline-none focus:border-brand-400 focus:ring-2 focus:ring-brand-100 transition-all">
              </div>
            </div>
            
            <div class="space-y-2">
              <label class="flex items-center gap-3 p-3.5 bg-green-50 border-2 border-green-200 rounded-2xl cursor-pointer transition-all hover:shadow-sm">
                <input type="radio" name="delivery" checked class="w-4 h-4 text-brand-600">
                <div>
                  <span class="font-semibold text-sm">Standard</span>
                  <span class="text-xs text-gray-400 ml-2">3-5 jours ouvrés</span>
                  <p class="text-xs text-green-600 font-medium">Gratuit</p>
                </div>
              </label>
              <label class="flex items-center gap-3 p-3.5 bg-white border-2 border-gray-200 rounded-2xl cursor-pointer transition-all hover:border-gray-300 hover:shadow-sm">
                <input type="radio" name="delivery" class="w-4 h-4 text-brand-600">
                <div>
                  <span class="font-semibold text-sm">Express</span>
                  <span class="text-xs text-gray-400 ml-2">1-2 jours ouvrés</span>
                  <p class="text-xs text-gray-500">+ 9,99 €</p>
                </div>
              </label>
            </div>
          </div>
        `,
        
        3: `
          <div class="step-content-enter">
            <div class="flex items-center gap-3 mb-5">
              <div class="w-10 h-10 bg-brand-50 rounded-xl flex items-center justify-center">
                <i class="fa-solid fa-credit-card text-brand-600"></i>
              </div>
              <div>
                <h3 class="font-display font-bold text-lg text-gray-800">Paiement sécurisé</h3>
                <p class="text-sm text-gray-400">Choisissez votre méthode de paiement</p>
              </div>
            </div>
            
            <!-- Méthodes de paiement -->
            <div class="space-y-2 mb-5">
              <label class="flex items-center gap-3 p-3.5 bg-brand-50 border-2 border-brand-300 rounded-2xl cursor-pointer transition-all hover:shadow-sm">
                <input type="radio" name="payment" checked class="w-4 h-4 text-brand-600">
                <i class="fa-regular fa-credit-card text-brand-600 text-lg"></i>
                <span class="font-semibold text-sm">Carte Bancaire</span>
                <span class="text-xs text-gray-400 ml-auto">Visa, Mastercard</span>
              </label>
              <label class="flex items-center gap-3 p-3.5 bg-white border-2 border-gray-200 rounded-2xl cursor-pointer transition-all hover:border-gray-300 hover:shadow-sm">
                <input type="radio" name="payment" class="w-4 h-4 text-brand-600">
                <i class="fa-brands fa-paypal text-blue-600 text-lg"></i>
                <span class="font-semibold text-sm">PayPal</span>
                <span class="text-xs text-gray-400 ml-auto">Connexion sécurisée</span>
              </label>
              <label class="flex items-center gap-3 p-3.5 bg-white border-2 border-gray-200 rounded-2xl cursor-pointer transition-all hover:border-gray-300 hover:shadow-sm">
                <input type="radio" name="payment" class="w-4 h-4 text-brand-600">
                <i class="fa-brands fa-apple text-gray-800 text-lg"></i>
                <span class="font-semibold text-sm">Apple Pay</span>
              </label>
            </div>
            
            <!-- Résumé -->
            <div class="bg-gray-50 rounded-2xl p-4">
              <div class="flex justify-between text-sm py-1.5 text-gray-500">
                <span>Sous-total</span><span>379,98 €</span>
              </div>
              <div class="flex justify-between text-sm py-1.5 text-gray-500">
                <span>Livraison</span><span class="text-green-600 font-medium">Gratuite</span>
              </div>
              <div class="flex justify-between text-sm py-1.5 text-gray-500 border-b border-gray-200 pb-2">
                <span>TVA (20%)</span><span>63,33 €</span>
              </div>
              <div class="flex justify-between font-display font-bold text-lg pt-2 text-gray-800">
                <span>Total</span><span class="text-brand-700">379,98 €</span>
              </div>
            </div>
          </div>
        `
      };
      
      // ============ FONCTIONS ============
      function updateUI() {
        // Mise à jour des cercles d'étapes
        for (let i = 1; i <= TOTAL_STEPS; i++) {
          const circle = document.getElementById('circle' + i);
          const label = document.getElementById('label' + i);
          
          circle.classList.remove('bg-brand-600', 'text-white', 'shadow-glow', 'animate-pulse-soft',
                                'bg-success-500', 'text-white', 'shadow-success-glow',
                                'bg-gray-200', 'text-gray-500');
          label.classList.remove('text-brand-600', 'text-success-500', 'text-gray-500');
          
          const numberSpan = circle.querySelector('.step-number');
          const checkSpan = circle.querySelector('.step-check');
          
          if (completedSteps.has(i)) {
            circle.classList.add('bg-success-500', 'text-white', 'shadow-success-glow');
            label.classList.add('text-success-500');
            if (numberSpan) numberSpan.classList.add('hidden');
            if (checkSpan) checkSpan.classList.remove('hidden');
          } else if (i === currentStep) {
            circle.classList.add('bg-brand-600', 'text-white', 'shadow-glow', 'animate-pulse-soft');
            label.classList.add('text-brand-600');
            if (numberSpan) numberSpan.classList.remove('hidden');
            if (checkSpan) checkSpan.classList.add('hidden');
          } else {
            circle.classList.add('bg-gray-200', 'text-gray-500');
            label.classList.add('text-gray-500');
            if (numberSpan) numberSpan.classList.remove('hidden');
            if (checkSpan) checkSpan.classList.add('hidden');
          }
        }
        
        // Barre de progression
        const progressPercent = currentStep === 1 ? 0 : currentStep === 2 ? 50 : 100;
        progressLine.style.width = progressPercent + '%';
        
        // Contenu
        stepContent.innerHTML = contents[currentStep];
        
        // Boutons
        if (currentStep === 1) {
          btnPrev.disabled = true;
          btnPrev.className = 'flex items-center gap-2 px-4 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200 bg-gray-100 text-gray-400 cursor-not-allowed border border-gray-200';
        } else {
          btnPrev.disabled = false;
          btnPrev.className = 'flex items-center gap-2 px-4 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200 bg-white text-gray-600 border border-gray-300 hover:bg-gray-50 hover:border-gray-400 active:scale-95';
        }
        
        if (currentStep === TOTAL_STEPS) {
          btnNext.innerHTML = '<i class="fa-solid fa-check mr-1"></i> Confirmer';
          btnNext.className = 'flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200 bg-success-500 text-white shadow-lg shadow-success-200 hover:bg-success-600 active:scale-95';
          btnNext.onclick = confirmOrder;
        } else {
          btnNext.innerHTML = 'Suivant <i class="fa-solid fa-arrow-right text-xs ml-1"></i>';
          btnNext.className = 'flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200 bg-brand-600 text-white shadow-lg shadow-brand-200 hover:bg-brand-700 hover:shadow-brand-300 active:scale-95';
          btnNext.onclick = nextStep;
        }
        
        stepCounter.textContent = `Étape ${currentStep}/${TOTAL_STEPS}`;
      }
      
      function navigateToStep(step) {
        if (step < currentStep || completedSteps.has(step - 1)) {
          currentStep = step;
          updateUI();
        }
      }
      
      function nextStep() {
        if (currentStep < TOTAL_STEPS) {
          completedSteps.add(currentStep);
          currentStep++;
          updateUI();
        }
      }
      
      function previousStep() {
        if (currentStep > 1) {
          currentStep--;
          updateUI();
        }
      }
      
      function confirmOrder() {
        completedSteps.add(3);
        updateUI();
        
        // Animation de confirmation
        const btnNext = document.getElementById('btnNext');
        btnNext.innerHTML = '<i class="fa-solid fa-spinner fa-spin mr-1"></i> Traitement...';
        btnNext.disabled = true;
        btnNext.className = 'flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200 bg-success-500 text-white opacity-75 cursor-wait';
        
        setTimeout(() => {
          stepContent.innerHTML = `
            <div class="step-content-enter text-center py-6">
              <div class="inline-flex items-center justify-center w-20 h-20 bg-success-50 rounded-full mb-4">
                <i class="fa-solid fa-check text-3xl text-success-500 animate-bounce-in"></i>
              </div>
              <h3 class="font-display font-bold text-xl text-gray-800 mb-2">Commande confirmée !</h3>
              <p class="text-gray-400 mb-1">Votre commande <span class="font-semibold text-gray-600">#CMD-2026-0421</span> a bien été enregistrée.</p>
              <p class="text-sm text-gray-400 mb-5">Un email a été envoyé à thomas.martin@email.fr</p>
              <button onclick="location.reload()" class="inline-flex items-center gap-2 px-5 py-2.5 bg-brand-600 text-white rounded-xl text-sm font-semibold hover:bg-brand-700 transition-colors shadow-lg shadow-brand-200 active:scale-95">
                <i class="fa-solid fa-arrow-rotate-right text-xs"></i>
                Nouvelle commande
              </button>
            </div>
          `;
          
          // Cacher les boutons
          document.getElementById('navButtons').style.display = 'none';
          
          // Mettre toutes les étapes en complétées
          for (let i = 1; i <= TOTAL_STEPS; i++) {
            completedSteps.add(i);
          }
          progressLine.style.width = '100%';
          updateUI();
        }, 1800);
      }
      
      // ============ EXPOSER LES FONCTIONS ============
      window.navigateToStep = navigateToStep;
      window.nextStep = nextStep;
      window.previousStep = previousStep;
      window.confirmOrder = confirmOrder;
      
      // ============ INITIALISATION ============
      updateUI();
      console.log('✨ CheckoutSteps • Theme Tailwind • Prêt');
    })();
  </script>
</body>
</html>

Télécharger le fichier source

Partager