Work Duration Effectiveness Tool

Work Duration Effectiveness Tool

Logged Sessions for Date:

Analyze Productivity Patterns

Manage Work Categories

Understanding Your Work Duration Effectiveness

1. Log Your Work Sessions Consistently (Log Session Tab)
After completing a focused work session, log it:
  • Date: The date the session took place.
  • Task/Activity: What you worked on.
  • Category: Assign it to a relevant category (manage these in the "Categories" tab).
  • Actual Duration: How long you actually worked in minutes (e.g., 25, 50, 90).
  • Effectiveness Score (1-5): Rate how effective you felt that session was:
    • 1: Very Ineffective (many distractions, little accomplished)
    • 2: Slightly Ineffective (some progress, but below par)
    • 3: Moderately Effective (average, typical output)
    • 4: Effective (good focus, solid progress)
    • 5: Highly Effective (peak focus, flow state, significant results)
  • Notes: Briefly mention any factors that influenced your effectiveness (e.g., "Quiet environment," "Interrupted frequently," "Felt tired").
2. Analyze Your Effectiveness Patterns (Analyze Effectiveness Tab)
Choose a period (e.g., Last 30 Days) and click "Analyze Data." The tool will show you:
  • Average Effectiveness by Work Duration: This chart helps you see if you tend to be more or less effective when working for certain lengths of time (e.g., are your 25-minute sessions rated higher than your 90-minute ones?).
  • Average Effectiveness by Category: See which types of tasks you tend to be most effective at, or if certain categories correlate with different effectiveness scores.
  • Summary Findings: The tool will try to highlight duration brackets or categories where your self-rated effectiveness is highest.
3. Interpret and Act on Insights
  • Identify your "peak duration" – the length of a work session where you consistently rate your effectiveness highly. Try to structure more of your important work into sessions of this length.
  • If long sessions show declining effectiveness, consider incorporating more frequent short breaks.
  • If certain task categories consistently have lower effectiveness scores, explore why. Do you need different strategies for those tasks? Different times of day?
  • Use your notes to understand the context behind your scores. What makes a "Highly Effective" session for you? Try to replicate those conditions.
4. Experiment and Refine
This tool helps you learn about your personal work style. Use the insights to experiment with different work patterns, session lengths, and break schedules to find what maximizes your sustainable productivity.
'; return; } const displayDate = wdetFormatDisplayDate(selectedDateKey); if(wdetLogDateDisplayEl) wdetLogDateDisplayEl.textContent = displayDate; wdetRenderLoggedSessions(selectedDateKey); } function wdetRenderLoggedSessions(dateKey) { /* ... */ if(!wdetLoggedSessionsListEl) return; wdetLoggedSessionsListEl.innerHTML = ''; const sessions = wdetWorkSessionLogs[dateKey] || []; if (sessions.length === 0) { wdetLoggedSessionsListEl.innerHTML = '

No work sessions logged for this day yet.

'; return; } sessions.sort((a,b)=> new Date(a.date+"T00:00:00Z") - new Date(b.date+"T00:00:00Z") ); // Should not be needed if keyed by date already, unless storing multiple entries per day and they need sub-sorting sessions.forEach(session => { const cat = wdetSettings.categories.find(c => c.id === session.categoryId); const itemEl = document.createElement('div'); itemEl.className = 'wdet-list-item'; itemEl.innerHTML = `

${session.taskName}

Duration: ${session.durationMinutes}m | Effectiveness: ${session.effectivenessScore}/5 ${cat ? `| ${cat.name}` : '| Uncategorized'} ${session.notes ? `
Notes: ${session.notes.replace(/\n/g, '
')}
` : ''}

`; wdetLoggedSessionsListEl.appendChild(itemEl); }); } window.wdetOpenLogModal = function(sessionId = null) { /* ... */ const selectedDateKey = wdetLogDateInput.value; if (!selectedDateKey) { alert("Please select a date first."); return; } wdetLogEntryForm.reset(); wdetLogEntryIdInput.value = ''; wdetLogEntryDateKeyModalInput.value = selectedDateKey; wdetPopulateCategorySelectForModal(); if (sessionId) { const sessions = wdetWorkSessionLogs[selectedDateKey] || []; const session = sessions.find(s => s.id === sessionId); if (session) { wdetLogEntryModalTitleEl.textContent = 'Edit Work Session for ' + wdetFormatDisplayDate(selectedDateKey); wdetLogEntryIdInput.value = session.id; wdetEntryTaskNameInput.value = session.taskName; wdetEntryCategorySelectEl.value = session.categoryId || ""; wdetEntryDurationMinutesInput.value = session.durationMinutes; // Set radio button for effectiveness score const scoreRadio = wdetLogEntryForm.querySelector(`input[name="effectivenessScore"][value="${session.effectivenessScore}"]`); if (scoreRadio) scoreRadio.checked = true; wdetEntryNotesInput.value = session.notes || ""; } } else { wdetLogEntryModalTitleEl.textContent = 'Log New Work Session for ' + wdetFormatDisplayDate(selectedDateKey); // Default effectiveness score e.g. 3 const defaultScoreRadio = wdetLogEntryForm.querySelector(`input[name="effectivenessScore"][value="3"]`); if (defaultScoreRadio) defaultScoreRadio.checked = true; } wdetLogEntryModalEl.style.display = 'block'; }; window.wdetCloseModal = (modalId) => { /* ... */ const modal = document.getElementById(modalId); if(modal) modal.style.display = 'none'; } if(wdetLogEntryForm) wdetLogEntryForm.addEventListener('submit', function(e) { /* ... */ e.preventDefault(); const entryId = wdetLogEntryIdInput.value; const dateKey = wdetLogEntryDateKeyModalInput.value; if (!dateKey) { alert("Error: Date context lost for entry."); return; } const selectedEffectivenessRadio = wdetLogEntryForm.querySelector('input[name="effectivenessScore"]:checked'); if (!selectedEffectivenessRadio) { alert("Please select an effectiveness score."); return; } const entryData = { date: dateKey, // Store the date with the entry taskName: wdetEntryTaskNameInput.value.trim(), categoryId: wdetEntryCategorySelectEl.value, durationMinutes: parseInt(wdetEntryDurationMinutesInput.value), effectivenessScore: parseInt(selectedEffectivenessRadio.value), notes: wdetEntryNotesInput.value.trim() }; if (!entryData.taskName || isNaN(entryData.durationMinutes) || entryData.durationMinutes <= 0) { alert("Task name and a valid positive duration are required."); return; } if (!entryData.categoryId) { alert("Please select a category."); return; } if (!wdetWorkSessionLogs[dateKey]) wdetWorkSessionLogs[dateKey] = []; if (entryId) { const index = wdetWorkSessionLogs[dateKey].findIndex(e => e.id === entryId); if (index > -1) { wdetWorkSessionLogs[dateKey][index] = { ...wdetWorkSessionLogs[dateKey][index], ...entryData }; } } else { const newEntry = { id: 'session-' + Date.now(), ...entryData }; wdetWorkSessionLogs[dateKey].push(newEntry); } wdetSaveSessionLogs(); wdetRenderLoggedSessions(dateKey); wdetCloseModal('wdetLogEntryModal'); }); window.wdetDeleteLogSession = function(sessionId) { /* ... */ const selectedDateKey = wdetLogDateInput.value; if (!selectedDateKey || !wdetWorkSessionLogs[selectedDateKey]) return; if (confirm('Are you sure you want to delete this logged session?')) { wdetWorkSessionLogs[selectedDateKey] = wdetWorkSessionLogs[selectedDateKey].filter(s => s.id !== sessionId); if(wdetWorkSessionLogs[selectedDateKey].length === 0) { delete wdetWorkSessionLogs[selectedDateKey]; } wdetSaveSessionLogs(); wdetRenderLoggedSessions(selectedDateKey); } } // --- Analysis & Reports --- // (wdetRunAnalysis, PDF export, chart rendering will go here) // ... Placeholder ... // --- Initialization --- document.addEventListener('DOMContentLoaded', () => { // Assign DOM Elements wdetLogDateInput = document.getElementById('wdetLogDate'); wdetLogDateDisplayEl = document.getElementById('wdetLogDateDisplay'); wdetLoggedSessionsListEl = document.getElementById('wdetLoggedSessionsList'); wdetAddCategoryForm = document.getElementById('wdetAddCategoryForm'); wdetCategoryNameInput = document.getElementById('wdetCategoryNameInput'); wdetCategoryColorInput = document.getElementById('wdetCategoryColorInput'); wdetCategoriesListEl = document.getElementById('wdetCategoriesList'); wdetLogEntryModalEl = document.getElementById('wdetLogEntryModal'); wdetLogEntryModalTitleEl = document.getElementById('wdetLogEntryModalTitle'); wdetLogEntryForm = document.getElementById('wdetLogEntryForm'); wdetLogEntryIdInput = document.getElementById('wdetLogEntryId'); wdetLogEntryDateKeyModalInput = document.getElementById('wdetLogEntryDateKey_modal'); wdetEntryTaskNameInput = document.getElementById('wdetEntryTaskName'); wdetEntryCategorySelectEl = document.getElementById('wdetEntryCategorySelect'); wdetEntryDurationMinutesInput = document.getElementById('wdetEntryDurationMinutes'); wdetEntryNotesInput = document.getElementById('wdetEntryNotes'); wdetAnalysisPeriodSelectEl = document.getElementById('wdetAnalysisPeriodSelect'); wdetAnalysisResultsEl = document.getElementById('wdetAnalysisResults'); wdetAnalysisPeriodDisplayEl = document.getElementById('wdetAnalysisPeriodDisplay'); wdetTotalSessionsAnalyzedEl = document.getElementById('wdetTotalSessionsAnalyzed'); wdetOverallAvgEffectivenessEl = document.getElementById('wdetOverallAvgEffectiveness'); wdetDurationEffectivenessChartEl = document.getElementById('wdetDurationEffectivenessChart'); wdetDurationFindingsEl = document.getElementById('wdetDurationFindings'); wdetCategoryEffectivenessChartEl = document.getElementById('wdetCategoryEffectivenessChart'); wdetCategoryFindingsEl = document.getElementById('wdetCategoryFindings'); wdetAnalysisDetailedLogTableBodyEl = document.querySelector('#wdetAnalysisDetailedLogTable tbody'); wdetDownloadPdfBtn = document.getElementById('wdetDownloadPdfButton'); // Element checks const criticalElements = [wdetLogDateInput, wdetAddCategoryForm, wdetLogEntryForm, wdetAnalysisPeriodSelectEl]; if (criticalElements.some(el => !el)) { console.error("WDET: Critical DOM elements missing, tool might not function correctly."); // alert("Error: Core UI elements missing. Please check HTML code."); // return; // Can't stop script here, just warn. } // Event Listeners if(wdetAddCategoryForm) wdetAddCategoryForm.addEventListener('submit', handleAddCategoryFormSubmit); // LogEntryForm listener already added above. if(wdetLogDateInput) wdetLogDateInput.addEventListener('change', wdetHandleLogDateChange); // Analysis button and PDF button are onclick in HTML. // Default date and load const today = new Date(2025, 4, 14); // May 14, 2025 if(wdetLogDateInput) wdetLogDateInput.value = wdetFormatDateKey(today); wdetLoadData(); const firstTabButton = document.querySelector('#workDurationEffectivenessTool .wdet-tab-button'); if (firstTabButton) firstTabButton.click(); window.addEventListener('click', function(event) { if (event.target.classList.contains('wdet-modal')) { wdetCloseModal(event.target.id); } }); }); // --- Analysis and Charting (Full implementation) --- window.wdetRunAnalysis = function() { if (!wdetAnalysisResultsEl || !wdetAnalysisPeriodSelectEl || !wdetTotalSessionsAnalyzedEl || !wdetOverallAvgEffectivenessEl || !wdetDurationEffectivenessChartEl || !wdetDurationFindingsEl || !wdetCategoryEffectivenessChartEl || !wdetCategoryFindingsEl || !wdetAnalysisDetailedLogTableBodyEl) { console.error("Analysis UI elements not found"); return; } const period = wdetAnalysisPeriodSelectEl.value; const todayForAnalysis = new Date(2025, 4, 14); // Use context date for period calculation consistency todayForAnalysis.setHours(0,0,0,0); let startDate, endDate; let periodDisplayStr = ""; if (period === "last7") { endDate = new Date(todayForAnalysis); startDate = new Date(todayForAnalysis); startDate.setDate(todayForAnalysis.getDate() - 6); periodDisplayStr = `Last 7 Days (${wdetFormatDisplayDate(wdetFormatDateKey(startDate))} - ${wdetFormatDisplayDate(wdetFormatDateKey(endDate))})`; } else if (period === "last30") { endDate = new Date(todayForAnalysis); startDate = new Date(todayForAnalysis); startDate.setDate(todayForAnalysis.getDate() - 29); periodDisplayStr = `Last 30 Days (${wdetFormatDisplayDate(wdetFormatDateKey(startDate))} - ${wdetFormatDisplayDate(wdetFormatDateKey(endDate))})`; } else { // all_time // Find min/max dates from logs const allDates = Object.keys(wdetWorkSessionLogs).map(key => new Date(key + "T00:00:00Z")); if (allDates.length === 0) { wdetAnalysisResultsEl.style.display = 'block'; wdetAnalysisResultsEl.innerHTML = '

No data logged yet to analyze.

'; if(wdetDownloadPdfBtn) wdetDownloadPdfBtn.style.display = 'none'; return; } startDate = new Date(Math.min.apply(null, allDates)); endDate = new Date(Math.max.apply(null, allDates)); periodDisplayStr = `All Time (${wdetFormatDisplayDate(wdetFormatDateKey(startDate))} - ${wdetFormatDisplayDate(wdetFormatDateKey(endDate))})`; } wdetAnalysisPeriodDisplayEl.textContent = periodDisplayStr; const filteredEntries = []; let currentDateIter = new Date(startDate); while(currentDateIter <= endDate) { const dateKey = wdetFormatDateKey(currentDateIter); if (wdetWorkSessionLogs[dateKey]) { filteredEntries.push(...wdetWorkSessionLogs[dateKey]); } currentDateIter.setDate(currentDateIter.getDate() + 1); } if (filteredEntries.length === 0) { wdetAnalysisResultsEl.style.display = 'block'; wdetTotalSessionsAnalyzedEl.textContent = "0"; wdetOverallAvgEffectivenessEl.textContent = "N/A"; wdetDurationEffectivenessChartEl.innerHTML = "

No data for this period.

"; wdetDurationFindingsEl.innerHTML = ""; wdetCategoryEffectivenessChartEl.innerHTML = "

No data for this period.

"; wdetCategoryFindingsEl.innerHTML = ""; wdetAnalysisDetailedLogTableBodyEl.innerHTML = "No entries in this period."; if(wdetDownloadPdfBtn) wdetDownloadPdfBtn.style.display = 'none'; return; } wdetTotalSessionsAnalyzedEl.textContent = filteredEntries.length; const totalEffectivenessSum = filteredEntries.reduce((sum, entry) => sum + entry.effectivenessScore, 0); wdetOverallAvgEffectivenessEl.textContent = (totalEffectivenessSum / filteredEntries.length).toFixed(2) + "/5"; // Analysis by Duration Bracket const durationAnalysis = {}; wdetSettings.durationBrackets.forEach(b => durationAnalysis[b.label] = { sumScore: 0, count: 0, color: wdetSettings.categories[wdetSettings.durationBrackets.indexOf(b) % wdetSettings.categories.length]?.color || '#cccccc' }); // Cycle through category colors for brackets filteredEntries.forEach(entry => { const bracket = wdetSettings.durationBrackets.find(b => entry.durationMinutes >= b.min && entry.durationMinutes <= b.max); if (bracket) { durationAnalysis[bracket.label].sumScore += entry.effectivenessScore; durationAnalysis[bracket.label].count++; } else { // Fallback for durations exceeding max defined bracket (e.g. 121+ min) const lastBracket = wdetSettings.durationBrackets[wdetSettings.durationBrackets.length-1]; if(entry.durationMinutes >= lastBracket.min){ durationAnalysis[lastBracket.label].sumScore += entry.effectivenessScore; durationAnalysis[lastBracket.label].count++; } } }); wdetDurationEffectivenessChartEl.innerHTML = '
Avg. Effectiveness Score:
'; let maxAvgDurationScore = 0; Object.values(durationAnalysis).forEach(data => { if (data.count > 0) { const avg = data.sumScore / data.count; if (avg > maxAvgDurationScore) maxAvgDurationScore = avg; } }); let bestDurationBracket = "N/A"; let highestScoreForDuration = 0; for (const label in durationAnalysis) { const data = durationAnalysis[label]; const avgScore = data.count > 0 ? (data.sumScore / data.count) : 0; const barHeightPercent = maxAvgDurationScore > 0 ? (avgScore / 5) * 100 : 0; // Max score is 5 if(avgScore > highestScoreForDuration && data.count > 0){ highestScoreForDuration = avgScore; bestDurationBracket = label; } const barWrapper = document.createElement('div'); barWrapper.className = 'wdet-chart-bar-wrapper'; barWrapper.innerHTML = `
${label} (${data.count} sess.)
${avgScore.toFixed(2)}
`; wdetDurationEffectivenessChartEl.appendChild(barWrapper); } wdetDurationFindingsEl.innerHTML = bestDurationBracket !== "N/A" ? `You seem to be most effective during work sessions lasting ${bestDurationBracket} (Avg. Score: ${highestScoreForDuration.toFixed(2)}/5).` : "Not enough data to determine peak duration effectiveness."; // Analysis by Category const categoryAnalysis = {}; wdetSettings.categories.forEach(cat => categoryAnalysis[cat.id] = { name: cat.name, color: cat.color, sumScore: 0, count: 0, totalTime: 0 }); filteredEntries.forEach(entry => { if (entry.categoryId && categoryAnalysis[entry.categoryId]) { categoryAnalysis[entry.categoryId].sumScore += entry.effectivenessScore; categoryAnalysis[entry.categoryId].count++; categoryAnalysis[entry.categoryId].totalTime += entry.durationMinutes; } else { // Uncategorized if (!categoryAnalysis['uncategorized']) categoryAnalysis['uncategorized'] = { name: "Uncategorized", color: "#aaaaaa", sumScore: 0, count: 0, totalTime: 0 }; categoryAnalysis['uncategorized'].sumScore += entry.effectivenessScore; categoryAnalysis['uncategorized'].count++; categoryAnalysis['uncategorized'].totalTime += entry.durationMinutes; } }); wdetCategoryEffectivenessChartEl.innerHTML = '
Avg. Effectiveness Score:
'; let maxAvgCategoryScore = 0; Object.values(categoryAnalysis).forEach(data => { if (data.count > 0) { const avg = data.sumScore / data.count; if (avg > maxAvgCategoryScore) maxAvgCategoryScore = avg; } }); let bestCategory = "N/A"; let highestScoreForCategory = 0; for (const catId in categoryAnalysis) { const data = categoryAnalysis[catId]; if(data.count === 0) continue; // Skip categories with no entries in this period const avgScore = data.count > 0 ? (data.sumScore / data.count) : 0; const barHeightPercent = maxAvgCategoryScore > 0 ? (avgScore / 5) * 100 : 0; if(avgScore > highestScoreForCategory){ highestScoreForCategory = avgScore; bestCategory = data.name; } const barWrapper = document.createElement('div'); barWrapper.className = 'wdet-chart-bar-wrapper'; barWrapper.innerHTML = `
${data.name} (${data.count} sess.)
${avgScore.toFixed(2)}
`; wdetCategoryEffectivenessChartEl.appendChild(barWrapper); } wdetCategoryFindingsEl.innerHTML = bestCategory !== "N/A" ? `Your highest average effectiveness is often in ${bestCategory} tasks (Avg. Score: ${highestScoreForCategory.toFixed(2)}/5).` : "Not enough categorized data to determine peak category effectiveness."; // Detailed Log Table wdetAnalysisDetailedLogTableBodyEl.innerHTML = ''; filteredEntries.sort((a,b) => new Date(a.date+"T00:00:00Z").getTime() - new Date(b.date+"T00:00:00Z").getTime() || a.taskName.localeCompare(b.taskName) ); // Sort by date then name filteredEntries.forEach(entry => { const cat = wdetSettings.categories.find(c => c.id === entry.categoryId); const row = wdetAnalysisDetailedLogTableBodyEl.insertRow(); row.insertCell().textContent = wdetFormatDisplayDate(entry.date); row.insertCell().textContent = entry.taskName; row.insertCell().textContent = cat ? cat.name : 'Uncategorized'; row.insertCell().textContent = entry.durationMinutes; row.insertCell().textContent = entry.effectivenessScore; row.insertCell().textContent = entry.notes || ""; }); wdetAnalysisResultsEl.style.display = 'block'; if(wdetDownloadPdfBtn) wdetDownloadPdfBtn.style.display = 'block'; } // --- PDF Export --- // (handlePdfDownload function, similar to previous tools, adapting for this data) // ... Placeholder ... // --- Initialization --- // (All DOM assignments and main listeners moved into DOMContentLoaded)
Scroll to Top