Weekly Workload Planner
Plan your tasks, balance your workload, and stay productive.
Add a New Task
Total Weekly Hours
0
Your Week Ahead
${task.name}
${task.hours.toFixed(1)} hrs
`;
taskListDiv.appendChild(taskCard);
});
plannerBoard.appendChild(dayColumn);
});
totalHoursSummary.textContent = totalHours.toFixed(1);
const hasTasks = tasks.length > 0;
downloadPdfBtn.disabled = !hasTasks;
clearAllBtn.disabled = !hasTasks;
setupDragAndDropListeners();
}
// SECTION: DRAG & DROP LOGIC
// ==========================
function setupDragAndDropListeners() {
const taskCards = document.querySelectorAll('.task-card');
const dayColumns = document.querySelectorAll('.day-column');
taskCards.forEach(card => {
card.addEventListener('dragstart', (e) => {
draggedTaskId = parseInt(e.target.closest('.task-card').dataset.id);
e.target.classList.add('dragging');
});
card.addEventListener('dragend', (e) => {
e.target.classList.remove('dragging');
draggedTaskId = null;
});
});
dayColumns.forEach(column => {
column.addEventListener('dragover', (e) => {
e.preventDefault();
column.classList.add('drag-over');
});
column.addEventListener('dragleave', (e) => {
column.classList.remove('drag-over');
});
column.addEventListener('drop', (e) => {
e.preventDefault();
column.classList.remove('drag-over');
const newDay = column.dataset.day;
if (draggedTaskId && newDay) {
updateTaskDay(draggedTaskId, newDay);
}
});
});
}
// SECTION: PDF GENERATION
// =======================
function generatePDF() {
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
doc.setFont('helvetica', 'bold');
doc.setFontSize(22);
doc.setTextColor('#1f2937');
doc.text('Weekly Workload Plan', doc.internal.pageSize.getWidth() / 2, 20, { align: 'center' });
const totalHours = tasks.reduce((sum, task) => sum + task.hours, 0);
doc.setFont('helvetica', 'normal');
doc.setFontSize(12);
doc.setTextColor('#6b7280');
doc.text(`Total Estimated Hours: ${totalHours.toFixed(1)}`, doc.internal.pageSize.getWidth() / 2, 28, { align: 'center' });
const tableRows = [];
daysOfWeek.forEach(day => {
const tasksForDay = tasks.filter(task => task.day === day);
if (tasksForDay.length > 0) {
const hoursForDay = tasksForDay.reduce((sum, task) => sum + task.hours, 0);
// Add a header row for the day
tableRows.push([{ content: `${day} (${hoursForDay.toFixed(1)} hrs)`, colSpan: 2, styles: { fontStyle: 'bold', fillColor: '#f3f4f6' } }]);
tasksForDay.forEach(task => {
tableRows.push([task.name, `${task.hours.toFixed(1)} hrs`]);
});
}
});
doc.autoTable({
head: [['Task Description', 'Estimated Hours']],
body: tableRows,
startY: 40,
theme: 'grid',
headStyles: { fillColor: [31, 41, 55], textColor: [255, 255, 255] },
didParseCell: function (data) {
if (data.cell.raw.content && data.cell.raw.colSpan) {
data.cell.styles.halign = 'center';
}
}
});
doc.save(`Weekly_Workload_Plan_${new Date().toISOString().split('T')[0]}.pdf`);
}
// SECTION: EVENT LISTENERS
// ========================
function setupEventListeners() {
addTaskBtn.addEventListener('click', addTask);
clearAllBtn.addEventListener('click', clearAllTasks);
downloadPdfBtn.addEventListener('click', generatePDF);
// Use event delegation for delete buttons
plannerBoard.addEventListener('click', (e) => {
if (e.target.classList.contains('delete-btn')) {
const taskId = parseInt(e.target.dataset.id);
deleteTask(taskId);
}
});
}
// Initial Load
loadState();
setupEventListeners();
});
