Retour
Tapis Classique - sur_mesure #1 - Tapis L’Iran – Sur mesure - waootapis

Tapis Classique - sur_mesure #1 - Tapis L’Iran – Sur mesure

1 800,00 MAD
Prix au m²

Tapis Classique - sur_mesure #1

Matériau: Laine
Dimensions max : 200 cm × 300 cm
Couleur: Jaune
Stock: En stock (10)

Description

Tapis Classique - sur_mesure de haute qualité, sélectionné automatiquement pour la démo.

// Si type fixe, pas de dimensions requises let length = 0; let width = 0; let calculatedPrice = window.unitPrice; const isFixe = (window.isFixe === true || window.isFixe === 'true'); const isSurMesure = (window.isSurMesure === true || window.isSurMesure === 'true'); if (!isFixe) { length = parseFloat(document.getElementById('modal-length').value) || 0; width = parseFloat(document.getElementById('modal-width').value) || 0; if (length <= 0 || width <= 0) { showNotification('Veuillez entrer des dimensions valides', 'error'); return; } // Pour sur mesure, respecter les dimensions max if (isSurMesure && (window.maxWidthCm || window.maxHeightCm)) { if (window.maxWidthCm && length > window.maxWidthCm) { showNotification('La longueur maximale pour ce modèle est de ' + window.maxWidthCm + ' cm.', 'error'); return; } if (window.maxHeightCm && width > window.maxHeightCm) { showNotification('La largeur maximale pour ce modèle est de ' + window.maxHeightCm + ' cm.', 'error'); return; } } const surfaceM2 = (length * width) / 10000; calculatedPrice = surfaceM2 * window.unitPrice; } const btn = this; btn.disabled = true; btn.textContent = 'Ajout en cours...'; const formData = new FormData(); // Récupérer la couleur sélectionnée const selectedColorInput = document.getElementById('selected-color'); const selectedColor = selectedColorInput ? selectedColorInput.value : ''; formData.append('product_id', productId); formData.append('quantity', quantity); formData.append('length', length); formData.append('width', width); formData.append('calculated_price', calculatedPrice); if (selectedColor) { formData.append('color', selectedColor); } fetch('api/add_to_cart.php', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { if (data.success) { if (typeof showNotification === 'function') { showNotification(data.message, 'success'); } if (typeof updateCartCount === 'function') { updateCartCount(data.cart_count); } window.closeDimensionsModal(); } else { if (typeof showNotification === 'function') { showNotification(data.message || 'Erreur lors de l\'ajout au panier', 'error'); } } }) .catch(error => { if (typeof showNotification === 'function') { showNotification('Erreur lors de l\'ajout au panier', 'error'); } }) .finally(() => { btn.disabled = false; btn.textContent = 'Ajouter au panier'; }); }); } }); // Fonction pour changer l'image principale function changeMainImage(src, element, colorName, colorIndex) { const mainImage = document.getElementById('main-image'); if (mainImage) { // Ajouter un effet de fondu mainImage.style.opacity = '0.5'; setTimeout(() => { mainImage.src = src; mainImage.style.opacity = '1'; }, 150); } // Mettre à jour les miniatures actives document.querySelectorAll('.thumbnail').forEach(thumb => thumb.classList.remove('active')); if (element) { element.classList.add('active'); } // Si une couleur correspond à cette image, la sélectionner automatiquement let colorToSelect = colorName; // Si pas de nom de couleur mais un index, trouver la couleur par index if ((!colorToSelect || colorToSelect.trim() === '') && colorIndex !== undefined && colorIndex !== null) { const colorOptions = document.querySelectorAll('.color-option'); if (colorIndex < colorOptions.length) { const colorOption = colorOptions[colorIndex]; colorToSelect = colorOption.getAttribute('data-color-name'); } } if (colorToSelect && colorToSelect.trim() !== '') { // Trouver l'option de couleur correspondante const colorOptions = document.querySelectorAll('.color-option'); let colorFound = false; colorOptions.forEach((opt, idx) => { const optColorName = opt.getAttribute('data-color-name'); // Comparer par nom ou par index if ((optColorName && optColorName.trim() === colorToSelect.trim()) || (colorIndex !== undefined && idx === colorIndex)) { colorFound = true; // Simuler un clic sur cette couleur pour mettre à jour l'apparence opt.style.borderColor = 'var(--primary-color)'; opt.style.background = 'rgba(139,69,19,0.1)'; // Mettre à jour le champ caché const selectedColorInput = document.getElementById('selected-color'); if (selectedColorInput) { const finalColorName = optColorName || colorToSelect; selectedColorInput.value = finalColorName; } // Désélectionner les autres couleurs colorOptions.forEach(otherOpt => { if (otherOpt !== opt) { otherOpt.style.borderColor = 'var(--border-color)'; otherOpt.style.background = 'var(--light-color)'; } }); } }); } } // Fonction pour sélectionner une couleur function selectColor(element, colorName, colorImage, colorIndex) { // Mettre à jour l'apparence des options de couleur document.querySelectorAll('.color-option').forEach(opt => { opt.style.borderColor = 'var(--border-color)'; opt.style.background = 'var(--light-color)'; }); element.style.borderColor = 'var(--primary-color)'; element.style.background = 'rgba(139,69,19,0.1)'; // Mettre à jour le champ caché const selectedColorInput = document.getElementById('selected-color'); if (selectedColorInput) { selectedColorInput.value = colorName; } // Changer l'image principale const mainImage = document.getElementById('main-image'); if (mainImage) { let imagePath = colorImage && colorImage.trim() !== '' ? colorImage.trim() : null; // Si pas d'image directe, chercher l'image correspondante par index if (!imagePath && colorIndex !== undefined && colorIndex !== null) { const thumbnails = document.querySelectorAll('.thumbnail'); if (colorIndex < thumbnails.length) { const matchingThumbnail = thumbnails[colorIndex]; imagePath = matchingThumbnail.getAttribute('data-image-path') || matchingThumbnail.src; } } if (imagePath) { // Ajouter un effet de fondu lors du changement mainImage.style.opacity = '0.5'; // Précharger l'image pour éviter les erreurs const img = new Image(); img.onload = function() { mainImage.src = imagePath; mainImage.style.opacity = '1'; // Mettre à jour la miniature active document.querySelectorAll('.thumbnail').forEach(thumb => { thumb.classList.remove('active'); const thumbImagePath = thumb.getAttribute('data-image-path') || thumb.src; const thumbSrc = thumbImagePath.split('/').pop(); const newImageName = imagePath.split('/').pop(); // Comparer les chemins complets ou juste les noms de fichiers if (thumbImagePath === imagePath || thumbSrc === newImageName || thumb.src.includes(newImageName)) { thumb.classList.add('active'); } }); }; img.onerror = function() { // Essayer différentes variantes du chemin const pathVariants = [ imagePath, '../' + imagePath, imagePath.replace(/^\.\.\//, ''), imagePath.startsWith('assets/') ? imagePath : 'assets/images/products/' + imagePath.split('/').pop() ]; let triedVariants = 0; const tryNextVariant = function() { if (triedVariants < pathVariants.length) { const variant = pathVariants[triedVariants]; const testImg = new Image(); testImg.onload = function() { mainImage.src = variant; mainImage.style.opacity = '1'; // Mettre à jour la miniature active document.querySelectorAll('.thumbnail').forEach(thumb => { thumb.classList.remove('active'); const thumbImagePath = thumb.getAttribute('data-image-path') || thumb.src; if (thumbImagePath === variant || thumb.src.includes(variant.split('/').pop())) { thumb.classList.add('active'); } }); }; testImg.onerror = function() { triedVariants++; tryNextVariant(); }; testImg.src = variant; } else { // Si aucune variante ne fonctionne, restaurer l'image par défaut const defaultImage = mainImage.getAttribute('data-default-image'); if (defaultImage) { mainImage.src = defaultImage; mainImage.style.opacity = '1'; } else { mainImage.style.opacity = '1'; } } }; tryNextVariant(); }; img.src = imagePath; } else { // Si pas d'image pour la couleur, restaurer l'image par défaut const defaultImage = mainImage.getAttribute('data-default-image'); if (defaultImage) { mainImage.src = defaultImage; mainImage.style.opacity = '1'; } } } } function increaseQuantity() { const input = document.getElementById('product-quantity'); const max = parseInt(input.getAttribute('max')); if (parseInt(input.value) < max) { input.value = parseInt(input.value) + 1; } } function decreaseQuantity() { const input = document.getElementById('product-quantity'); if (parseInt(input.value) > 1) { input.value = parseInt(input.value) - 1; } } function calculateTotalPrice() { const lengthInput = document.getElementById('length'); const widthInput = document.getElementById('width'); // Vérifier si les champs existent (pour les produits sans calculateur de dimensions) if (!lengthInput || !widthInput) { return; } const length = parseFloat(lengthInput.value) || 0; const width = parseFloat(widthInput.value) || 0; const priceCalculation = document.getElementById('price-calculation'); const dimensionsDisplay = document.getElementById('dimensions-display'); const surfaceArea = document.getElementById('surface-area'); const totalPrice = document.getElementById('total-price'); if (length > 0 && width > 0) { // Convertir cm² en m² (1 m² = 10 000 cm²) const surfaceCm2 = length * width; const surfaceM2 = surfaceCm2 / 10000; const total = surfaceM2 * unitPrice; // Afficher les dimensions if (dimensionsDisplay) { dimensionsDisplay.textContent = Math.round(length) + ' cm × ' + Math.round(width) + ' cm'; } // Afficher la surface avec 2 décimales et format français const surfaceFormatted = surfaceM2.toFixed(2).replace('.', ','); if (surfaceArea) { surfaceArea.textContent = surfaceFormatted + ' m²'; } if (totalPrice) { totalPrice.textContent = formatPrice(total); } if (priceCalculation) { priceCalculation.style.display = 'block'; } } else { if (priceCalculation) { priceCalculation.style.display = 'none'; } } } window.formatPrice = function(price) { // Format: 1 234,56 MAD (comme la fonction PHP) return price.toFixed(2).replace('.', ',').replace(/\B(?=(\d{3})+(?!\d))/g, ' ') + ' MAD'; };