Panier
E Commerce
Bootstrap 5
Responsive
Html
Css
Javascript
Produits
Template
Boutique
Commande
Shopping Cart
Template panier e-commerce Bootstrap 5 avec liste produits, quantités modifiables, calcul sous-total et bouton commande. Design moderne pour boutique en ligne.
<!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>Template Product Panier Bootstrap5 2026 05081225 | AngularForAll</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css">
<style>
:root {
--primary: #6c5ce7;
--secondary: #a8a4e6;
--accent: #ff6b6b;
--dark: #2d3436;
--light: #f8f9fa;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
background-attachment: fixed;
min-height: 100vh;
}
.main-container {
background: rgba(255, 255, 255, 0.95);
border-radius: 30px;
margin: 30px auto;
padding: 30px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
backdrop-filter: blur(10px);
max-width: 1400px;
}
.navbar-custom {
background: white;
border-radius: 20px;
padding: 15px 30px;
margin-bottom: 30px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.1);
}
.cart-icon {
position: relative;
cursor: pointer;
transition: transform 0.3s ease;
}
.cart-icon:hover {
transform: scale(1.1);
}
.cart-count {
position: absolute;
top: -8px;
right: -8px;
background: var(--accent);
color: white;
border-radius: 50%;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: bold;
}
.product-card {
background: white;
border-radius: 20px;
overflow: hidden;
transition: all 0.3s ease;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
border: none;
height: 100%;
}
.product-card:hover {
transform: translateY(-10px);
box-shadow: 0 15px 40px rgba(108, 92, 231, 0.3);
}
.product-image {
height: 250px;
object-fit: cover;
transition: transform 0.3s ease;
}
.product-card:hover .product-image {
transform: scale(1.05);
}
.product-badge {
position: absolute;
top: 15px;
right: 15px;
background: var(--accent);
color: white;
padding: 5px 15px;
border-radius: 20px;
font-size: 14px;
font-weight: bold;
}
.btn-primary {
background: var(--primary);
border: none;
border-radius: 15px;
padding: 10px 25px;
transition: all 0.3s ease;
}
.btn-primary:hover {
background: #5b4bc4;
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(108, 92, 231, 0.4);
}
.modal-custom {
border-radius: 30px;
overflow: hidden;
}
.modal-header {
background: linear-gradient(135deg, var(--primary), var(--secondary));
color: white;
}
.cart-item {
background: white;
border-radius: 15px;
padding: 15px;
margin-bottom: 15px;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
}
.quantity-btn {
background: var(--light);
border: 2px solid var(--primary);
color: var(--primary);
border-radius: 10px;
padding: 5px 12px;
transition: all 0.3s ease;
}
.quantity-btn:hover {
background: var(--primary);
color: white;
}
.search-container {
position: relative;
}
.search-input {
border-radius: 15px;
border: 2px solid #e0e0e0;
padding: 10px 20px;
transition: all 0.3s ease;
}
.search-input:focus {
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(108, 92, 231, 0.1);
}
.empty-cart {
text-align: center;
padding: 50px 20px;
}
.fade-in {
animation: fadeIn 0.6s ease-in;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.toast-custom {
position: fixed;
bottom: 30px;
right: 30px;
background: white;
border-radius: 15px;
padding: 15px 25px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
z-index: 9999;
animation: slideInRight 0.5s ease;
}
@keyframes slideInRight {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
</style>
</head>
<body>
<div class="container main-container">
<!-- Navigation -->
<nav class="navbar navbar-custom">
<div class="container-fluid">
<span class="navbar-brand mb-0 h1">
<i class="bi bi-bag-heart-fill" style="color: var(--primary);"></i>
<strong>ShopModerne</strong>
</span>
<div class="d-flex align-items-center gap-3">
<div class="search-container">
<input type="text" id="searchInput" class="form-control search-input" placeholder="Rechercher un produit...">
</div>
<div class="cart-icon" onclick="openCart()">
<i class="bi bi-cart3" style="font-size: 28px; color: var(--primary);"></i>
<span class="cart-count" id="cartCount">0</span>
</div>
</div>
</div>
</nav>
<!-- Products Section -->
<div class="row" id="productsContainer">
<!-- Products will be rendered here -->
</div>
</div>
<!-- Cart Modal -->
<div class="modal fade" id="cartModal" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-scrollable">
<div class="modal-content modal-custom">
<div class="modal-header">
<h5 class="modal-title">
<i class="bi bi-cart-check"></i> Mon Panier
</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="close"></button>
</div>
<div class="modal-body" id="cartItems">
<!-- Cart items will be rendered here -->
</div>
<div class="modal-footer d-flex justify-content-between">
<div>
<strong>Total: </strong>
<span class="text-primary fw-bold fs-5" id="cartTotal">0.00 €</span>
</div>
<div>
<button class="btn btn-outline-danger" onclick="clearCart()">
<i class="bi bi-trash"></i> Vider le panier
</button>
<button class="btn btn-primary ms-2" onclick="checkout()">
<i class="bi bi-credit-card"></i> Commander
</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Product Data
const products = [
{
id: 1,
name: "Smartphone Pro X",
price: 899.99,
image: "public/main-phone.webp",
description: "Smartphone dernière génération avec appareil photo 108MP",
badge: "Nouveau"
},
{
id: 2,
name: "Écouteurs Sans Fil",
price: 149.99,
image: "public/baff.webp",
description: "Écouteurs bluetooth avec réduction de bruit active",
badge: "Promo"
},
{
id: 3,
name: "Montre Connectée",
price: 299.99,
image: "public/smartwash.webp",
description: "Montre intelligente avec suivi santé et GPS",
badge: "Best Seller"
},
{
id: 4,
name: "Tablette Graphique",
price: 449.99,
image: "public/phoneL.webp",
description: "Tablette pour designers avec stylet ultra-précis",
badge: "Premium"
},
{
id: 5,
name: "Enceinte Portable",
price: 79.99,
image: "public/ordinateur-portable-laptop.webp",
description: "Enceinte waterproof avec son 360°",
badge: "Promo"
},
{
id: 6,
name: "Caméra Action 4K",
price: 249.99,
image: "public/mobile1.png",
description: "Caméra ultra-HD stabilisée pour vos aventures",
badge: "Nouveau"
},
{
id: 7,
name: "Clavier Mécanique RGB",
price: 129.99,
image: "public/img1.jpg",
description: "Clavier gaming avec switches Cherry MX",
},
{
id: 8,
name: "Disque Dur SSD 1To",
price: 109.99,
image: "public/img2.jpg",
description: "Stockage ultra-rapide pour vos données",
badge: "Promo"
}
];
// Cart Management
let cart = JSON.parse(localStorage.getItem('cart')) || [];
function saveCart() {
localStorage.setItem('cart', JSON.stringify(cart));
updateCartCount();
}
function updateCartCount() {
const count = cart.reduce((sum, item) => sum + item.quantity, 0);
document.getElementById('cartCount').textContent = count;
}
function addToCart(productId) {
const product = products.find(p => p.id === productId);
const existingItem = cart.find(item => item.id === productId);
if (existingItem) {
existingItem.quantity++;
} else {
cart.push({
...product,
quantity: 1
});
}
saveCart();
showToast(`${product.name} ajouté au panier !`);
}
function removeFromCart(productId) {
cart = cart.filter(item => item.id !== productId);
saveCart();
renderCart();
showToast('Produit retiré du panier');
}
function updateQuantity(productId, change) {
const item = cart.find(item => item.id === productId);
if (item) {
item.quantity += change;
if (item.quantity <= 0) {
removeFromCart(productId);
} else {
saveCart();
renderCart();
}
}
}
function clearCart() {
if (confirm('Voulez-vous vraiment vider le panier ?')) {
cart = [];
saveCart();
renderCart();
showToast('Panier vidé');
}
}
function getCartTotal() {
return cart.reduce((sum, item) => sum + (item.price * item.quantity), 0);
}
function openCart() {
renderCart();
const modal = new bootstrap.Modal(document.getElementById('cartModal'));
modal.show();
}
function checkout() {
if (cart.length === 0) {
alert('Votre panier est vide !');
return;
}
const total = getCartTotal().toFixed(2);
if (confirm(`Confirmer la commande de ${total} € ?`)) {
alert('Commande validée avec succès ! Merci pour votre achat.');
cart = [];
saveCart();
renderCart();
const modal = bootstrap.Modal.getInstance(document.getElementById('cartModal'));
modal.hide();
}
}
function showToast(message) {
const toast = document.createElement('div');
toast.className = 'toast-custom';
toast.innerHTML = `
<i class="bi bi-check-circle-fill text-success me-2"></i>
${message}
`;
document.body.appendChild(toast);
setTimeout(() => {
toast.remove();
}, 3000);
}
// Render Functions
function renderProducts(productsToRender = products) {
const container = document.getElementById('productsContainer');
container.innerHTML = productsToRender.map((product, index) => `
<div class="col-md-6 col-lg-3 mb-4 fade-in" style="animation-delay: ${index * 0.1}s">
<div class="product-card">
<div class="position-relative">
<img src="${product.image}" class="product-image w-100" alt="${product.name}">
${product.badge ? `<span class="product-badge">${product.badge}</span>` : ''}
</div>
<div class="p-3">
<h5 class="fw-bold mb-2">${product.name}</h5>
<p class="text-muted small mb-3">${product.description}</p>
<div class="d-flex justify-content-between align-items-center">
<span class="fs-4 fw-bold" style="color: var(--primary);">
${product.price.toFixed(2)} €
</span>
<button class="btn btn-primary" onclick="addToCart(${product.id})">
<i class="bi bi-cart-plus"></i> Ajouter
</button>
</div>
</div>
</div>
</div>
`).join('');
}
function renderCart() {
const container = document.getElementById('cartItems');
if (cart.length === 0) {
container.innerHTML = `
<div class="empty-cart">
<i class="bi bi-cart-x" style="font-size: 64px; color: #ddd;"></i>
<h4 class="mt-3">Votre panier est vide</h4>
<p class="text-muted">Ajoutez des produits pour commencer vos achats</p>
</div>
`;
} else {
container.innerHTML = cart.map(item => `
<div class="cart-item">
<div class="row align-items-center">
<div class="col-md-2">
<img src="${item.image}" class="rounded" width="80" height="80" style="object-fit: cover;" alt="${item.name}">
</div>
<div class="col-md-4">
<h6 class="mb-1">${item.name}</h6>
<small class="text-muted">${item.price.toFixed(2)} € / unité</small>
</div>
<div class="col-md-3">
<div class="d-flex align-items-center gap-2">
<button class="quantity-btn" onclick="updateQuantity(${item.id}, -1)">-</button>
<span class="fw-bold fs-5">${item.quantity}</span>
<button class="quantity-btn" onclick="updateQuantity(${item.id}, 1)">+</button>
</div>
</div>
<div class="col-md-2">
<span class="fw-bold">${(item.price * item.quantity).toFixed(2)} €</span>
</div>
<div class="col-md-1">
<button class="btn btn-danger btn-sm" onclick="removeFromCart(${item.id})">
<i class="bi bi-trash"></i>
</button>
</div>
</div>
</div>
`).join('');
}
document.getElementById('cartTotal').textContent = `${getCartTotal().toFixed(2)} €`;
}
// Search functionality
document.getElementById('searchInput').addEventListener('input', (e) => {
const searchTerm = e.target.value.toLowerCase();
const filtered = products.filter(product =>
product.name.toLowerCase().includes(searchTerm) ||
product.description.toLowerCase().includes(searchTerm)
);
renderProducts(filtered);
});
// Initialize
document.addEventListener('DOMContentLoaded', () => {
renderProducts();
updateCartCount();
renderCart();
});
</script>
</body>
</html>
Télécharger le fichier source