diff --git a/src/PowderCoating.Web/Controllers/InvoicesController.cs b/src/PowderCoating.Web/Controllers/InvoicesController.cs index b43ae8b..0d4abef 100644 --- a/src/PowderCoating.Web/Controllers/InvoicesController.cs +++ b/src/PowderCoating.Web/Controllers/InvoicesController.cs @@ -917,7 +917,7 @@ public class InvoicesController : Controller TempData["Success"] = $"Invoice {invoice.InvoiceNumber} marked as sent."; if (!pdfAndNotifSucceeded) - TempData["Warning"] = "The invoice is marked as sent, but PDF generation or the customer email failed. Check the notification logs or your email configuration."; + TempData["WarningPermanent"] = "The invoice is marked as sent, but PDF generation or the customer email failed. Check the notification logs or your email configuration."; return RedirectToAction(nameof(Details), new { id }); } catch (Exception ex) @@ -1302,8 +1302,8 @@ public class InvoicesController : Controller } catch (Exception ex) { - _logger.LogError(ex, "Error generating PDF for invoice {Id}", id); - TempData["Error"] = "An error occurred while generating the PDF."; + _logger.LogError(ex, "Error generating PDF for invoice {Id}. Inner: {Inner}", id, ex.InnerException?.Message ?? ex.Message); + TempData["ErrorPermanent"] = $"PDF generation failed: {ex.Message}"; return RedirectToAction(nameof(Details), new { id }); } } diff --git a/src/PowderCoating.Web/Helpers/ToastHelper.cs b/src/PowderCoating.Web/Helpers/ToastHelper.cs index 9d479a3..22ff16b 100644 --- a/src/PowderCoating.Web/Helpers/ToastHelper.cs +++ b/src/PowderCoating.Web/Helpers/ToastHelper.cs @@ -31,6 +31,9 @@ namespace PowderCoating.Web.Helpers /// TempData key read by the layout to render a yellow warning toast. private const string WarningKey = "Warning"; + /// TempData key read by the layout to render a yellow warning toast that does not auto-dismiss. + private const string WarningPermanentKey = "WarningPermanent"; + /// TempData key read by the layout to render a blue info toast. private const string InfoKey = "Info"; @@ -67,6 +70,15 @@ namespace PowderCoating.Web.Helpers tempData[WarningKey] = message; } + /// + /// Stores a warning (yellow) toast that requires manual dismissal (no auto-timeout). + /// Use for critical warnings the user must not miss, such as email delivery failures. + /// + public static void WarningPermanent(this ITempDataDictionary tempData, string message) + { + tempData[WarningPermanentKey] = message; + } + /// /// Stores an informational (blue) toast message in TempData for display on /// the next page render after a redirect. @@ -123,6 +135,15 @@ namespace PowderCoating.Web.Helpers controller.TempData.Warning(message); } + /// + /// Stores a permanent warning (yellow, no auto-dismiss) in the controller's TempData. + /// Use for failures the user must not miss — email delivery errors, PDF generation failures. + /// + public static void ToastWarningPermanent(this Controller controller, string message) + { + controller.TempData.WarningPermanent(message); + } + /// /// Stores an informational (blue) toast in the controller's TempData. /// Convenience wrapper around . @@ -165,7 +186,7 @@ namespace PowderCoating.Web.Helpers : $"{channel} notification was skipped."); break; case NotificationStatus.Failed: - controller.ToastWarning(!string.IsNullOrEmpty(log.ErrorMessage) + controller.ToastWarningPermanent(!string.IsNullOrEmpty(log.ErrorMessage) ? $"{channel} delivery failed: {log.ErrorMessage}" : $"{channel} notification failed."); break; diff --git a/src/PowderCoating.Web/Views/Shared/_Layout.cshtml b/src/PowderCoating.Web/Views/Shared/_Layout.cshtml index 449d017..fc9a0e2 100644 --- a/src/PowderCoating.Web/Views/Shared/_Layout.cshtml +++ b/src/PowderCoating.Web/Views/Shared/_Layout.cshtml @@ -890,6 +890,10 @@ { } + @if (TempData["WarningPermanent"] != null) + { + + } @if (TempData["Info"] != null) { diff --git a/src/PowderCoating.Web/wwwroot/js/toast-notifications.js b/src/PowderCoating.Web/wwwroot/js/toast-notifications.js index 06087c6..bf85dae 100644 --- a/src/PowderCoating.Web/wwwroot/js/toast-notifications.js +++ b/src/PowderCoating.Web/wwwroot/js/toast-notifications.js @@ -118,6 +118,12 @@ function displayTempDataMessages() { showWarning(warningMsg.textContent.trim()); } + // Permanent warning — no auto-dismiss + const warningPerm = document.getElementById('tempdata-warning-permanent-message'); + if (warningPerm && warningPerm.textContent.trim()) { + toastr.warning(warningPerm.textContent.trim(), 'Warning', { timeOut: 0, extendedTimeOut: 0 }); + } + // Info message const infoMsg = document.getElementById('tempdata-info-message'); if (infoMsg && infoMsg.textContent.trim()) {