Remote Work Productivity Monitor Remote Work Productivity Monitor Visualize your team's performance and identify key productivity trends. Dashboard Data Configuration Productivity Dashboard Team Performance Overview Team Member Details Team Member Tasks Completed Hours Logged Productivity Score Download Dashboard as PDF Team Data Input Add, edit, or remove team members and their weekly data below. Reporting Period Add Team Member ← Previous Next → ${kpi.label} ${kpi.value} `).join(''); lucide.createIcons(); // Render Chart renderPerformanceChart(); // Render Details Table dom.teamDetailsTable.innerHTML = teamData.map(member => { const productivity = member.hours > 0 ? ((member.tasks / member.hours) * 10).toFixed(1) : 'N/A'; return ` ${member.name} ${member.tasks} ${member.hours} ${productivity} `; }).join(''); } function renderPerformanceChart() { const ctx = document.getElementById('team-performance-chart').getContext('2d'); const labels = teamData.map(m => m.name); const tasksData = teamData.map(m => m.tasks); const hoursData = teamData.map(m => m.hours); if (teamPerformanceChart) { teamPerformanceChart.destroy(); } teamPerformanceChart = new Chart(ctx, { type: 'bar', data: { labels, datasets: [ { label: 'Tasks Completed', data: tasksData, backgroundColor: '#3b82f6', borderColor: '#1e40af', borderWidth: 1, borderRadius: 4, }, { label: 'Hours Logged', data: hoursData, backgroundColor: '#a5b4fc', borderColor: '#4338ca', borderWidth: 1, borderRadius: 4, } ] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true, grid: { color: '#e5e7eb' } }, x: { grid: { display: false } } }, plugins: { legend: { position: 'top' } } } }); } // --- EVENT HANDLERS & DATA MANIPULATION --- function handleDataChange(event) { const id = parseInt(event.target.dataset.id, 10); const field = event.target.dataset.field; const value = field === 'name' ? event.target.value : parseInt(event.target.value, 10) || 0; const memberIndex = teamData.findIndex(m => m.id === id); if (memberIndex > -1) { teamData[memberIndex][field] = value; } renderDashboard(); } function addMember() { const newId = teamData.length > 0 ? Math.max(...teamData.map(m => m.id)) + 1 : 1; teamData.push({ id: newId, name: 'New Member', tasks: 0, hours: 0 }); renderDataConfiguration(); renderDashboard(); } function deleteMember(event) { const id = parseInt(event.currentTarget.dataset.id, 10); teamData = teamData.filter(m => m.id !== id); renderDataConfiguration(); renderDashboard(); } // --- UI & PDF --- window.changeTab = function(tabNumber) { document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active')); document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active')); document.getElementById(`tab-btn-${tabNumber}`).classList.add('active'); document.getElementById(`tab-content-${tabNumber}`).classList.add('active'); dom.navPrev.style.display = (tabNumber === 2) ? 'inline-flex' : 'none'; dom.navNext.style.display = (tabNumber === 1) ? 'inline-flex' : 'none'; } window.downloadPDF = function() { const { jsPDF } = window.jspdf; const pdfElement = document.getElementById('pdf-output'); if (teamPerformanceChart) teamPerformanceChart.options.animation = false; html2canvas(pdfElement, { scale: 2, backgroundColor: '#f0f2f5', onclone: (doc) => { // Re-render lucide icons in the cloned document for canvas capture doc.querySelectorAll('[data-lucide]').forEach(el => { const iconName = el.getAttribute('data-lucide'); if (lucide.icons[iconName]) el.innerHTML = lucide.icons[iconName].toSvg(); }); } }).then(canvas => { if (teamPerformanceChart) teamPerformanceChart.options.animation = true; const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'portrait', unit: 'px', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pageMargin = 40; const contentWidth = pdfWidth - (pageMargin * 2); const canvasRatio = canvas.height / canvas.width; const contentHeight = contentWidth * canvasRatio; pdf.addImage(imgData, 'PNG', pageMargin, pageMargin, contentWidth, contentHeight); pdf.save('Productivity-Report.pdf'); }); } init(); });