382 lines
8.5 KiB
Markdown
382 lines
8.5 KiB
Markdown
# Toast Notification System - Implementation Guide
|
|
|
|
## Overview
|
|
|
|
A modern, consistent toast notification system has been implemented across the entire application using Toastr.js. This provides better UX for validation errors, success messages, warnings, and informational messages.
|
|
|
|
## Features
|
|
|
|
✅ **Automatic Display**: TempData messages and ModelState errors automatically show as toast notifications
|
|
✅ **Consistent API**: Easy-to-use helper methods for controllers
|
|
✅ **Multiple Types**: Success, Error, Warning, and Info notifications
|
|
✅ **Accessible**: ARIA-compliant and keyboard accessible
|
|
✅ **Responsive**: Works on desktop, tablet, and mobile
|
|
✅ **Themeable**: Integrated with Bootstrap 5 dark/light themes
|
|
|
|
---
|
|
|
|
## For Controllers - Setting Toast Messages
|
|
|
|
### Option 1: Using Extension Methods (Recommended)
|
|
|
|
```csharp
|
|
using PowderCoating.Web.Helpers;
|
|
|
|
public class MyController : Controller
|
|
{
|
|
public IActionResult Create(MyDto dto)
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
// ... save logic ...
|
|
|
|
this.ToastSuccess("Item created successfully!");
|
|
return RedirectToAction(nameof(Index));
|
|
}
|
|
|
|
// Validation errors are automatically shown as toasts
|
|
return View(dto);
|
|
}
|
|
|
|
public IActionResult Delete(int id)
|
|
{
|
|
try
|
|
{
|
|
// ... delete logic ...
|
|
this.ToastSuccess("Item deleted successfully!");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
this.ToastError($"Failed to delete item: {ex.Message}");
|
|
}
|
|
|
|
return RedirectToAction(nameof(Index));
|
|
}
|
|
}
|
|
```
|
|
|
|
### Option 2: Using TempData Directly
|
|
|
|
```csharp
|
|
using PowderCoating.Web.Helpers;
|
|
|
|
// Success
|
|
TempData.Success("Operation completed successfully!");
|
|
|
|
// Error
|
|
TempData.Error("An error occurred while processing your request.");
|
|
|
|
// Warning
|
|
TempData.Warning("This action cannot be undone.");
|
|
|
|
// Info
|
|
TempData.Info("Your changes have been saved as a draft.");
|
|
```
|
|
|
|
### Option 3: Traditional TempData (Still Supported)
|
|
|
|
```csharp
|
|
// Still works - will be displayed as toasts
|
|
TempData["Success"] = "Item saved!";
|
|
TempData["Error"] = "Something went wrong.";
|
|
TempData["Warning"] = "Please review the changes.";
|
|
TempData["Info"] = "New feature available!";
|
|
```
|
|
|
|
---
|
|
|
|
## For Views - Replacing Old Validation Summaries
|
|
|
|
### Old Way (Still Works)
|
|
```html
|
|
<div asp-validation-summary="ModelOnly" class="alert alert-danger"></div>
|
|
```
|
|
|
|
### New Way (Recommended)
|
|
```html
|
|
@* Simple inline indicator - errors show as toasts automatically *@
|
|
<partial name="_ValidationSummary" />
|
|
|
|
@* Or use nothing - ModelState errors auto-show as toasts! *@
|
|
```
|
|
|
|
### Field-Level Validation (Unchanged)
|
|
```html
|
|
@* Field-level validation still works the same *@
|
|
<span asp-validation-for="Name" class="text-danger"></span>
|
|
```
|
|
|
|
---
|
|
|
|
## For JavaScript - Manual Toast Display
|
|
|
|
### Basic Usage
|
|
|
|
```javascript
|
|
// Success
|
|
showSuccess('Changes saved successfully!');
|
|
|
|
// Error
|
|
showError('Failed to load data.');
|
|
|
|
// Warning
|
|
showWarning('Your session will expire in 5 minutes.');
|
|
|
|
// Info
|
|
showInfo('A new version is available.');
|
|
```
|
|
|
|
### With Custom Titles
|
|
|
|
```javascript
|
|
showSuccess('Profile updated!', 'Success');
|
|
showError('Connection lost.', 'Network Error');
|
|
showWarning('Unsaved changes detected.', 'Warning');
|
|
showInfo('New messages available.', 'Notification');
|
|
```
|
|
|
|
### Validation Errors
|
|
|
|
```javascript
|
|
// Single error
|
|
showValidationErrors(['Email is required']);
|
|
|
|
// Multiple errors
|
|
showValidationErrors([
|
|
'Email is required',
|
|
'Password must be at least 8 characters',
|
|
'Terms and conditions must be accepted'
|
|
]);
|
|
```
|
|
|
|
### Clear All Toasts
|
|
|
|
```javascript
|
|
clearAllToasts();
|
|
```
|
|
|
|
---
|
|
|
|
## Configuration
|
|
|
|
Toast behavior is configured in `/wwwroot/js/toast-notifications.js`:
|
|
|
|
```javascript
|
|
toastr.options = {
|
|
"closeButton": true, // Show close button
|
|
"newestOnTop": true, // New toasts appear on top
|
|
"progressBar": true, // Show countdown progress bar
|
|
"positionClass": "toast-top-right", // Position on screen
|
|
"preventDuplicates": true, // Prevent duplicate messages
|
|
"timeOut": "5000", // Auto-close after 5 seconds
|
|
"extendedTimeOut": "1000", // Extended timeout on hover
|
|
// ... more options
|
|
};
|
|
```
|
|
|
|
### Available Positions
|
|
- `toast-top-right` (default)
|
|
- `toast-top-left`
|
|
- `toast-bottom-right`
|
|
- `toast-bottom-left`
|
|
- `toast-top-center`
|
|
- `toast-bottom-center`
|
|
- `toast-top-full-width`
|
|
- `toast-bottom-full-width`
|
|
|
|
---
|
|
|
|
## Migration Guide
|
|
|
|
### 1. Update Controllers
|
|
|
|
**Before:**
|
|
```csharp
|
|
TempData["Success"] = "Item created!";
|
|
```
|
|
|
|
**After:**
|
|
```csharp
|
|
using PowderCoating.Web.Helpers;
|
|
|
|
this.ToastSuccess("Item created!");
|
|
```
|
|
|
|
### 2. Update Views
|
|
|
|
**Before:**
|
|
```html
|
|
@if (TempData["Success"] != null)
|
|
{
|
|
<div class="alert alert-success">@TempData["Success"]</div>
|
|
}
|
|
|
|
<div asp-validation-summary="ModelOnly" class="alert alert-danger"></div>
|
|
```
|
|
|
|
**After:**
|
|
```html
|
|
@* Messages automatically show as toasts - no view code needed! *@
|
|
|
|
@* Optional: Simple validation indicator *@
|
|
<partial name="_ValidationSummary" />
|
|
```
|
|
|
|
### 3. JavaScript AJAX Callbacks
|
|
|
|
**Before:**
|
|
```javascript
|
|
if (result.success) {
|
|
alert('Saved!');
|
|
}
|
|
```
|
|
|
|
**After:**
|
|
```javascript
|
|
if (result.success) {
|
|
showSuccess('Saved successfully!');
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Examples by Scenario
|
|
|
|
### CRUD Operations
|
|
|
|
```csharp
|
|
// Create
|
|
this.ToastSuccess($"'{entity.Name}' created successfully!");
|
|
|
|
// Update
|
|
this.ToastSuccess($"'{entity.Name}' updated successfully!");
|
|
|
|
// Delete
|
|
this.ToastSuccess($"'{entity.Name}' deleted successfully!");
|
|
|
|
// Soft Delete
|
|
this.ToastWarning($"'{entity.Name}' moved to trash.");
|
|
```
|
|
|
|
### Validation Failures
|
|
|
|
```csharp
|
|
// ModelState errors show automatically as toasts
|
|
// Just return the view
|
|
if (!ModelState.IsValid)
|
|
{
|
|
return View(dto);
|
|
}
|
|
```
|
|
|
|
### Business Logic Errors
|
|
|
|
```csharp
|
|
if (customer.CurrentBalance > 0)
|
|
{
|
|
this.ToastError("Cannot delete customer with outstanding balance.");
|
|
return RedirectToAction(nameof(Details), new { id });
|
|
}
|
|
```
|
|
|
|
### Warnings
|
|
|
|
```csharp
|
|
if (item.StockLevel < item.ReorderPoint)
|
|
{
|
|
this.ToastWarning($"Low stock alert: {item.Name} needs reordering.");
|
|
}
|
|
```
|
|
|
|
### Info Messages
|
|
|
|
```csharp
|
|
if (newFeaturesAvailable)
|
|
{
|
|
this.ToastInfo("New features are available! Check the dashboard.");
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Styling & Theming
|
|
|
|
Toast notifications automatically adapt to Bootstrap 5 dark/light themes. Colors are derived from:
|
|
|
|
- **Success**: `--bs-success` (green)
|
|
- **Error**: `--bs-danger` (red)
|
|
- **Warning**: `--bs-warning` (yellow/orange)
|
|
- **Info**: `--bs-info` (blue)
|
|
|
|
---
|
|
|
|
## Accessibility
|
|
|
|
✅ Toast notifications include proper ARIA attributes
|
|
✅ Keyboard accessible (close with ESC key)
|
|
✅ Screen reader friendly
|
|
✅ Respects `prefers-reduced-motion` for animations
|
|
|
|
---
|
|
|
|
## Best Practices
|
|
|
|
### ✅ DO
|
|
|
|
- Use success toasts for completed actions
|
|
- Use error toasts for failures and validation issues
|
|
- Use warning toasts for important information requiring attention
|
|
- Use info toasts for helpful tips and non-critical updates
|
|
- Keep messages concise (1-2 sentences max)
|
|
- Use action-specific messages ("Customer 'Acme Corp' created successfully")
|
|
|
|
### ❌ DON'T
|
|
|
|
- Don't use toasts for critical errors requiring user action (use modals)
|
|
- Don't use toasts for form field validation (use inline validation)
|
|
- Don't chain multiple toasts for the same action
|
|
- Don't use vague messages ("Success!" - what succeeded?)
|
|
- Don't use toasts for loading states (use spinners)
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Toast not appearing?
|
|
|
|
1. Check browser console for JavaScript errors
|
|
2. Verify Toastr library is loaded: Check `<head>` for `toastr.min.css` and `toastr.min.js`
|
|
3. Verify toast-notifications.js is loaded after Toastr
|
|
4. Check that TempData keys are correct: "Success", "Error", "Warning", "Info"
|
|
|
|
### Toast appears twice?
|
|
|
|
- Check that you're not manually displaying AND using TempData
|
|
- Verify the page isn't being loaded twice
|
|
|
|
### Styling issues?
|
|
|
|
- Check for CSS conflicts with custom styles
|
|
- Verify Bootstrap 5 is loaded
|
|
- Check browser console for CSS errors
|
|
|
|
---
|
|
|
|
## Files Modified/Created
|
|
|
|
### New Files
|
|
- `/wwwroot/lib/toastr/` - Toastr library files (via LibMan)
|
|
- `/wwwroot/js/toast-notifications.js` - Toast notification system
|
|
- `/Helpers/ToastHelper.cs` - C# helper methods
|
|
- `/Views/Shared/_ValidationSummary.cshtml` - Modern validation summary partial
|
|
|
|
### Modified Files
|
|
- `/libman.json` - Added Toastr library
|
|
- `/Views/Shared/_Layout.cshtml` - Added Toastr references and TempData containers
|
|
|
|
---
|
|
|
|
## Support & Feedback
|
|
|
|
For questions or issues with the toast notification system, please contact the development team or create an issue in the project repository.
|