Work Routine Optimizer
General Work Hours
Define Time Block Types
Create Daily Template Schedule
Tasks for Date
Scheduled Routine for Date
Work Routine Optimization Guide
- 1. Understand Your Energy Levels
- Identify times of the day when you are most alert and focused (for "Focus Work") and when you might be better suited for lighter tasks ("Admin/Emails") or meetings.
- 2. Time Blocking
- Allocate specific blocks of time for specific types of tasks. The "Daily Template" helps you do this. Stick to your blocks as much as possible.
- 3. Prioritize ruthlessly
- Use the priority field for tasks. When scheduling, try to fit high-priority items into your most productive blocks.
- 4. Estimate Task Durations
- Accurately estimating how long tasks will take is crucial for effective scheduling. Be realistic and add a small buffer if unsure. This tool helps you see if you're overcommitting time in a block.
- 5. Batch Similar Tasks
- Group similar tasks together (e.g., do all email responses in one "Admin" block). This reduces context switching and improves efficiency.
- 6. Include Breaks
- Don't forget to schedule short breaks throughout your day. Define a "Break" block type. Regular breaks prevent burnout and can actually increase overall productivity (e.g., Pomodoro Technique).
- 7. Minimize Distractions
- During "Focus Work" blocks, try to minimize interruptions. Turn off notifications or find a quiet space.
- 8. Review and Adjust
- Your ideal routine might take time to perfect. At the end of each day or week, review what worked and what didn't. Adjust your `Daily Template` or task categorization in the `Settings & Template` tab as needed.
- 9. Single Task Focus
- While a block might contain multiple small tasks of the same type, try to focus on completing one task before moving to the next, especially during "Focus Work" blocks.
×
Add Task for Day
×
Assign Tasks to Block
No tasks assigned to this block.
${wroFormatTime(blockInstance.startTime)} - ${wroFormatTime(blockInstance.endTime)}
${blockInstance.name || (blockType ? blockType.name : 'Block')}
${capacityText}
${tasksHTML}
`;
wroDailyScheduleOutputEl.appendChild(blockDiv);
});
}
window.wroOpenAssignTaskModal = function(blockInstanceId) {
const selectedDateKey = wroSelectedDateInput.value;
if (!selectedDateKey || !wroDailySchedules[selectedDateKey]) return;
const blockInstance = wroDailySchedules[selectedDateKey].scheduledBlocks.find(b => b.id === blockInstanceId);
if (!blockInstance) return;
wroAssignTargetBlockInstanceIdInput.value = blockInstanceId;
wroAssignTaskModalTitleEl.textContent = `Assign Tasks to: ${blockInstance.name || 'Block'} (${wroFormatTime(blockInstance.startTime)}-${wroFormatTime(blockInstance.endTime)})`;
wroAssignableTasksListEl.innerHTML = '';
const dayTasks = wroDailySchedules[selectedDateKey].dayTasksList;
const assignableTasks = dayTasks.filter(task =>
!wroIsTaskAssignedToAnyBlock(task.id, selectedDateKey) && // Not already assigned to *any* block
(task.taskTypeId === blockInstance.blockTypeId || !blockInstance.blockTypeId) // Match block type or if block has no type
);
if (assignableTasks.length === 0) {
wroAssignableTasksListEl.innerHTML = 'No suitable unassigned tasks available for this block type, or all tasks are already scheduled.
'; } else { assignableTasks.forEach(task => { const div = document.createElement('div'); div.innerHTML = ``; wroAssignableTasksListEl.appendChild(div); }); } wroAssignTaskModalEl.style.display = 'block'; } function wroIsTaskAssignedToAnyBlock(taskId, dateKey) { if (!wroDailySchedules[dateKey] || !wroDailySchedules[dateKey].scheduledBlocks) return false; return wroDailySchedules[dateKey].scheduledBlocks.some(block => block.tasks.includes(taskId)); } window.wroConfirmTaskAssignment = function() { const selectedDateKey = wroSelectedDateInput.value; const blockInstanceId = wroAssignTargetBlockInstanceIdInput.value; if (!selectedDateKey || !blockInstanceId || !wroDailySchedules[selectedDateKey]) return; const blockInstance = wroDailySchedules[selectedDateKey].scheduledBlocks.find(b => b.id === blockInstanceId); if (!blockInstance) return; const selectedTaskCheckboxes = wroAssignableTasksListEl.querySelectorAll('input[name="assignableTask"]:checked'); let assignedTaskTotalTime = blockInstance.tasks.reduce((sum, tid) => { const task = wroDailySchedules[selectedDateKey].dayTasksList.find(t => t.id === tid); return sum + (task ? task.estimatedTimeMinutes : 0); }, 0); const blockDuration = wroTimeDiffInMinutes(blockInstance.startTime, blockInstance.endTime); selectedTaskCheckboxes.forEach(checkbox => { const taskId = checkbox.value; const taskToAdd = wroDailySchedules[selectedDateKey].dayTasksList.find(t => t.id === taskId); if (taskToAdd && (assignedTaskTotalTime + taskToAdd.estimatedTimeMinutes <= blockDuration)) { if (!blockInstance.tasks.includes(taskId)) { blockInstance.tasks.push(taskId); assignedTaskTotalTime += taskToAdd.estimatedTimeMinutes; } } else if (taskToAdd) { alert(`Cannot add task "${taskToAdd.name}". Exceeds block capacity of ${blockDuration} minutes.`); } }); wroSaveDailySchedule(selectedDateKey); wroRenderDayTasksList(selectedDateKey); // To update if any tasks are now visually "scheduled" wroRenderDailyScheduleView(selectedDateKey); wroCloseModal('wroAssignTaskModal'); } window.wroUnassignTaskFromBlock = function(blockInstanceId, taskId) { const selectedDateKey = wroSelectedDateInput.value; if (!selectedDateKey || !blockInstanceId || !taskId || !wroDailySchedules[selectedDateKey]) return; const blockInstance = wroDailySchedules[selectedDateKey].scheduledBlocks.find(b => b.id === blockInstanceId); if (blockInstance) { blockInstance.tasks = blockInstance.tasks.filter(id => id !== taskId); wroSaveDailySchedule(selectedDateKey); wroRenderDailyScheduleView(selectedDateKey); wroRenderDayTasksList(selectedDateKey); // Refresh tasks list too } } // --- PDF Export --- if(wroDownloadPdfBtn) wroDownloadPdfBtn.addEventListener('click', function() { const selectedDateKey = wroSelectedDateInput.value; if (!selectedDateKey || !wroDailySchedules[selectedDateKey]) { alert("Please select a date with a planned routine to download."); return; } const daySchedule = wroDailySchedules[selectedDateKey]; const { jsPDF } = window.jspdf; const doc = new jsPDF(); doc.setFontSize(18); doc.setTextColor(getComputedStyle(document.documentElement).getPropertyValue('--wro-primary-color').trim()); doc.text(`Work Routine for: ${dtsgFormatDisplayDate(selectedDateKey)}`, 14, 22); let yPos = 35; doc.setFontSize(10); doc.setTextColor(50); doc.text(`Work Hours: ${wroFormatTime(wroSettings.workStartTime)} - ${wroFormatTime(wroSettings.workEndTime)}`, 14, yPos); yPos += 10; daySchedule.scheduledBlocks.forEach(blockInstance => { if (yPos > 260) { doc.addPage(); yPos = 20; } const blockType = wroSettings.timeBlockTypes.find(t => t.id === blockInstance.blockTypeId); const blockColor = blockType ? blockType.color : '#cccccc'; doc.setFontSize(12); // Simulate colored header for block - difficult to get actual CSS var value reliably in jsPDF without parsing // For now, just use a standard color or pass the hex directly doc.setFillColor(blockColor.startsWith('var') ? '#dddddd' : blockColor); // Fallback for CSS vars doc.rect(14, yPos - 4, doc.internal.pageSize.getWidth() - 28, 7, 'F'); doc.setTextColor(blockColor === '#F39C12' || blockColor === '#2ECC71' ? 50 : 255); // Text color based on perceived BG doc.text(`${wroFormatTime(blockInstance.startTime)} - ${wroFormatTime(blockInstance.endTime)}: ${blockInstance.name || (blockType ? blockType.name : 'Block')}`, 15, yPos); yPos += 8; doc.setTextColor(50); // Reset text color doc.setFontSize(9); if (blockInstance.tasks && blockInstance.tasks.length > 0) { blockInstance.tasks.forEach(taskId => { if (yPos > 270) { doc.addPage(); yPos = 20; } const task = daySchedule.dayTasksList.find(t => t.id === taskId); if (task) { const taskTypeForPdf = wroSettings.timeBlockTypes.find(t => t.id === task.taskTypeId); doc.text(` \u2022 ${task.name} (${task.estimatedTimeMinutes}m) - P: ${task.priority}, S: ${task.status}, Type: ${taskTypeForPdf ? taskTypeForPdf.name : 'N/A'}`, 18, yPos); yPos += 5; } }); } else { if (yPos > 270) { doc.addPage(); yPos = 20; } doc.text(" No tasks scheduled in this block.", 18, yPos); yPos += 5; } yPos += 3; // Space after block }); doc.save(`WorkRoutine_${selectedDateKey}.pdf`); }); // --- Initialization --- document.addEventListener('DOMContentLoaded', () => { wroLoadSettings(); wroLoadDailySchedules(); const today = new Date(2025, 4, 14); // May 14, 2025 for default wroSelectedDateInput.value = wroFormatDateKey(today); wroHandleDateChange(); // Initial render for selected/default date const firstTabButton = document.querySelector('#workRoutineOptimizerTool .wro-tab-button'); if (firstTabButton) { firstTabButton.click(); } // Close modals if clicked outside window.addEventListener('click', function(event) { if (event.target.classList.contains('wro-modal')) { wroCloseModal(event.target.id); } }); });