/** * Toast Notification System * Requires Bootstrap 5 JS */ function showToast(title, message, type = 'info') { // Create container if not exists let toastContainer = document.getElementById('toast-container'); if (!toastContainer) { toastContainer = document.createElement('div'); toastContainer.id = 'toast-container'; toastContainer.className = 'toast-container position-fixed top-0 end-0 p-3'; toastContainer.style.zIndex = '1100'; document.body.appendChild(toastContainer); } // Inject CSS for transition if not already present if (!document.getElementById('toast-animation-styles')) { const style = document.createElement('style'); style.id = 'toast-animation-styles'; style.innerHTML = ` @keyframes slideInRight { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } .toast-slide-in { animation: slideInRight 0.3s ease-out forwards; } `; document.head.appendChild(style); } // Map type to Bootstrap color class const bgClass = type === 'success' ? 'bg-success' : (type === 'error' || type === 'danger' ? 'bg-danger' : 'bg-info'); // Create toast element const toastEl = document.createElement('div'); toastEl.className = `toast align-items-center text-white ${bgClass} border-0 mb-2 toast-slide-in`; toastEl.setAttribute('role', 'alert'); toastEl.setAttribute('aria-live', 'assertive'); toastEl.setAttribute('aria-atomic', 'true'); toastEl.innerHTML = `
${title}
${message}
`; toastContainer.appendChild(toastEl); // Initialize and show const bsToast = new bootstrap.Toast(toastEl, { autohide: true, delay: 5000 }); bsToast.show(); // Remove from DOM when hidden toastEl.addEventListener('hidden.bs.toast', () => { toastEl.remove(); }); } // Map showNotification to showToast for backward compatibility window.showNotification = function(message, type) { const title = type === 'success' ? 'Success' : (type === 'error' ? 'Error' : 'Notification'); showToast(title, message, type); };