updated alert modal, fixed vendor view history

This commit is contained in:
ssbg04 committed 2026-05-10 01:47:36 +08:00
1 parent 0b91856248
commit cb0dcbe3d1
8 files changed
+282 -156

No files matched your search

+16 -1
View File
@@ -434,7 +434,22 @@ $(document).ready(function () {
</tr>`;
});
$("#lowStockTableBody").html(rows);
setTimeout(() => { $("#lowStockModal").modal("show"); }, 500);
// Replace modal with notification
setTimeout(() => {
if ('Notification' in window) {
Notification.requestPermission().then(permission => {
if (permission === 'granted') {
new Notification('Low Stock Alert!', {
body: 'Items below reorder level detected',
tag: 'lowStockAlert'
});
}
});
} else {
// Fallback to alert if notifications not supported
alert('Low Stock Alert! Items below reorder level detected');
}
}, 500);
}
}
+14 -2
View File
@@ -245,7 +245,6 @@ $(document).ready(function () {
});
});
// --- 5. Low Stock Alerts ---
function checkAndShowLowStockAlert(inventoryData) {
let lowStockItems = inventoryData.filter(item => parseInt(item.quantity) <= parseInt(item.reorder_level));
@@ -260,10 +259,23 @@ $(document).ready(function () {
</tr>`;
});
$("#lowStockTableBody").html(rows);
setTimeout(() => { $("#lowStockModal").modal("show"); }, 500);
// Show premium notification instead of modal
showNotification({
title: 'Low Stock Alert!',
message: `${lowStockItems.length} items are below reorder level.`,
type: 'danger',
icon: 'bi-exclamation-triangle-fill',
action: {
label: 'View & Restock',
callback: 'viewLowStock()'
}
});
}
}
$(document).on("click", "#manualRestockBtn", function() {
$("#lowStockModal").modal("hide");
switchTab('po');
+67 -14
View File
@@ -24,25 +24,78 @@ let spendChartInstance = null;
// ==========================================
// 2. GLOBAL HELPER FUNCTIONS
// ==========================================
function showAlert(msg, type) {
// Create a unique ID for this alert so the timer doesn't accidentally hide a newer alert
let alertId = 'alert-' + Date.now();
function showAlert(msg, type = 'info') {
const toastId = 'toast-' + Date.now();
const iconMap = {
'success': 'bi-check-circle-fill',
'danger': 'bi-exclamation-octagon-fill',
'warning': 'bi-exclamation-triangle-fill',
'info': 'bi-info-circle-fill'
};
const icon = iconMap[type] || 'bi-bell-fill';
const title = type.charAt(0).toUpperCase() + type.slice(1);
$("#alertBox").html(`
<div id="${alertId}" class="alert alert-${type} alert-dismissible fade show border-0 shadow-sm" style="z-index: 1050;">
${msg}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
const toastHtml = `
<div id="${toastId}" class="toast toast-custom toast-${type} fade hide" role="alert" aria-live="assertive" aria-atomic="true" data-bs-autohide="false">
<div class="toast-header toast-header-custom">
<i class="bi ${icon} text-${type} me-2"></i>
<strong class="me-auto text-${type}">${title}</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body toast-body-custom">
${msg}
</div>
</div>
`);
`;
// Auto-hide the alert after 4 seconds (4000 milliseconds)
setTimeout(function() {
$("#" + alertId).fadeOut(400, function() {
$(this).remove(); // Completely removes it from the screen
});
}, 4000);
$("#toastContainer").append(toastHtml);
const toastElement = document.getElementById(toastId);
const toast = new bootstrap.Toast(toastElement, { autohide: false });
toast.show();
toastElement.addEventListener('hidden.bs.toast', function () {
$(this).remove();
});
}
// Global function for complex notifications (with buttons/links)
function showNotification(options) {
const toastId = 'notif-' + Date.now();
const type = options.type || 'info';
const icon = options.icon || 'bi-bell-fill';
const toastHtml = `
<div id="${toastId}" class="toast toast-custom toast-${type} fade hide" role="alert" aria-live="assertive" aria-atomic="true" data-bs-autohide="false" style="min-width: 300px;">
<div class="toast-header toast-header-custom">
<i class="bi ${icon} text-${type} me-2"></i>
<strong class="me-auto text-${type}">${options.title || 'Notification'}</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body toast-body-custom">
<div class="mb-2">${options.message}</div>
${options.action ? `<button class="btn btn-sm btn-${type} rounded-pill px-3 mt-2" onclick="${options.action.callback}">${options.action.label}</button>` : ''}
</div>
</div>
`;
$("#toastContainer").append(toastHtml);
const toastElement = document.getElementById(toastId);
const toast = new bootstrap.Toast(toastElement, { autohide: false });
toast.show();
toastElement.addEventListener('hidden.bs.toast', function () {
$(this).remove();
});
}
// Dedicated function for opening low stock modal
window.viewLowStock = function() {
$("#lowStockModal").modal("show");
};
// ==========================================
// 3. SPA LAZY LOADING ROUTER
// ==========================================