', {
id: 'easy-invoice-toast-container',
class: 'fixed top-4 right-4 z-50 space-y-2 max-w-sm w-full'
});
$('body').append(toastContainer);
}
/**
* Show a toast notification
*
* @param {string} type - success, error, warning, info
* @param {string} message - The message to display
* @param {object} options - Additional options
*/
function show(type, message, options = {}) {
const config = {
duration: options.duration || TOAST_CONFIG.duration,
autoHide: options.autoHide !== false,
dismissible: options.dismissible !== false,
...options
};
// Validate type
if (!TOAST_TYPES[type]) {
type = 'info';
}
const toastId = 'toast-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9);
const toastType = TOAST_TYPES[type];
// Create toast element
const toast = $('
', {
id: toastId,
class: `easy-invoice-toast ${toastType.bgColor} ${toastType.borderColor} border rounded-lg p-4 shadow-lg transform transition-all duration-300 ease-in-out translate-x-full opacity-0`,
html: `
${config.dismissible ? `
` : ''}
`
});
// Add to container
toastContainer.append(toast);
// Store toast info
const toastInfo = {
id: toastId,
element: toast,
type: type,
message: message,
created: Date.now(),
autoHide: config.autoHide,
duration: config.duration
};
activeToasts.push(toastInfo);
// Limit number of toasts
if (activeToasts.length > TOAST_CONFIG.maxToasts) {
const oldestToast = activeToasts.shift();
hideToast(oldestToast.id);
}
// Animate in
setTimeout(function() {
toast.removeClass('translate-x-full opacity-0').addClass('translate-x-0 opacity-100');
}, 10);
// Handle close button
if (config.dismissible) {
toast.find('.toast-close').on('click', function() {
hideToast(toastId);
});
}
// Auto-hide if enabled
if (config.autoHide && config.duration > 0) {
setTimeout(function() {
hideToast(toastId);
}, config.duration);
}
return toastId;
}
/**
* Hide a specific toast
*
* @param {string} toastId - The ID of the toast to hide
*/
function hideToast(toastId) {
const toastIndex = activeToasts.findIndex(t => t.id === toastId);
if (toastIndex === -1) return;
const toast = activeToasts[toastIndex];
// Animate out
toast.element.addClass('translate-x-full opacity-0');
setTimeout(function() {
toast.element.remove();
activeToasts.splice(toastIndex, 1);
}, 300);
}
/**
* Hide all toasts
*/
function hideAll() {
activeToasts.forEach(function(toast) {
hideToast(toast.id);
});
}
/**
* Show success toast
*/
function success(message, options = {}) {
return show('success', message, options);
}
/**
* Show error toast
*/
function error(message, options = {}) {
return show('error', message, options);
}
/**
* Show warning toast
*/
function warning(message, options = {}) {
return show('warning', message, options);
}
/**
* Show info toast
*/
function info(message, options = {}) {
return show('info', message, options);
}
// Initialize when DOM is ready
$(document).ready(function() {
init();
});
// Expose the toast API globally
window.EasyInvoiceToast = {
show: show,
success: success,
error: error,
warning: warning,
info: info,
hide: hideToast,
hideAll: hideAll
};
// Temporarily disable alert override to prevent errors
// window.originalAlert = window.alert;
// window.alert = function(message) {
// EasyInvoiceToast.info(message, { duration: 4000 });
// };
// Global AJAX response handler for toast notifications
$(document).ajaxSuccess(function(event, xhr, settings) {
try {
const response = JSON.parse(xhr.responseText);
// Check if response contains toast data
if (response.data && response.data.toast) {
const toast = response.data.toast;
const options = toast.options || {};
switch (toast.type) {
case 'success':
EasyInvoiceToast.success(toast.message, options);
break;
case 'error':
EasyInvoiceToast.error(toast.message, options);
break;
case 'warning':
EasyInvoiceToast.warning(toast.message, options);
break;
case 'info':
EasyInvoiceToast.info(toast.message, options);
break;
}
}
} catch (e) {
// Response is not JSON or doesn't contain toast data
}
});
$(document).ajaxError(function(event, xhr, settings, error) {
// Show error toast for failed AJAX requests
if (xhr.status !== 0) { // Don't show for aborted requests
EasyInvoiceToast.error('Request failed. Please try again.', { duration: 5000 });
}
});
})(jQuery);