/** * Toast Notification System * Provides consistent, user-friendly notifications across the application * Uses Toastr library with Bootstrap 5 theming */ // Configure Toastr global options toastr.options = { "closeButton": true, "debug": false, "newestOnTop": true, "progressBar": true, "positionClass": "toast-top-right", "preventDuplicates": true, "onclick": null, "showDuration": "300", "hideDuration": "1000", "timeOut": "5000", "extendedTimeOut": "1000", "showEasing": "swing", "hideEasing": "linear", "showMethod": "fadeIn", "hideMethod": "fadeOut" }; /** * Show success toast notification * @param {string} message - The success message to display * @param {string} title - Optional title for the toast */ function showSuccess(message, title = 'Success') { toastr.success(message, title); } /** * Show error toast notification * @param {string} message - The error message to display * @param {string} title - Optional title for the toast */ function showError(message, title = 'Error') { toastr.error(message, title); } /** * Show warning toast notification * @param {string} message - The warning message to display * @param {string} title - Optional title for the toast */ function showWarning(message, title = 'Warning') { toastr.warning(message, title); } /** * Show info toast notification * @param {string} message - The info message to display * @param {string} title - Optional title for the toast */ function showInfo(message, title = 'Info') { toastr.info(message, title); } /** * Show validation errors from ModelState * @param {Array} errors - Array of validation error messages */ function showValidationErrors(errors) { if (!errors || errors.length === 0) return; // If single error, show it directly if (errors.length === 1) { showError(errors[0], 'Validation Error'); return; } // Multiple errors - show as a list const errorList = ''; toastr.error(errorList, `${errors.length} Validation Errors`, { timeOut: 8000, extendedTimeOut: 2000 }); } /** * Display TempData messages automatically on page load * Expects TempData keys: Success, Error, Warning, Info */ function displayTempDataMessages() { // Success message const successMsg = document.getElementById('tempdata-success-message'); if (successMsg && successMsg.textContent.trim()) { showSuccess(successMsg.textContent.trim()); } // Error message const errorMsg = document.getElementById('tempdata-error-message'); if (errorMsg && errorMsg.textContent.trim()) { showError(errorMsg.textContent.trim()); } // Permanent success — no auto-dismiss const successPerm = document.getElementById('tempdata-success-permanent-message'); if (successPerm && successPerm.textContent.trim()) { toastr.success(successPerm.textContent.trim(), 'Success', { timeOut: 0, extendedTimeOut: 0 }); } // Permanent error — no auto-dismiss const errorPerm = document.getElementById('tempdata-error-permanent-message'); if (errorPerm && errorPerm.textContent.trim()) { toastr.error(errorPerm.textContent.trim(), 'Error', { timeOut: 0, extendedTimeOut: 0 }); } // Warning message const warningMsg = document.getElementById('tempdata-warning-message'); if (warningMsg && warningMsg.textContent.trim()) { showWarning(warningMsg.textContent.trim()); } // Info message const infoMsg = document.getElementById('tempdata-info-message'); if (infoMsg && infoMsg.textContent.trim()) { showInfo(infoMsg.textContent.trim()); } } /** * Display ModelState validation errors on page load * Expects a hidden div with id 'modelstate-errors' containing JSON array of errors */ function displayModelStateErrors() { const errorContainer = document.getElementById('modelstate-errors'); if (errorContainer && errorContainer.textContent.trim()) { try { const errors = JSON.parse(errorContainer.textContent); showValidationErrors(errors); } catch (e) { console.error('Failed to parse ModelState errors:', e); } } } /** * Escape HTML to prevent XSS * @param {string} text - Text to escape * @returns {string} - Escaped text */ function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } /** * Clear all toasts */ function clearAllToasts() { toastr.clear(); } // Auto-initialize on page load document.addEventListener('DOMContentLoaded', function() { displayTempDataMessages(); displayModelStateErrors(); }); // Make functions globally available window.showSuccess = showSuccess; window.showError = showError; window.showWarning = showWarning; window.showInfo = showInfo; window.showValidationErrors = showValidationErrors; window.clearAllToasts = clearAllToasts;