Task & Productivity Management Dashboard

Task & Productivity Management Dashboard

Organize, track, and visualize your team's workflow and productivity.

Tasks by Status

Tasks by Priority

Task Board

${task.title}

${task.description}

Due: ${task.dueDate || 'N/A'}

`; card.addEventListener('dragstart', handleDragStart); column.appendChild(card); }); column.addEventListener('dragover', handleDragOver); column.addEventListener('dragleave', handleDragLeave); column.addEventListener('drop', handleDrop); taskBoard.appendChild(column); }); }; const renderCharts = () => { const statusCtx = document.getElementById('statusChart').getContext('2d'); const priorityCtx = document.getElementById('priorityChart').getContext('2d'); const statusCounts = statuses.map(s => tasks.filter(t => t.status === s).length); const priorityCounts = priorities.map(p => tasks.filter(t => t.priority === p).length); if (statusChart) statusChart.destroy(); statusChart = new Chart(statusCtx, { type: 'doughnut', data: { labels: statuses, datasets: [{ data: statusCounts, backgroundColor: ['#60a5fa', '#fbbf24', '#34d399'], // Blue, Amber, Green }] }, options: { responsive: true, maintainAspectRatio: false } }); if (priorityChart) priorityChart.destroy(); priorityChart = new Chart(priorityCtx, { type: 'pie', data: { labels: priorities, datasets: [{ data: priorityCounts, backgroundColor: [priorityColors.Low, priorityColors.Medium, priorityColors.High], }] }, options: { responsive: true, maintainAspectRatio: false } }); }; const renderTaskListEditor = () => { const container = taskListEditor.querySelector('.space-y-2'); container.innerHTML = ''; if (tasks.length === 0) { container.innerHTML = '

No tasks yet. Add one using the form above.

'; return; } tasks.forEach(task => { const el = document.createElement('div'); el.className = 'flex items-center justify-between p-3 bg-gray-50 rounded-md'; el.innerHTML = `

${task.title} (${task.status})

Priority: ${task.priority} | Due: ${task.dueDate || 'N/A'}

`; container.appendChild(el); }); }; // --- EVENT HANDLERS --- // Form Submission (Add/Update) taskForm.addEventListener('submit', (e) => { e.preventDefault(); const idInput = document.getElementById('task-id'); const title = document.getElementById('task-title').value; const description = document.getElementById('task-desc').value; const dueDate = document.getElementById('task-due-date').value; const priority = document.getElementById('task-priority').value; if (idInput.value) { // Update existing task const task = tasks.find(t => t.id == idInput.value); if (task) { task.title = title; task.description = description; task.dueDate = dueDate; task.priority = priority; } } else { // Add new task const newId = tasks.length > 0 ? Math.max(...tasks.map(t => t.id)) + 1 : 1; tasks.push({ id: newId, title, description, dueDate, priority, status: 'To Do' }); } resetForm(); renderAll(); }); // Edit/Delete buttons taskListEditor.addEventListener('click', (e) => { if (e.target.classList.contains('edit-btn')) { const taskId = e.target.dataset.taskId; const task = tasks.find(t => t.id == taskId); if (task) populateFormForEdit(task); } if (e.target.classList.contains('delete-btn')) { const taskId = e.target.dataset.taskId; if (confirm('Are you sure you want to delete this task?')) { tasks = tasks.filter(t => t.id != taskId); renderAll(); } } }); cancelEditBtn.addEventListener('click', resetForm); // Drag and Drop Handlers let draggedItemId = null; function handleDragStart(e) { draggedItemId = e.target.dataset.taskId; e.target.classList.add('dragging'); } function handleDragOver(e) { e.preventDefault(); e.currentTarget.classList.add('drag-over'); } function handleDragLeave(e) { e.currentTarget.classList.remove('drag-over'); } function handleDrop(e) { e.preventDefault(); e.currentTarget.classList.remove('drag-over'); const newStatus = e.currentTarget.dataset.status; const task = tasks.find(t => t.id == draggedItemId); if (task) { task.status = newStatus; document.querySelector('.dragging')?.classList.remove('dragging'); renderAll(); } draggedItemId = null; } // PDF Download downloadPdfBtn.addEventListener('click', () => { const exportArea = document.getElementById('dashboard-export-area'); const mainTitleEl = document.querySelector('#task-tool-container h1'); if (!exportArea || !mainTitleEl) return; const originalBtnText = downloadPdfBtn.innerHTML; downloadPdfBtn.disabled = true; downloadPdfBtn.innerHTML = `Processing...`; html2canvas(exportArea, { scale: 2, useCORS: true, windowWidth: exportArea.scrollWidth, windowHeight: exportArea.scrollHeight }) .then(canvas => { const { jsPDF } = window.jspdf; const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'landscape', unit: 'mm', format: 'a4' }); const pageMargin = 15; const pdfPageWidth = pdf.internal.pageSize.getWidth(); const pdfPageHeight = pdf.internal.pageSize.getHeight(); const pdfContentWidth = pdfPageWidth - (2 * pageMargin); const canvasAspectRatio = canvas.width / canvas.height; const pdfImgHeight = pdfContentWidth / canvasAspectRatio; let yPos = pageMargin; pdf.setFontSize(18).setFont('helvetica', 'bold'); pdf.text(mainTitleEl.innerText, pdfPageWidth / 2, yPos, { align: 'center' }); yPos += 12; let heightLeft = pdfImgHeight; let positionOnCanvas = 0; pdf.addImage(imgData, 'PNG', pageMargin, yPos, pdfContentWidth, pdfImgHeight); heightLeft -= (pdfPageHeight - yPos - pageMargin); while (heightLeft > 0) { positionOnCanvas -= (pdfPageHeight - (2 * pageMargin)); pdf.addPage(); pdf.addImage(imgData, 'PNG', pageMargin, positionOnCanvas + pageMargin, pdfContentWidth, pdfImgHeight); heightLeft -= (pdfPageHeight - (2 * pageMargin)); } pdf.save(`task-dashboard-report-${new Date().toISOString().slice(0,10)}.pdf`); }) .catch(err => { console.error("PDF generation failed:", err); alert("Error generating PDF."); }) .finally(() => { downloadPdfBtn.disabled = false; downloadPdfBtn.innerHTML = originalBtnText; }); }); // --- HELPER FUNCTIONS --- function populateFormForEdit(task) { document.getElementById('task-id').value = task.id; document.getElementById('task-title').value = task.title; document.getElementById('task-desc').value = task.description; document.getElementById('task-due-date').value = task.dueDate; document.getElementById('task-priority').value = task.priority; taskForm.querySelector('button[type="submit"]').textContent = 'Update Task'; cancelEditBtn.classList.remove('hidden'); taskForm.scrollIntoView({ behavior: 'smooth' }); } function resetForm() { taskForm.reset(); document.getElementById('task-id').value = ''; taskForm.querySelector('button[type="submit"]').textContent = 'Add Task'; cancelEditBtn.classList.add('hidden'); } // --- INITIALIZATION --- tabDashboardBtn.addEventListener('click', () => switchTab('dashboard')); tabConfigBtn.addEventListener('click', () => switchTab('config')); prevTabBtn.addEventListener('click', () => switchTab('dashboard')); nextTabBtn.addEventListener('click', () => switchTab('config')); switchTab('dashboard'); renderAll(); });
Scroll to Top