// Notification System - Replaces alerts and confirms /** * Show a notification message * @param {string} message - The message to display * @param {string} type - 'success', 'error', 'warning', 'info' * @param {number} duration - Auto-close duration in ms (0 = don't auto-close) */ function showNotification(message, type = 'info', duration = 5000) { const container = document.getElementById('notificationContainer'); if (!container) { console.warn('Notification container not found'); return; } const notification = document.createElement('div'); notification.className = `notification ${type}`; const titles = { success: 'Success', error: 'Error', warning: 'Warning', info: 'Info' }; notification.innerHTML = `
${titles[type] || 'Notification'}
${escapeHtml(message)}
`; container.appendChild(notification); // Auto-remove after duration if (duration > 0) { setTimeout(() => { if (notification.parentElement) { notification.style.animation = 'slideInRight 0.3s ease-out reverse'; setTimeout(() => notification.remove(), 300); } }, duration); } return notification; } /** * Show a confirmation dialog * @param {string} message - The message to display * @param {string} title - The dialog title * @returns {Promise} - Resolves to true if confirmed, false if cancelled */ function showConfirm(message, title = 'Confirm') { return new Promise((resolve) => { const overlay = document.createElement('div'); overlay.className = 'confirm-dialog-overlay'; overlay.innerHTML = `
${escapeHtml(title)}
${escapeHtml(message)}
`; document.body.appendChild(overlay); // Store resolve function globally temporarily window.__confirmResolve__ = resolve; // Close on overlay click (outside dialog) overlay.addEventListener('click', (e) => { if (e.target === overlay) { overlay.remove(); resolve(false); } }); }); } function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } /** * Show a prompt dialog with input field * @param {string} message - The message to display * @param {string} title - The dialog title * @param {string} defaultValue - Default input value * @param {string} placeholder - Input placeholder * @returns {Promise} - Resolves to input value if confirmed, null if cancelled */ function showPrompt(message, title = 'Input', defaultValue = '', placeholder = '') { return new Promise((resolve) => { const overlay = document.createElement('div'); overlay.className = 'confirm-dialog-overlay'; overlay.innerHTML = `
${escapeHtml(title)}
${escapeHtml(message)}
`; document.body.appendChild(overlay); // Store resolve function globally temporarily window.__promptResolve__ = resolve; // Focus input setTimeout(() => { const input = document.getElementById('promptInput'); if (input) { input.focus(); input.select(); } }, 100); // Handle Enter key const input = document.getElementById('promptInput'); if (input) { input.addEventListener('keypress', (e) => { if (e.key === 'Enter') { overlay.remove(); resolve(input.value); } }); } // Close on overlay click (outside dialog) overlay.addEventListener('click', (e) => { if (e.target === overlay) { overlay.remove(); resolve(null); } }); // Handle Escape key const handleEscape = (e) => { if (e.key === 'Escape') { overlay.remove(); resolve(null); document.removeEventListener('keydown', handleEscape); } }; document.addEventListener('keydown', handleEscape); }); } // Make functions globally available window.showNotification = showNotification; window.showConfirm = showConfirm; window.showPrompt = showPrompt;