Template Loading Product - Bootstrap 4

🏷️ Extraits de code HTML 📅 17/04/2026 👤 Mezgani said
Bootstrap Bootstrap4 Loading Product Html Css

Template de chargement de produit Bootstrap 4 avec design élégant et moderne.

<!doctype html>
<html lang="fr">
  <head>
  <meta charset="UTF-8" />
  <meta name="copyright" content="MEZGANI Said" />
  <meta name="author" content="AngularForAll" />
  <meta name="robots" content="noindex, nofollow" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Loading Product Bootstrap 4 | AngularForAll</title>
  <!-- Bootstrap 5 + Icons -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
  <!-- Google Fonts -->
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      font-family: 'Inter', sans-serif;
      background: #f8fafc;
      min-height: 100vh;
    }

    /* Navbar */
    .navbar {
      background: white !important;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.03);
      padding: 1rem 0;
    }

    .navbar-brand {
      font-weight: 700;
      font-size: 1.5rem;
      color: #1e293b !important;
    }

    .navbar-brand span {
      color: #3b82f6;
    }

    /* Header de page */
    .page-header {
      background: white;
      border-bottom: 1px solid #e2e8f0;
      padding: 1.5rem 0;
      margin-bottom: 2rem;
    }

    .page-title {
      font-weight: 700;
      font-size: 1.8rem;
      color: #0f172a;
      margin-bottom: 0.25rem;
    }

    .breadcrumb {
      margin-bottom: 0;
    }

    .breadcrumb-item a {
      color: #64748b;
      text-decoration: none;
    }

    .result-count {
      color: #64748b;
      font-size: 0.9rem;
    }

    /* Filtres sidebar */
    .filter-section {
      background: white;
      border-radius: 16px;
      padding: 1.5rem;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.02);
      border: 1px solid #e2e8f0;
      margin-bottom: 1.5rem;
    }

    .filter-title {
      font-weight: 700;
      font-size: 1rem;
      margin-bottom: 1rem;
      color: #1e293b;
    }

    /* Squelettes de chargement (Skeleton Loaders) */
    .skeleton {
      background: linear-gradient(90deg, #f1f5f9 25%, #e2e8f0 50%, #f1f5f9 75%);
      background-size: 200% 100%;
      animation: skeleton-loading 1.5s ease-in-out infinite;
      border-radius: 8px;
    }

    @keyframes skeleton-loading {
      0% { background-position: 200% 0; }
      100% { background-position: -200% 0; }
    }

    .skeleton-text {
      height: 14px;
      margin-bottom: 8px;
      border-radius: 6px;
    }

    .skeleton-text-sm {
      height: 12px;
      width: 60%;
      margin-bottom: 8px;
      border-radius: 6px;
    }

    .skeleton-text-lg {
      height: 18px;
      width: 80%;
      margin-bottom: 10px;
      border-radius: 6px;
    }

    .skeleton-filter {
      height: 30px;
      margin-bottom: 12px;
      border-radius: 8px;
    }

    .skeleton-checkbox {
      display: flex;
      align-items: center;
      margin-bottom: 10px;
    }

    .skeleton-checkbox .skeleton-box {
      width: 18px;
      height: 18px;
      border-radius: 4px;
      margin-right: 10px;
    }

    /* Product Card Skeleton */
    .product-card-skeleton {
      background: white;
      border-radius: 16px;
      padding: 1rem;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
      border: 1px solid #e2e8f0;
      height: 100%;
    }

    .skeleton-image {
      width: 100%;
      height: 180px;
      border-radius: 12px;
      margin-bottom: 1rem;
    }

    .skeleton-badge {
      width: 70px;
      height: 24px;
      border-radius: 20px;
      margin-bottom: 10px;
    }

    .skeleton-price {
      width: 100px;
      height: 24px;
      border-radius: 6px;
      margin-top: 10px;
    }

    .skeleton-button {
      width: 100%;
      height: 40px;
      border-radius: 8px;
      margin-top: 15px;
    }

    /* Product Card Réelle (pour la démonstration) */
    .product-card {
      background: white;
      border-radius: 16px;
      padding: 1rem;
      box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
      border: 1px solid #e2e8f0;
      height: 100%;
      transition: all 0.3s ease;
      position: relative;
      overflow: hidden;
    }

    .product-card:hover {
      transform: translateY(-4px);
      box-shadow: 0 12px 24px rgba(0, 0, 0, 0.08);
      border-color: #cbd5e1;
    }

    .product-badge {
      position: absolute;
      top: 1rem;
      left: 1rem;
      background: #ef4444;
      color: white;
      padding: 0.25rem 0.75rem;
      border-radius: 20px;
      font-size: 0.75rem;
      font-weight: 600;
      z-index: 2;
    }

    .product-badge.new {
      background: #10b981;
    }

    .product-badge.sale {
      background: #f59e0b;
    }

    .product-image {
      width: 100%;
      height: 180px;
      object-fit: cover;
      border-radius: 12px;
      margin-bottom: 1rem;
      background: #f1f5f9;
    }

    .product-category {
      color: #64748b;
      font-size: 0.8rem;
      text-transform: uppercase;
      letter-spacing: 0.5px;
      margin-bottom: 0.25rem;
    }

    .product-title {
      font-weight: 700;
      font-size: 1rem;
      color: #1e293b;
      margin-bottom: 0.5rem;
      line-height: 1.4;
    }

    .product-rating {
      display: flex;
      align-items: center;
      gap: 6px;
      margin-bottom: 0.5rem;
    }

    .stars {
      color: #fbbf24;
      letter-spacing: 2px;
      font-size: 0.85rem;
    }

    .rating-count {
      color: #64748b;
      font-size: 0.8rem;
    }

    .product-price {
      display: flex;
      align-items: center;
      gap: 8px;
      margin-bottom: 1rem;
    }

    .current-price {
      font-weight: 700;
      font-size: 1.3rem;
      color: #1e293b;
    }

    .old-price {
      color: #94a3b8;
      text-decoration: line-through;
      font-size: 0.9rem;
    }

    .btn-add-cart {
      width: 100%;
      background: #1e293b;
      color: white;
      border: none;
      border-radius: 8px;
      padding: 0.7rem;
      font-weight: 600;
      font-size: 0.9rem;
      transition: all 0.2s;
    }

    .btn-add-cart:hover {
      background: #3b82f6;
    }

    /* Loader spinner */
    .loader-overlay {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(255, 255, 255, 0.9);
      backdrop-filter: blur(4px);
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 9999;
      transition: opacity 0.3s ease;
    }

    .loader-content {
      text-align: center;
    }

    .spinner {
      width: 60px;
      height: 60px;
      border: 4px solid #e2e8f0;
      border-top-color: #3b82f6;
      border-radius: 50%;
      animation: spin 0.8s linear infinite;
      margin: 0 auto 1rem;
    }

    @keyframes spin {
      to { transform: rotate(360deg); }
    }

    .loader-text {
      color: #1e293b;
      font-weight: 600;
      font-size: 1.1rem;
    }

    .loader-subtext {
      color: #64748b;
      font-size: 0.9rem;
      margin-top: 0.25rem;
    }

    /* Progress bar de chargement */
    .loading-progress {
      width: 200px;
      height: 4px;
      background: #e2e8f0;
      border-radius: 4px;
      margin: 1rem auto 0;
      overflow: hidden;
    }

    .progress-fill {
      height: 100%;
      background: #3b82f6;
      border-radius: 4px;
      animation: progressFill 2s ease-in-out infinite;
      width: 0%;
    }

    @keyframes progressFill {
      0% { width: 0%; }
      50% { width: 70%; }
      100% { width: 100%; }
    }

    /* Pagination skeleton */
    .pagination-skeleton {
      display: flex;
      justify-content: center;
      gap: 8px;
      margin-top: 2rem;
    }

    .skeleton-page {
      width: 40px;
      height: 40px;
      border-radius: 8px;
    }

    /* Animation de fondu */
    .fade-in {
      animation: fadeIn 0.5s ease;
    }

    @keyframes fadeIn {
      from { opacity: 0; transform: translateY(10px); }
      to { opacity: 1; transform: translateY(0); }
    }

    /* Responsive */
    @media (max-width: 768px) {
      .page-title {
        font-size: 1.5rem;
      }

      .skeleton-image {
        height: 150px;
      }

      .product-image {
        height: 150px;
      }
    }

    /* Mode démonstration - basculer entre loading et loaded */
    .demo-controls {
      position: fixed;
      bottom: 20px;
      right: 20px;
      z-index: 10000;
      display: flex;
      gap: 10px;
    }

    .demo-btn {
      background: white;
      border: 1px solid #e2e8f0;
      border-radius: 12px;
      padding: 10px 20px;
      font-weight: 600;
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
      cursor: pointer;
      transition: all 0.2s;
    }

    .demo-btn:hover {
      background: #3b82f6;
      color: white;
      border-color: #3b82f6;
    }

    /* Conteneur principal */
    .products-container {
      transition: opacity 0.3s ease;
    }

    .products-container.loading {
      opacity: 0.6;
      pointer-events: none;
    }
  </style>
</head>
<body>

<!-- Loader Overlay -->
<div class="loader-overlay" id="loaderOverlay">
  <div class="loader-content">
    <div class="spinner"></div>
    <div class="loader-text">Chargement des produits...</div>
    <div class="loader-subtext">Cela ne prendra qu'un instant</div>
    <div class="loading-progress">
      <div class="progress-fill"></div>
    </div>
  </div>
</div>

<!-- Navbar -->
<nav class="navbar">
  <div class="container">
    <a class="navbar-brand" href="#">
      <i class="bi bi-bag-fill me-2" style="color: #3b82f6;"></i>Shop<span>Now</span>
    </a>
    <div class="d-flex gap-3">
      <a href="#" class="text-dark"><i class="bi bi-search fs-5"></i></a>
      <a href="#" class="text-dark"><i class="bi bi-heart fs-5"></i></a>
      <a href="#" class="text-dark position-relative">
        <i class="bi bi-cart3 fs-5"></i>
        <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">2</span>
      </a>
    </div>
  </div>
</nav>

<!-- Header de page -->
<div class="page-header">
  <div class="container">
    <h1 class="page-title">Tous les produits</h1>
    <nav aria-label="breadcrumb">
      <ol class="breadcrumb">
        <li class="breadcrumb-item"><a href="#">Accueil</a></li>
        <li class="breadcrumb-item"><a href="#">Boutique</a></li>
        <li class="breadcrumb-item active">Produits</li>
      </ol>
    </nav>
  </div>
</div>

<!-- Contenu principal -->
<div class="container pb-5">
  <div class="row">
    <!-- Sidebar Filtres -->
    <div class="col-lg-3">
      <!-- Filtres Skeleton (affiché pendant le chargement) -->
      <div id="filtersSkeleton">
        <div class="filter-section">
          <div class="filter-title skeleton skeleton-text"></div>
          <div class="skeleton skeleton-filter"></div>
          <div class="skeleton skeleton-filter"></div>
          <div class="skeleton skeleton-filter"></div>
        </div>

        <div class="filter-section">
          <div class="filter-title skeleton skeleton-text"></div>
          <div class="skeleton-checkbox">
            <div class="skeleton skeleton-box"></div>
            <div class="skeleton skeleton-text-sm" style="flex:1;"></div>
          </div>
          <div class="skeleton-checkbox">
            <div class="skeleton skeleton-box"></div>
            <div class="skeleton skeleton-text-sm" style="flex:1;"></div>
          </div>
          <div class="skeleton-checkbox">
            <div class="skeleton skeleton-box"></div>
            <div class="skeleton skeleton-text-sm" style="flex:1;"></div>
          </div>
          <div class="skeleton-checkbox">
            <div class="skeleton skeleton-box"></div>
            <div class="skeleton skeleton-text-sm" style="flex:1;"></div>
          </div>
        </div>

        <div class="filter-section">
          <div class="filter-title skeleton skeleton-text"></div>
          <div class="skeleton skeleton-text-sm" style="width:100%;"></div>
          <div class="skeleton" style="height:6px; margin:15px 0;"></div>
          <div class="d-flex justify-content-between">
            <div class="skeleton skeleton-text-sm" style="width:40px;"></div>
            <div class="skeleton skeleton-text-sm" style="width:40px;"></div>
          </div>
        </div>
      </div>

      <!-- Filtres Réels (cachés initialement) -->
      <div id="filtersReal" style="display: none;">
        <div class="filter-section">
          <h6 class="filter-title">Catégories</h6>
          <div class="form-check mb-2">
            <input class="form-check-input" type="checkbox" id="cat1" checked>
            <label class="form-check-label" for="cat1">Électronique (24)</label>
          </div>
          <div class="form-check mb-2">
            <input class="form-check-input" type="checkbox" id="cat2">
            <label class="form-check-label" for="cat2">Mode (18)</label>
          </div>
          <div class="form-check mb-2">
            <input class="form-check-input" type="checkbox" id="cat3">
            <label class="form-check-label" for="cat3">Maison (15)</label>
          </div>
          <div class="form-check">
            <input class="form-check-input" type="checkbox" id="cat4">
            <label class="form-check-label" for="cat4">Sports (12)</label>
          </div>
        </div>

        <div class="filter-section">
          <h6 class="filter-title">Marques</h6>
          <div class="form-check mb-2">
            <input class="form-check-input" type="checkbox" id="brand1">
            <label class="form-check-label" for="brand1">Apple (8)</label>
          </div>
          <div class="form-check mb-2">
            <input class="form-check-input" type="checkbox" id="brand2">
            <label class="form-check-label" for="brand2">Samsung (12)</label>
          </div>
          <div class="form-check mb-2">
            <input class="form-check-input" type="checkbox" id="brand3">
            <label class="form-check-label" for="brand3">Nike (6)</label>
          </div>
          <div class="form-check">
            <input class="form-check-input" type="checkbox" id="brand4">
            <label class="form-check-label" for="brand4">Adidas (5)</label>
          </div>
        </div>

        <div class="filter-section">
          <h6 class="filter-title">Prix</h6>
          <input type="range" class="form-range mb-3" min="0" max="1000" value="500">
          <div class="d-flex justify-content-between">
            <span class="small text-secondary">0€</span>
            <span class="small text-secondary">1000€</span>
          </div>
        </div>
      </div>
    </div>

    <!-- Zone des produits -->
    <div class="col-lg-9">
      <!-- Barre de tri et résultat -->
      <div class="d-flex justify-content-between align-items-center mb-4">
        <div id="resultCount">
          <span class="skeleton skeleton-text-sm d-inline-block" style="width:100px;"></span>
        </div>
        <div id="sortSelect">
          <span class="skeleton d-inline-block" style="width:150px; height:35px; border-radius:8px;"></span>
        </div>
      </div>

      <!-- Grille de produits -->
      <div class="row g-4" id="productsGrid">
        <!-- Squelettes de produits (8 items) -->
        <div class="col-md-4 col-sm-6 product-skeleton-item">
          <div class="product-card-skeleton">
            <div class="skeleton skeleton-image"></div>
            <div class="skeleton skeleton-badge"></div>
            <div class="skeleton skeleton-text"></div>
            <div class="skeleton skeleton-text-sm"></div>
            <div class="skeleton skeleton-price"></div>
            <div class="skeleton skeleton-button"></div>
          </div>
        </div>
        <div class="col-md-4 col-sm-6 product-skeleton-item">
          <div class="product-card-skeleton">
            <div class="skeleton skeleton-image"></div>
            <div class="skeleton skeleton-badge"></div>
            <div class="skeleton skeleton-text"></div>
            <div class="skeleton skeleton-text-sm"></div>
            <div class="skeleton skeleton-price"></div>
            <div class="skeleton skeleton-button"></div>
          </div>
        </div>
        <div class="col-md-4 col-sm-6 product-skeleton-item">
          <div class="product-card-skeleton">
            <div class="skeleton skeleton-image"></div>
            <div class="skeleton skeleton-badge"></div>
            <div class="skeleton skeleton-text"></div>
            <div class="skeleton skeleton-text-sm"></div>
            <div class="skeleton skeleton-price"></div>
            <div class="skeleton skeleton-button"></div>
          </div>
        </div>
        <div class="col-md-4 col-sm-6 product-skeleton-item">
          <div class="product-card-skeleton">
            <div class="skeleton skeleton-image"></div>
            <div class="skeleton skeleton-badge"></div>
            <div class="skeleton skeleton-text"></div>
            <div class="skeleton skeleton-text-sm"></div>
            <div class="skeleton skeleton-price"></div>
            <div class="skeleton skeleton-button"></div>
          </div>
        </div>
        <div class="col-md-4 col-sm-6 product-skeleton-item">
          <div class="product-card-skeleton">
            <div class="skeleton skeleton-image"></div>
            <div class="skeleton skeleton-badge"></div>
            <div class="skeleton skeleton-text"></div>
            <div class="skeleton skeleton-text-sm"></div>
            <div class="skeleton skeleton-price"></div>
            <div class="skeleton skeleton-button"></div>
          </div>
        </div>
        <div class="col-md-4 col-sm-6 product-skeleton-item">
          <div class="product-card-skeleton">
            <div class="skeleton skeleton-image"></div>
            <div class="skeleton skeleton-badge"></div>
            <div class="skeleton skeleton-text"></div>
            <div class="skeleton skeleton-text-sm"></div>
            <div class="skeleton skeleton-price"></div>
            <div class="skeleton skeleton-button"></div>
          </div>
        </div>
        <div class="col-md-4 col-sm-6 product-skeleton-item">
          <div class="product-card-skeleton">
            <div class="skeleton skeleton-image"></div>
            <div class="skeleton skeleton-badge"></div>
            <div class="skeleton skeleton-text"></div>
            <div class="skeleton skeleton-text-sm"></div>
            <div class="skeleton skeleton-price"></div>
            <div class="skeleton skeleton-button"></div>
          </div>
        </div>
        <div class="col-md-4 col-sm-6 product-skeleton-item">
          <div class="product-card-skeleton">
            <div class="skeleton skeleton-image"></div>
            <div class="skeleton skeleton-badge"></div>
            <div class="skeleton skeleton-text"></div>
            <div class="skeleton skeleton-text-sm"></div>
            <div class="skeleton skeleton-price"></div>
            <div class="skeleton skeleton-button"></div>
          </div>
        </div>
      </div>

      <!-- Produits Réels (cachés initialement) -->
      <div class="row g-4" id="productsReal" style="display: none;"></div>

      <!-- Pagination Skeleton -->
      <div class="pagination-skeleton" id="paginationSkeleton">
        <div class="skeleton skeleton-page"></div>
        <div class="skeleton skeleton-page"></div>
        <div class="skeleton skeleton-page"></div>
        <div class="skeleton skeleton-page"></div>
        <div class="skeleton skeleton-page"></div>
      </div>

      <!-- Pagination Réelle (cachée initialement) -->
      <div id="paginationReal" style="display: none;">
        <nav class="mt-5">
          <ul class="pagination justify-content-center">
            <li class="page-item disabled"><a class="page-link" href="#">Précédent</a></li>
            <li class="page-item active"><a class="page-link" href="#">1</a></li>
            <li class="page-item"><a class="page-link" href="#">2</a></li>
            <li class="page-item"><a class="page-link" href="#">3</a></li>
            <li class="page-item"><a class="page-link" href="#">4</a></li>
            <li class="page-item"><a class="page-link" href="#">Suivant</a></li>
          </ul>
        </nav>
      </div>
    </div>
  </div>
</div>

<!-- Boutons de démonstration -->
<div class="demo-controls">
  <button class="demo-btn" id="showLoadingBtn">
    <i class="bi bi-arrow-repeat me-2"></i>Simuler chargement
  </button>
  <button class="demo-btn" id="showLoadedBtn">
    <i class="bi bi-check-circle me-2"></i>Afficher produits
  </button>
</div>

<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>

<script>
  (function() {
    'use strict';

    // Éléments DOM
    const loaderOverlay = document.getElementById('loaderOverlay');
    const filtersSkeleton = document.getElementById('filtersSkeleton');
    const filtersReal = document.getElementById('filtersReal');
    const productsGrid = document.getElementById('productsGrid');
    const productsReal = document.getElementById('productsReal');
    const paginationSkeleton = document.getElementById('paginationSkeleton');
    const paginationReal = document.getElementById('paginationReal');
    const resultCount = document.getElementById('resultCount');
    const sortSelect = document.getElementById('sortSelect');

    // Données des produits
    const products = [
      { id: 1, name: 'Écouteurs Sans Fil Pro', category: 'Électronique', price: 89.99, oldPrice: 129.99, rating: 4.8, reviews: 234, badge: 'sale', image: '🎧' },
      { id: 2, name: 'Montre Connectée Sport', category: 'Électronique', price: 199.99, oldPrice: null, rating: 4.9, reviews: 156, badge: 'new', image: '⌚' },
      { id: 3, name: 'Sac à Dos Urbain', category: 'Mode', price: 59.99, oldPrice: 79.99, rating: 4.7, reviews: 89, badge: 'sale', image: '🎒' },
      { id: 4, name: 'Enceinte Bluetooth Portable', category: 'Électronique', price: 49.99, oldPrice: null, rating: 4.6, reviews: 312, badge: null, image: '🔊' },
      { id: 5, name: 'Baskets Running Air', category: 'Sports', price: 129.99, oldPrice: 159.99, rating: 4.8, reviews: 178, badge: 'sale', image: '👟' },
      { id: 6, name: 'Lampe de Bureau LED', category: 'Maison', price: 34.99, oldPrice: null, rating: 4.5, reviews: 67, badge: null, image: '💡' },
      { id: 7, name: 'Gourde Isotherme', category: 'Sports', price: 24.99, oldPrice: 34.99, rating: 4.7, reviews: 145, badge: 'sale', image: '🧴' },
      { id: 8, name: 'Chargeur Rapide USB-C', category: 'Électronique', price: 29.99, oldPrice: null, rating: 4.8, reviews: 423, badge: null, image: '🔌' },
      { id: 9, name: 'T-shirt Premium Coton', category: 'Mode', price: 29.99, oldPrice: 39.99, rating: 4.4, reviews: 98, badge: 'sale', image: '👕' }
    ];

    // Générer les étoiles
    function getStars(rating) {
      const fullStars = Math.floor(rating);
      const halfStar = rating % 1 >= 0.5;
      let stars = '';
      for (let i = 0; i < fullStars; i++) stars += '★';
      if (halfStar) stars += '½';
      while (stars.length < 5) stars += '☆';
      return stars;
    }

    // Afficher les produits réels
    function renderProducts() {
      let html = '';
      products.forEach(product => {
        const badgeHtml = product.badge ?
          `<span class="product-badge ${product.badge}">${product.badge === 'sale' ? '-30%' : 'Nouveau'}</span>` : '';

        html += `
          <div class="col-md-4 col-sm-6 fade-in">
            <div class="product-card">
              ${badgeHtml}
              <div class="product-image d-flex align-items-center justify-content-center" style="font-size: 4rem;">
                ${product.image}
              </div>
              <div class="product-category">${product.category}</div>
              <h3 class="product-title">${product.name}</h3>
              <div class="product-rating">
                <span class="stars">${getStars(product.rating)}</span>
                <span class="rating-count">(${product.reviews})</span>
              </div>
              <div class="product-price">
                <span class="current-price">${product.price.toFixed(2)}€</span>
                ${product.oldPrice ? `<span class="old-price">${product.oldPrice.toFixed(2)}€</span>` : ''}
              </div>
              <button class="btn-add-cart">
                <i class="bi bi-cart-plus me-2"></i>Ajouter au panier
              </button>
            </div>
          </div>
        `;
      });
      productsReal.innerHTML = html;
    }

    // Afficher le compteur de résultats réel
    function renderResultCount() {
      resultCount.innerHTML = `<span class="result-count"><i class="bi bi-grid-3x3-gap-fill me-1"></i>${products.length} produits trouvés</span>`;
    }

    // Afficher le select de tri réel
    function renderSortSelect() {
      sortSelect.innerHTML = `
        <select class="form-select" style="width: auto; min-width: 180px;">
          <option selected>Trier par : Popularité</option>
          <option>Prix : croissant</option>
          <option>Prix : décroissant</option>
          <option>Nouveautés</option>
          <option>Meilleures ventes</option>
        </select>
      `;
    }

    // Mode chargement
    function showLoading() {
      loaderOverlay.style.display = 'flex';
      filtersSkeleton.style.display = 'block';
      filtersReal.style.display = 'none';
      productsGrid.style.display = 'flex';
      productsReal.style.display = 'none';
      paginationSkeleton.style.display = 'flex';
      paginationReal.style.display = 'none';

      resultCount.innerHTML = '<span class="skeleton skeleton-text-sm d-inline-block" style="width:100px;"></span>';
      sortSelect.innerHTML = '<span class="skeleton d-inline-block" style="width:150px; height:35px; border-radius:8px;"></span>';
    }

    // Mode chargé
    function showLoaded() {
      loaderOverlay.style.display = 'none';
      filtersSkeleton.style.display = 'none';
      filtersReal.style.display = 'block';
      productsGrid.style.display = 'none';
      productsReal.style.display = 'flex';
      paginationSkeleton.style.display = 'none';
      paginationReal.style.display = 'block';

      renderProducts();
      renderResultCount();
      renderSortSelect();
    }

    // Simuler un temps de chargement
    function simulateLoading() {
      showLoading();

      setTimeout(() => {
        showLoaded();
      }, 2500);
    }

    // Boutons de démonstration
    document.getElementById('showLoadingBtn').addEventListener('click', () => {
      showLoading();
      setTimeout(() => {
        // Reste en loading jusqu'à ce qu'on clique sur "Afficher produits"
      }, 100);
    });

    document.getElementById('showLoadedBtn').addEventListener('click', () => {
      showLoaded();
    });

    // Masquer le loader après 2 secondes au chargement initial
    window.addEventListener('load', () => {
      setTimeout(() => {
        showLoaded();
      }, 2000);
    });

    // Initialiser en mode chargement
    showLoading();
  })();
</script>

</body>
</html>