1/** 2 * Aratice Quote Notifications 3 * Système de notifications pour les actions sur le devis 4 */ 5 6(function ($) { 7 "use strict"; 8 9 // Container pour les notifications (créé dynamiquement) 10 let $notificationContainer = null; 11 12 /** 13 * Initialiser le container de notifications 14 */ 15 function initNotificationContainer() { 16 if ($notificationContainer) { 17 return; 18 } 19 20 // Injecter les styles critiques inline pour garantir l'affichage 21 // même si le CSS externe est différé/supprimé par un plugin de cache 22 if (!document.getElementById("aratice-notif-inline-css")) { 23 var style = document.createElement("style"); 24 style.id = "aratice-notif-inline-css"; 25 style.textContent = 26 ".aratice-notifications-container{position:fixed;top:24px;right:24px;z-index:99999;display:flex;flex-direction:column;gap:12px;pointer-events:none;max-width:420px}" + 27 ".aratice-notification{display:flex;align-items:flex-start;gap:12px;padding:16px 20px;background:#fff;border-radius:12px;box-shadow:0 4px 12px rgba(0,0,0,.15),0 0 0 1px rgba(0,0,0,.05);pointer-events:auto;opacity:0;transform:translateX(400px);transition:all .3s cubic-bezier(.4,0,.2,1);max-width:100%;position:relative;overflow:hidden;font-family:'Lexend Deca',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif}" + 28 ".aratice-notification-show{opacity:1;transform:translateX(0)}" + 29 ".aratice-notification::before{content:'';position:absolute;bottom:0;left:0;height:3px;width:100%;transform-origin:left;animation:notifProg 3s linear forwards}" + 30 "@keyframes notifProg{from{transform:scaleX(1)}to{transform:scaleX(0)}}" + 31 ".aratice-notification-icon{flex-shrink:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center}" + 32 ".aratice-notification-icon svg{width:24px;height:24px}" + 33 ".aratice-notification-message{flex:1;font-size:14px;line-height:1.5;color:#1a1a1a;word-break:break-word}" + 34 ".aratice-notification-message strong{font-weight:600;color:#000}" + 35 ".aratice-notification-close{flex-shrink:0;width:20px;height:20px;padding:0;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:4px;color:#666}" + 36 ".aratice-notification-close svg{width:16px;height:16px}" + 37 ".aratice-notification-success{border-left:4px solid #7EAD53}" + 38 ".aratice-notification-success .aratice-notification-icon{color:#7EAD53}" + 39 ".aratice-notification-success::before{background:#7EAD53}" + 40 ".aratice-notification-error{border-left:4px solid #ef4444}" + 41 ".aratice-notification-error .aratice-notification-icon{color:#ef4444}" + 42 ".aratice-notification-error::before{background:#ef4444}" + 43 ".aratice-notification-info{border-left:4px solid #2B4B7C}" + 44 ".aratice-notification-info .aratice-notification-icon{color:#2B4B7C}" + 45 ".aratice-notification-info::before{background:#2B4B7C}" + 46 ".aratice-notification-warning{border-left:4px solid #f59e0b}" + 47 ".aratice-notification-warning .aratice-notification-icon{color:#f59e0b}" + 48 ".aratice-notification-warning::before{background:#f59e0b}"; 49 document.head.appendChild(style); 50 } 51 52 $notificationContainer = $( 53 '<div class="aratice-notifications-container"></div>' 54 ); 55 $("body").append($notificationContainer); 56 } 57 58 /** 59 * Afficher une notification 60 * @param {string} message - Message à afficher 61 * @param {string} type - Type de notification (success, error, info, warning) 62 * @param {number} duration - Durée d'affichage en ms (0 = permanent) 63 */ 64 function showNotification(message, type = "success", duration = 3000) { 65 initNotificationContainer(); 66 67 // Icône selon le type 68 const icons = { 69 success: `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> 70 <path d="M9 12L11 14L15 10M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" 71 stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 72 </svg>`, 73 error: `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
74 <path d="M12 8V12M12 16H12.01M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" 75 stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 76 </svg>`, 77 info: `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> 78 <path d="M12 16V12M12 8H12.01M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" 79 stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 80 </svg>`, 81 warning: `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> 82 <path d="M12 9V13M12 17H12.01M10.29 3.86L1.82 18C1.64537 18.3024 1.55297 18.6453 1.55199 18.9945C1.55101 19.3437 1.64149 19.6871 1.81441 19.9905C1.98733 20.2939 2.23641 20.5467 2.53682 20.7239C2.83723 20.9012 3.17975 20.9962 3.53 21H20.47C20.8203 20.9962 21.1628 20.9012 21.4632 20.7239C21.7636 20.5467 22.0127 20.2939 22.1856 19.9905C22.3585 19.6871 22.449 19.3437 22.448 18.9945C22.447 18.6453 22.3546 18.3024 22.18 18L13.71 3.86C13.5317 3.56611 13.2807 3.32312 12.9812 3.15448C12.6817 2.98585 12.3437 2.89725 12 2.89725C11.6563 2.89725 11.3183 2.98585 11.0188 3.15448C10.7193 3.32312 10.4683 3.56611 10.29 3.86Z" 83 stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 84 </svg>`, 85 }; 86 87 // Créer la notification 88 const $notification = $(` 89 <div class="aratice-notification aratice-notification-${type}"> 90 <div class="aratice-notification-icon"> 91 ${icons[type] || icons.info} 92 </div> 93 <div class="aratice-notification-message">${message}</div> 94 <button class="aratice-notification-close" aria-label="Fermer"> 95 <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> 96 <path d="M18 6L6 18M6 6L18 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 97 </svg> 98 </button> 99 </div> 100 `); 101 102 // Ajouter au container 103 $notificationContainer.append($notification); 104 105 // Animation d'entrée 106 setTimeout(() => { 107 $notification.addClass("aratice-notification-show"); 108 }, 10); 109 110 // Bouton fermer 111 $notification.find(".aratice-notification-close").on("click", function () { 112 closeNotification($notification); 113 }); 114 115 // Auto-fermeture si durée définie 116 if (duration > 0) { 117 setTimeout(() => { 118 closeNotification($notification); 119 }, duration); 120 } 121 122 return $notification; 123 } 124 125 /** 126 * Fermer une notification 127 * @param {jQuery} $notification - Ãlément notification à fermer 128 */ 129 function closeNotification($notification) { 130 $notification.removeClass("aratice-notification-show"); 131 setTimeout(() => { 132 $notification.remove(); 133 }, 300); 134 } 135 136 /** 137 * Ãcouter les événements de devis 138 */ 139 function listenToQuoteEvents() { 140 // Ajout de produit uniquement 141 $(document).on( 142 "aratice:product_added_to_quote", 143 function (e, productId, data) { 144 // Gérer deux formats de données : 145 // 1. { product: result.item, totals } (products-grid, quote-drag-drop, etc.) 146 // 2. result.item directement (product-options-sidebar, product-cart) 147 let productName = "Produit"; 148 149 if (data?.product?.title) { 150 // Format 1: data contient product 151 productName = data.product.title; 152 } else if (data?.title) { 153 // Format 2: data est directement l'item 154 productName = data.title; 155 } 156 157 showNotification( 158 `<strong>${productName}</strong> ajouté au devis`, 159 "success", 160 3000 161 ); 162 } 163 ); 164 } 165 166 /** 167 * Initialisation 168 */ 169 $(document).ready(function () { 170 // Attendre que QuoteStorage soit disponible 171 const initInterval = setInterval(() => { 172 if (window.QuoteStorage) { 173 clearInterval(initInterval); 174 listenToQuoteEvents(); 175 console.log("â Quote Notifications initialisées"); 176 } 177 }, 100); 178 179 // Timeout après 5 secondes 180 setTimeout(() => { 181 clearInterval(initInterval); 182 }, 5000); 183 }); 184 185 // Exposer la fonction globalement pour utilisation externe 186 window.araticeShowNotification = showNotification; 187})(jQuery); 188
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.