Expense Reimbursement Dashboard

Processing Overview

Reimbursement Pipeline

Spend by Department

Pending Requests Queue

Submit New Expense Report

All Submitted Reports

Report IDEmployeeDepartmentAmountStatusSubmittedAction

Avg. Payment Time

${(paymentTimes.reduce((a,b)=>a+b,0)/paymentTimes.length||0).toFixed(1)} days

`; } const renderChart = (id, type, data, options) => { const ctx = document.getElementById(id)?.getContext('2d'); if(!ctx) return; if(charts[id]) charts[id].destroy(); charts[id] = new Chart(ctx, { type, data, options }); }; function renderCharts(all) { const pipelineCounts = STATUS_LEVELS.slice(0,4).map(status => all.filter(r => r.status === status).length); renderChart('reimb-pipeline-chart', 'bar', { labels: STATUS_LEVELS.slice(0,4), datasets: [{ data: pipelineCounts, backgroundColor: ['#fef3c7', '#e0e7ff', '#cffafe', '#dcfce7'] }] }, { responsive: true, maintainAspectRatio: false, indexAxis: 'y', plugins: { legend: { display: false } } }); const byDept = all.reduce((acc, r) => { acc[r.dept] = (acc[r.dept] || 0) + r.amount; return acc; }, {}); renderChart('reimb-dept-chart', 'doughnut', { labels: Object.keys(byDept), datasets: [{ data: Object.values(byDept) }] }, { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'bottom' } } }); } function renderPendingTable(pending) { document.getElementById('reimb-pending-tbody').innerHTML = pending.map(r => { const nextStatus = STATUS_LEVELS[STATUS_LEVELS.indexOf(r.status) + 1]; const actionBtn = nextStatus && nextStatus !== 'Rejected' ? `` : ''; return `${r.id}${r.name}${r.dept}${new Intl.NumberFormat('en-US',{style:'currency',currency:'USD'}).format(r.amount)}${r.status}${actionBtn}`; }).join(''); } // --- RENDER MANAGEMENT UI --- function renderMasterTable(all) { document.getElementById('reimb-master-tbody').innerHTML = all.map(r => ` ${r.id}${r.name}${r.dept}${new Intl.NumberFormat('en-US',{style:'currency',currency:'USD'}).format(r.amount)} ${r.status} ${new Date(r.dates.Submitted).toLocaleDateString()} `).join(''); } // --- ACTIONS --- window.reimbAddReport = function() { reports.unshift({ id: `EXP-${Date.now() % 10000}`, name: document.getElementById('add-emp-name').value, dept: document.getElementById('add-dept').value, amount: parseFloat(document.getElementById('add-amount').value), status: 'Submitted', dates: { Submitted: new Date().toISOString().split('T')[0] }, }); renderAll(); } function handleActionClick(e) { if (!e.target.matches('.action-btn')) return; const id = e.target.dataset.id; const action = e.target.dataset.action; if (action === 'delete') { reports = reports.filter(r => r.id !== id); } else { const report = reports.find(r => r.id === id); if (report) { report.status = action; report.dates[action] = new Date().toISOString().split('T')[0]; } } renderAll(); } // --- GLOBAL & UTILITY --- window.reimbShowTab = id => { document.querySelectorAll('.reimb-main-tab-content, .reimb-main-tab-button').forEach(el => el.classList.remove('active')); document.getElementById(`reimb-tab-${id}`).classList.add('active'); document.querySelector(`.reimb-main-tab-button[onclick="reimbShowTab('${id}')"]`).classList.add('active'); }; window.reimbDownloadPDF = () => { html2canvas(document.getElementById('reimb-pdf-content'), { scale: 2 }).then(canvas => { const pdf = new jspdf.jsPDF({ orientation: 'landscape', unit: 'pt', format: 'a4' }); pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 40, 40, pdf.internal.pageSize.getWidth() - 80, 0); pdf.save('Expense_Reimbursement_Dashboard.pdf'); }); }; initialize(); });
Scroll to Top