Stock-out Analysis Dashboard

Stock-out Analysis Dashboard

Stock-out Overview

Loading dashboard data...

No product data available. Go to "Data Configuration" to add products.

'; return; } // Start building the HTML for the dashboard table let tableHtml = ` `; // Iterate through each product to create a table row products.forEach(product => { const daysUntilStockOutDisplay = product.daysUntilStockOut === 'N/A' ? 'N/A' : `${product.daysUntilStockOut} days`; // Apply a red background class if stock-out is imminent (daysUntilStockOut <= leadTime) const stockOutStatusClass = product.daysUntilStockOut !== 'N/A' && product.daysUntilStockOut <= product.leadTime ? 'bg-red-100 text-red-800 font-semibold' : ''; tableHtml += ` `; }); tableHtml += `
Product Name Current Stock Avg. Daily Sales Lead Time (Days) Days Until Stock-out Reorder Point Safety Stock
${product.name} ${product.currentStock} ${product.avgDailySales} ${product.leadTime} ${daysUntilStockOutDisplay} ${product.reorderPoint} ${product.safetyStock}
`; dashboardOutput.innerHTML = tableHtml; // Insert the generated table HTML into the dashboard output div } // --- Event Listeners --- // Tab button click listeners dashboardTabBtn.addEventListener('click', () => switchTab('dashboard')); dataConfigTabBtn.addEventListener('click', () => { switchTab('dataConfig'); loadProductInputs(); // Load current product data into input fields when switching to config tab }); // Add Product button listener addProductBtn.addEventListener('click', () => addProductInput()); // Calculate & Update Dashboard button listener calculateBtn.addEventListener('click', () => { calculateMetrics(); // Recalculate metrics based on current inputs renderDashboard(); // Re-render the dashboard with updated metrics switchTab('dashboard'); // Switch back to the dashboard tab to show results }); // Previous Tab button listener prevTabBtn.addEventListener('click', () => { if (activeTab === 'dataConfig') { switchTab('dashboard'); } }); // Next Tab button listener nextTabBtn.addEventListener('click', () => { if (activeTab === 'dashboard') { switchTab('dataConfig'); loadProductInputs(); // Load inputs when moving to data config } }); // PDF Download Button Listener downloadPdfBtn.addEventListener('click', function() { // List of elements to hide before capturing the dashboard for PDF // These are UI elements not relevant to the dashboard content itself in the PDF const elementsToHide = [ stockOutToolContainer.querySelector('h1'), // Main tool title stockOutToolContainer.querySelector('.flex.justify-center.mb-6'), // Tab navigation buttons stockOutToolContainer.querySelector('.flex.justify-center.mt-6').children[0], // The PDF download button itself stockOutToolContainer.querySelector('.flex.justify-center.space-x-4.mt-6') // Previous/Next navigation buttons ]; // Temporarily hide these elements elementsToHide.forEach(el => el && el.classList.add('hidden')); // Temporarily make the dashboard content visible if it's currently hidden // This ensures html2canvas captures the correct content even if the user is on the Data Config tab const wasHidden = dashboardTabContent.classList.contains('hidden'); if (wasHidden) { dashboardTabContent.classList.remove('hidden'); } // Use html2canvas to capture the dashboard output section as an image html2canvas(dashboardOutput, { scale: 2, // Increase scale for higher resolution in the PDF useCORS: true, // Important if any external images were used (not applicable here, but good practice) scrollX: -window.scrollX, // Adjust for horizontal scroll position scrollY: -window.scrollY, // Adjust for vertical scroll position windowWidth: document.documentElement.offsetWidth, // Capture full window width windowHeight: document.documentElement.offsetHeight // Capture full window height }).then(canvas => { const { jsPDF } = window.jspdf; // Get jsPDF object from window scope const imgData = canvas.toDataURL('image/png'); // Convert canvas to PNG image data URL const pdf = new jsPDF('p', 'mm', 'a4'); // Create new PDF document (portrait, mm units, A4 size) const imgWidth = 210; // A4 width in mm const pageHeight = 297; // A4 height in mm const imgHeight = canvas.height * imgWidth / canvas.width; // Calculate image height to maintain aspect ratio let heightLeft = imgHeight; // Remaining height to be added to PDF // Add the first page of the image to the PDF pdf.addImage(imgData, 'PNG', 0, 0, imgWidth, imgHeight); heightLeft -= pageHeight; // If content spans multiple pages, add new pages while (heightLeft >= 0) { pdf.addPage(); // Add a new page // Position the image correctly for multi-page content pdf.addImage(imgData, 'PNG', 0, heightLeft - imgHeight, imgWidth, imgHeight); heightLeft -= pageHeight; } pdf.save('stock-out-analysis-dashboard.pdf'); // Save the PDF file }).catch(error => { console.error("Error generating PDF:", error); // Log any errors during PDF generation }).finally(() => { // Always restore hidden elements and tab visibility, even if PDF generation fails elementsToHide.forEach(el => el && el.classList.remove('hidden')); if (wasHidden) { dashboardTabContent.classList.add('hidden'); } }); }); // --- Initial Setup on Load --- // Calculate initial metrics for the sample data calculateMetrics(); // Render the dashboard with the initial data renderDashboard(); // Load the sample product data into the configuration inputs loadProductInputs(); // Set the initial active tab to 'Dashboard' switchTab('dashboard'); });
Scroll to Top