(type, message)
| 16 | } |
| 17 | |
| 18 | function showNotification(type, message) { |
| 19 | // Remove any existing notification |
| 20 | const existingNotification = document.getElementById('notification'); |
| 21 | if (existingNotification) { |
| 22 | existingNotification.remove(); |
| 23 | } |
| 24 | |
| 25 | // Create new notification |
| 26 | const notification = document.createElement('div'); |
| 27 | notification.id = 'notification'; |
| 28 | notification.classList.add( |
| 29 | 'fixed', 'top-24', 'right-4', 'z-50', 'p-4', 'rounded-lg', 'shadow-lg', |
| 30 | 'transform', 'transition-all', 'duration-300', 'ease-in-out', 'translate-y-0', |
| 31 | 'flex', 'items-center', 'gap-2' |
| 32 | ); |
| 33 | |
| 34 | // Style based on notification type |
| 35 | if (type === 'error') { |
| 36 | notification.classList.add('bg-red-900/90', 'border', 'border-red-700', 'text-red-200'); |
| 37 | notification.innerHTML = '<i class="fas fa-circle-exclamation text-red-400 mr-2"></i>' + message; |
| 38 | } else if (type === 'warning') { |
| 39 | notification.classList.add('bg-yellow-900/90', 'border', 'border-yellow-700', 'text-yellow-200'); |
| 40 | notification.innerHTML = '<i class="fas fa-triangle-exclamation text-yellow-400 mr-2"></i>' + message; |
| 41 | } else if (type === 'success') { |
| 42 | notification.classList.add('bg-green-900/90', 'border', 'border-green-700', 'text-green-200'); |
| 43 | notification.innerHTML = '<i class="fas fa-circle-check text-green-400 mr-2"></i>' + message; |
| 44 | } else { |
| 45 | notification.classList.add('bg-blue-900/90', 'border', 'border-blue-700', 'text-blue-200'); |
| 46 | notification.innerHTML = '<i class="fas fa-circle-info text-blue-400 mr-2"></i>' + message; |
| 47 | } |
| 48 | |
| 49 | // Add close button |
| 50 | const closeBtn = document.createElement('button'); |
| 51 | closeBtn.innerHTML = '<i class="fas fa-xmark"></i>'; |
| 52 | closeBtn.classList.add('ml-auto', 'text-gray-400', 'hover:text-white', 'transition-colors'); |
| 53 | closeBtn.onclick = () => { |
| 54 | notification.classList.add('opacity-0', 'translate-y-[-20px]'); |
| 55 | setTimeout(() => notification.remove(), 300); |
| 56 | }; |
| 57 | notification.appendChild(closeBtn); |
| 58 | |
| 59 | // Add to DOM |
| 60 | document.body.appendChild(notification); |
| 61 | |
| 62 | // Animate in |
| 63 | setTimeout(() => { |
| 64 | notification.classList.add('opacity-0', 'translate-y-[-20px]'); |
| 65 | notification.offsetHeight; // Force reflow |
| 66 | notification.classList.remove('opacity-0', 'translate-y-[-20px]'); |
| 67 | }, 10); |
| 68 | |
| 69 | // Auto dismiss after 5 seconds |
| 70 | setTimeout(() => { |
| 71 | if (document.getElementById('notification')) { |
| 72 | notification.classList.add('opacity-0', 'translate-y-[-20px]'); |
| 73 | setTimeout(() => notification.remove(), 300); |
| 74 | } |
| 75 | }, 5000); |
no test coverage detected