NonInventPurchasingSystem/CPRNIMS.WebApps/wwwroot/js/toast-notifications.js
2026-01-20 07:44:30 +08:00

132 lines
4.0 KiB
JavaScript

class ToastManager {
constructor() {
this.container = document.getElementById('toast-container');
this.toastCount = 0;
}
show(type = 'info', message = '', title = '', duration = 4000) {
const toastId = `toast-${++this.toastCount}`;
const icons = {
success: 'fas fa-check-circle',
error: 'fas fa-exclamation-circle',
warning: 'fas fa-exclamation-triangle',
info: 'fas fa-info-circle'
};
const titles = {
success: title || 'Success',
error: title || 'Error',
warning: title || 'Warning',
info: title || 'Information'
};
const toastHTML = `
<div class="toast custom-toast ${type}" id="${toastId}" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<i class="toast-icon ${icons[type]} ${type}"></i>
<strong class="me-auto">${titles[type]}</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">
${message}
</div>
<div class="toast-progress" style="width: 100%"></div>
</div>
`;
this.container.insertAdjacentHTML('afterbegin', toastHTML);
const toastElement = document.getElementById(toastId);
const progressBar = toastElement.querySelector('.toast-progress');
// Show toast
const bsToast = new bootstrap.Toast(toastElement, {
autohide: false // We'll handle auto-hide manually for progress bar
});
bsToast.show();
// Progress bar animation
if (duration > 0) {
setTimeout(() => {
progressBar.style.transition = `width ${duration}ms linear`;
progressBar.style.width = '0%';
}, 100);
// Auto hide
setTimeout(() => {
this.hide(toastElement);
}, duration);
}
// Handle manual close
toastElement.addEventListener('hidden.bs.toast', () => {
toastElement.remove();
});
return toastElement;
}
hide(toastElement) {
toastElement.classList.add('toast-slide-out');
setTimeout(() => {
const bsToast = bootstrap.Toast.getInstance(toastElement);
if (bsToast) {
bsToast.hide();
}
}, 300);
}
success(message, title, duration) {
return this.show('success', message, title, duration);
}
error(message, title, duration) {
return this.show('error', message, title, duration);
}
warning(message, title, duration) {
return this.show('warning', message, title, duration);
}
info(message, title, duration) {
return this.show('info', message, title, duration);
}
clear() {
const toasts = this.container.querySelectorAll('.toast');
toasts.forEach(toast => {
const bsToast = bootstrap.Toast.getInstance(toast);
if (bsToast) {
bsToast.hide();
}
});
}
}
// Create global instance
const toastManager = new ToastManager();
// Global function for easy use
function showToast(type, message, title, duration) {
return toastManager.show(type, message, title, duration);
}
// Convenience functions
function showSuccess(message, title, duration) {
return toastManager.success(message, title, duration);
}
function showError(message, title, duration) {
return toastManager.error(message, title, duration);
}
function showWarning(message, title, duration) {
return toastManager.warning(message, title, duration);
}
function showInfo(message, title, duration) {
return toastManager.info(message, title, duration);
}
function clearAllToasts() {
toastManager.clear();
}