Online Store Performance Dashboard

Online Store Performance

Analyze sales, orders, and customer behavior.

Performance Overview

Revenue Over Time

Top Selling Products

Recent Orders

Date Order ID Product Name Category Amount

Enter Order Data

${totalOrders.toLocaleString()}

Avg. Order Value

${formatCurrency(avgOrderValue)}

Conversion Rate

${conversionRate.toFixed(2)}%

`; }; const renderDataTable = () => { dataTableBody.innerHTML = ''; const sortedOrders = [...state.orders].sort((a, b) => new Date(b.date) - new Date(a.date)); sortedOrders.forEach(order => { const row = ` ${order.date} #${1000 + order.id} ${order.productName} ${order.category} ${formatCurrency(order.price * order.quantity)} `; dataTableBody.innerHTML += row; }); }; const renderCharts = () => { // Revenue Trend Chart const revenueByDate = state.orders.reduce((acc, order) => { const revenue = order.price * order.quantity; acc[order.date] = (acc[order.date] || 0) + revenue; return acc; }, {}); const sortedDates = Object.keys(revenueByDate).sort((a, b) => new Date(a) - new Date(b)); if (revenueChart) revenueChart.destroy(); revenueChart = new Chart(revenueCanvas.getContext('2d'), { type: 'line', data: { labels: sortedDates, datasets: [{ label: 'Revenue', data: sortedDates.map(date => revenueByDate[date]), borderColor: '#8b5cf6', backgroundColor: 'rgba(139, 92, 246, 0.1)', fill: true, tension: 0.1 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } }, scales: { x: { type: 'time', time: { unit: 'day' } }, y: { beginAtZero: true, ticks: { callback: (value) => formatCurrency(value) } } } } }); // Top Selling Products Chart const salesByProduct = state.orders.reduce((acc, order) => { acc[order.productName] = (acc[order.productName] || 0) + order.quantity; return acc; }, {}); const sortedProducts = Object.entries(salesByProduct).sort((a, b) => b[1] - a[1]).slice(0, 5); const productLabels = sortedProducts.map(p => p[0]); const productData = sortedProducts.map(p => p[1]); if (productsChart) productsChart.destroy(); productsChart = new Chart(productsCanvas.getContext('2d'), { type: 'bar', data: { labels: productLabels, datasets: [{ label: 'Units Sold', data: productData, backgroundColor: ['#a78bfa', '#c4b5fd', '#ddd6fe', '#ede9fe', '#f5f3ff'] }] }, options: { indexAxis: 'y', responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } } } }); }; const renderConfigRows = () => { configRowsContainer.innerHTML = ''; const sortedOrders = [...state.orders].sort((a, b) => new Date(b.date) - new Date(a.date)); sortedOrders.forEach(order => { const row = `
`; configRowsContainer.innerHTML += row; }); addConfigEventListeners(); }; // --- EVENT HANDLERS --- const handleConfigChange = (e) => { const id = parseInt(e.target.dataset.id); const field = e.target.dataset.field; const value = (e.target.type === 'number') ? parseFloat(e.target.value) || 0 : e.target.value; const order = state.orders.find(o => o.id === id); if (order) order[field] = value; renderAll(); }; const handleAddOrder = () => { const newId = state.orders.length > 0 ? Math.max(...state.orders.map(o => o.id)) + 1 : 1; const today = new Date().toISOString().split('T')[0]; state.orders.push({ id: newId, date: today, productName: "New Product", category: "General", price: 0, quantity: 1 }); renderAll(); }; const handleRemoveOrder = (e) => { const id = parseInt(e.target.dataset.id); state.orders = state.orders.filter(o => o.id !== id); renderAll(); }; const addConfigEventListeners = () => { document.querySelectorAll('.config-input').forEach(input => input.addEventListener('change', handleConfigChange)); document.querySelectorAll('.remove-order-btn').forEach(button => button.addEventListener('click', handleRemoveOrder)); }; const handleDownloadPdf = () => { const { jsPDF } = window.jspdf; const pdfContent = document.getElementById('pdf-content'); document.querySelectorAll('.no-print').forEach(el => el.style.visibility = 'hidden'); Chart.defaults.animation = false; html2canvas(pdfContent, { scale: 2, useCORS: true, backgroundColor: '#ffffff' }).then(canvas => { document.querySelectorAll('.no-print').forEach(el => el.style.visibility = 'visible'); Chart.defaults.animation = true; const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const imgWidth = pdfWidth - 20; const imgHeight = canvas.height * imgWidth / canvas.width; pdf.addImage(imgData, 'PNG', 10, 10, imgWidth, imgHeight); pdf.save('Online-Store-Performance.pdf'); }); }; // --- TABBING LOGIC --- let currentTabIndex = 0; const updateTabButtons = () => { prevTabBtn.disabled = currentTabIndex === 0; nextTabBtn.disabled = currentTabIndex === tabContents.length - 1; }; const switchTab = (index) => { tabButtons.forEach(btn => btn.classList.remove('active')); tabContents.forEach(content => content.classList.remove('active')); tabButtons[index].classList.add('active'); tabContents[index].classList.add('active'); currentTabIndex = index; updateTabButtons(); }; tabButtons.forEach((button, index) => button.addEventListener('click', () => switchTab(index))); prevTabBtn.addEventListener('click', () => { if (currentTabIndex > 0) switchTab(currentTabIndex - 1); }); nextTabBtn.addEventListener('click', () => { if (currentTabIndex < tabContents.length - 1) switchTab(currentTabIndex + 1); }); // --- INITIALIZATION --- if (kpiCardsContainer && addOrderBtn && downloadPdfBtn) { addOrderBtn.addEventListener('click', handleAddOrder); downloadPdfBtn.addEventListener('click', handleDownloadPdf); renderAll(); updateTabButtons(); } else { console.error("Essential dashboard elements could not be found."); } });
Scroll to Top