Weekly Work Plan

Weekly Work Plan

Work Plan for: (select a date)

Weekly Priorities / Goals

    Daily Plan

    ${item.duration ? `Dur: ${item.duration}` : ''} Prio: ${item.priority} Status: ${item.status}

    `; ul.appendChild(li); }); ul.querySelectorAll('.edit-daily-item-btn').forEach(btn => btn.addEventListener('click', (e) => { const dayName = dailyPlanGridDiv.querySelector(`.add-daily-item-btn[data-day-id="${e.target.dataset.dayId}"]`)?.dataset.dayName || ""; const fullDate = dailyPlanGridDiv.querySelector(`.add-daily-item-btn[data-day-id="${e.target.dataset.dayId}"]`)?.dataset.fullName || ""; openDailyItemModal(e.target.dataset.dayId, `Edit Item for ${dayName}, ${fullDate}`, e.target.dataset.itemId); })); ul.querySelectorAll('.delete-daily-item-btn').forEach(btn => btn.addEventListener('click', (e) => deleteDailyItem(e.target.dataset.dayId, e.target.dataset.itemId))); } function openDailyItemModal(dayId, title, itemId = null) { dailyItemModalTitle.textContent = title; dailyItemDateInput.value = dayId; // Store the day this item belongs to dailyItemIdInput.value = itemId || ''; currentEditingDailyItemId = itemId; if (itemId) { const item = weeklyPlans[currentSelectedWeekId]?.dailyItems[dayId]?.find(i => i.id === itemId); if (item) { itemDescriptionInput.value = item.description; itemTimeInput.value = item.time || ''; itemDurationInput.value = item.duration || ''; itemPriorityInput.value = item.priority; itemStatusInput.value = item.status; } } else { // Reset for new item itemDescriptionInput.value = ''; itemTimeInput.value = ''; itemDurationInput.value = ''; itemPriorityInput.value = 'medium'; itemStatusInput.value = 'planned'; } dailyItemModal.style.display = 'block'; } closeDailyItemModalBtn.onclick = () => dailyItemModal.style.display = 'none'; saveDailyItemBtn.addEventListener('click', () => { const dayId = dailyItemDateInput.value; const description = itemDescriptionInput.value.trim(); if (!description || !dayId || !currentSelectedWeekId) { alert('Description is required and week/day context must be set.'); return; } const itemData = { id: currentEditingDailyItemId || generateId(), description, time: itemTimeInput.value.trim() || null, duration: itemDurationInput.value.trim() || null, priority: itemPriorityInput.value, status: itemStatusInput.value }; const dayItems = weeklyPlans[currentSelectedWeekId].dailyItems[dayId] || []; if (currentEditingDailyItemId) { const index = dayItems.findIndex(i => i.id === currentEditingDailyItemId); if (index > -1) dayItems[index] = itemData; } else { dayItems.push(itemData); } weeklyPlans[currentSelectedWeekId].dailyItems[dayId] = dayItems; saveCurrentWeekPlan(); renderDailyItemsForDay(dayId); dailyItemModal.style.display = 'none'; currentEditingDailyItemId = null; }); function deleteDailyItem(dayId, itemId) { if (confirm('Delete this item?')) { const dayItems = weeklyPlans[currentSelectedWeekId]?.dailyItems[dayId] || []; weeklyPlans[currentSelectedWeekId].dailyItems[dayId] = dayItems.filter(i => i.id !== itemId); saveCurrentWeekPlan(); renderDailyItemsForDay(dayId); } } // --- Global Actions --- savePlanBtn.addEventListener('click', () => { saveCurrentWeekPlan(); // Explicit save, though auto-save on item changes implemented alert('Weekly plan saved!'); }); clearPlanBtn.addEventListener('click', () => { if (currentSelectedWeekId && confirm(`Are you sure you want to clear the entire plan for week starting ${formatDate(new Date(currentSelectedWeekId+"T00:00:00"))}? This cannot be undone.`)) { delete weeklyPlans[currentSelectedWeekId]; saveCurrentWeekPlan(); // This will save the object without this week's key // Re-load or re-initialize the view for this week const {start} = getWeekRange(new Date(currentSelectedWeekId+"T00:00:00"), parseInt(planWeekStartDaySelect.value)); loadOrCreatePlanForWeek(currentSelectedWeekId, start); } }); // --- PDF Download --- downloadPlanPdfBtn.addEventListener('click', () => { if (!currentSelectedWeekId || !weeklyPlans[currentSelectedWeekId]) { alert('No plan selected or available to download.'); return; } const plan = weeklyPlans[currentSelectedWeekId]; const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'pt', 'a4'); const margin = 40; let yPos = margin; const pageWidth = doc.internal.pageSize.getWidth(); doc.setFontSize(18); doc.setTextColor(varToRGB('--primary-color').r, varToRGB('--primary-color').g, varToRGB('--primary-color').b); doc.text('Weekly Work Plan', pageWidth / 2, yPos, { align: 'center' }); yPos += 20; doc.setFontSize(12); doc.setTextColor(100); doc.text(`Plan for Week: ${formatDate(new Date(plan.weekStartDate+"T00:00:00"))} - ${formatDate(new Date(plan.weekEndDate+"T00:00:00"))}`, pageWidth / 2, yPos, { align: 'center' }); yPos += 15; doc.setFontSize(10); doc.text(`Generated: ${new Date().toLocaleString()}`, pageWidth / 2, yPos, { align: 'center' }); yPos += 25; // Weekly Priorities if (plan.weeklyPriorities.length > 0) { doc.setFontSize(14); doc.setTextColor(varToRGB('--primary-color').r, varToRGB('--primary-color').g, varToRGB('--primary-color').b); doc.text('Weekly Priorities / Goals:', margin, yPos); yPos += 18; doc.setFontSize(10); doc.setTextColor(50); plan.weeklyPriorities.forEach(prio => { const lines = doc.splitTextToSize(`• ${prio.description}`, pageWidth - 2 * margin - 5); if (yPos + lines.length * 12 > doc.internal.pageSize.getHeight() - margin) { doc.addPage(); yPos = margin; } doc.text(lines, margin + 5, yPos); yPos += lines.length * 12 + 3; }); yPos += 10; } // Daily Plan doc.setFontSize(14); doc.setTextColor(varToRGB('--primary-color').r, varToRGB('--primary-color').g, varToRGB('--primary-color').b); doc.text('Daily Plan:', margin, yPos); yPos += 18; const dayNamesForPdf = parseInt(planWeekStartDaySelect.value) === 1 ? ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] : ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; for (let i = 0; i < 7; i++) { const dayDate = new Date(plan.weekStartDate + "T00:00:00"); dayDate.setDate(new Date(plan.weekStartDate + "T00:00:00").getDate() + i); const dayId = getWeekId(dayDate); const items = plan.dailyItems[dayId] || []; items.sort((a,b) => (a.time || "").localeCompare(b.time || "")); if (yPos > doc.internal.pageSize.getHeight() - 60 && items.length > 0) { doc.addPage(); yPos = margin; } doc.setFontSize(12); doc.setTextColor(varToRGB('--dark-text').r, varToRGB('--dark-text').g, varToRGB('--dark-text').b); doc.text(`${dayNamesForPdf[i]}, ${formatDate(dayDate)}`, margin, yPos); yPos += 15; if (items.length > 0) { const body = items.map(item => [ item.time || 'Any Time', item.description, item.duration || 'N/A', item.priority.charAt(0).toUpperCase() + item.priority.slice(1), item.status.charAt(0).toUpperCase() + item.status.slice(1) ]); doc.autoTable({ startY: yPos, head: [['Time', 'Description', 'Duration', 'Priority', 'Status']], body: body, theme: 'grid', headStyles: { fillColor: varToRGB('--primary-color', true), textColor: varToRGB('--light-text', true) }, styles: { fontSize: 9, cellPadding:3 }, columnStyles: { 1: { cellWidth: 'auto' } } // Description column wider }); yPos = doc.lastAutoTable.finalY + 10; } else { doc.setFontSize(9); doc.setTextColor(150); doc.text('No items planned for this day.', margin + 5, yPos); yPos += 12; } yPos += 5; // Space between days } doc.save(`Weekly_Plan_${plan.weekStartDate}_to_${plan.weekEndDate}.pdf`); }); function varToRGB(varName, asArray = false) { const colorHex = getComputedStyle(document.documentElement).getPropertyValue(varName).trim(); if (!colorHex.startsWith('#')) { return asArray ? [0,0,0] : {r:0,g:0,b:0}; } const r = parseInt(colorHex.slice(1, 3), 16); const g = parseInt(colorHex.slice(3, 5), 16); const b = parseInt(colorHex.slice(5, 7), 16); return asArray ? [r,g,b] : {r,g,b}; } // --- Initializations --- const initialWeekStartDate = getWeekStart(today, parseInt(planWeekStartDaySelect.value)); planWeekPicker.value = getWeekId(initialWeekStartDate); // Set date picker to start of current week selectAndDisplayWeek(initialWeekStartDate); // Load and display the plan for initially selected week })();
    Scroll to Top