No data logged yet.
"; wdetDurationFindingsEl.innerHTML = "";
wdetCategoryEffectivenessChartEl.innerHTML = "
No data logged yet.
"; wdetCategoryFindingsEl.innerHTML = "";
wdetAnalysisDetailedLogTableBodyEl.innerHTML = "
| No data logged. |
";
if(wdetDownloadPdfBtn) wdetDownloadPdfBtn.style.display = 'none'; return;
}
const dateObjects = allLoggedDates.map(key => new Date(key + "T00:00:00Z"));
startDateObj = new Date(Math.min.apply(null, dateObjects)); startDateObj.setUTCHours(0,0,0,0);
endDateObj = new Date(Math.max.apply(null, dateObjects)); endDateObj.setUTCHours(23,59,59,999);
periodDisplayStr = `All Time (${wdetFormatDisplayDate(wdetFormatDateKey(startDateObj))} - ${wdetFormatDisplayDate(wdetFormatDateKey(endDateObj))})`;
}
if(wdetAnalysisPeriodDisplayEl) wdetAnalysisPeriodDisplayEl.textContent = periodDisplayStr;
const filteredEntries = [];
let currentDateIter = new Date(startDateObj);
while(currentDateIter <= endDateObj) {
const dateKey = wdetFormatDateKey(currentDateIter);
if (wdetWorkSessionLogs[dateKey]) {
filteredEntries.push(...wdetWorkSessionLogs[dateKey]);
}
currentDateIter.setDate(currentDateIter.getDate() + 1);
}
if (filteredEntries.length === 0) { /* ... handle no data for period ... */
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' });
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 {
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) { /* ... chart rendering from previous, ensure correct element access ... */
const data = durationAnalysis[label];
const avgScore = data.count > 0 ? (data.sumScore / data.count) : 0;
const barWidthPercent = 5 > 0 ? (avgScore / 5) * 100 : 0; // Bar width based on score out of 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.)
`;
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 = {}; /* ... same logic as before ... */
wdetSettings.categories.forEach(cat => categoryAnalysis[cat.id] = { name: cat.name, color: cat.color, sumScore: 0, count: 0, totalTime: 0 });
filteredEntries.forEach(entry => {
const catIdToUse = entry.categoryId || 'uncategorized';
if (!categoryAnalysis[catIdToUse] && catIdToUse === 'uncategorized') { // Dynamically add if not in settings
categoryAnalysis[catIdToUse] = { name: "Uncategorized", color: "#aaaaaa", sumScore: 0, count: 0, totalTime: 0 };
}
if(categoryAnalysis[catIdToUse]){
categoryAnalysis[catIdToUse].sumScore += entry.effectivenessScore;
categoryAnalysis[catIdToUse].count++;
categoryAnalysis[catIdToUse].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) { /* ... chart rendering ... */
const data = categoryAnalysis[catId];
if(data.count === 0) continue;
const avgScore = data.count > 0 ? (data.sumScore / data.count) : 0;
const barWidthPercent = 5 > 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.)
`;
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.";
// 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) );
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 ---
function handlePdfDownload() { /* ... */
if (!wdetAnalysisResultsEl.style.display || wdetAnalysisResultsEl.style.display === 'none') {
alert("Please run an analysis first to generate a PDF."); return;
}
const { jsPDF } = window.jspdf; const doc = new jsPDF();
const periodStr = wdetAnalysisPeriodDisplayEl.textContent || "Selected Period";
const primaryColor = getComputedStyle(document.documentElement).getPropertyValue('--wdet-primary-color').trim();
const secondaryColor = getComputedStyle(document.documentElement).getPropertyValue('--wdet-secondary-color').trim();
doc.setFontSize(18); doc.setTextColor(primaryColor);
doc.text("Work Duration Effectiveness Report", 14, 22);
doc.setFontSize(11); doc.setTextColor(100);
doc.text(`Analysis Period: ${periodStr}`, 14, 30);
doc.text(`Total Sessions Logged: ${wdetTotalSessionsAnalyzedEl.textContent}`, 14, 36);
doc.text(`Overall Average Effectiveness: ${wdetOverallAvgEffectivenessEl.textContent}`, 14, 42);
let yPos = 52;
doc.setFontSize(12); doc.setTextColor(primaryColor);
doc.text("Effectiveness by Duration:", 14, yPos); yPos += 7;
const durationTableData = [];
if (wdetDurationEffectivenessChartEl && wdetDurationEffectivenessChartEl.children.length > 1) { // children[0] is H5
for (let i = 1; i < wdetDurationEffectivenessChartEl.children.length; i++) {
const wrapper = wdetDurationEffectivenessChartEl.children[i];
const label = wrapper.querySelector('.wdet-chart-label')?.textContent || '';
const value = wrapper.querySelector('.wdet-chart-bar .value-text')?.textContent || '';
durationTableData.push([label.replace(/ \(\d+ sess\.\)/, ''), value]);
}
}
if (durationTableData.length > 0) {
doc.autoTable({ head: [['Duration Bracket', 'Avg. Effectiveness']], body: durationTableData, startY: yPos, theme: 'grid', headStyles: { fillColor: secondaryColor } });
yPos = doc.lastAutoTable.finalY + 10;
} else { doc.text("No duration analysis data.", 16, yPos); yPos += 7; }
if(wdetDurationFindingsEl) {
if (yPos > 270) { doc.addPage(); yPos = 20; }
doc.setFontSize(10); doc.setTextColor(50);
const findings1 = doc.splitTextToSize(wdetDurationFindingsEl.textContent || "No specific findings.", doc.internal.pageSize.getWidth() - 28);
doc.text(findings1, 14, yPos); yPos += findings1.length * 5 + 5;
}
if (yPos > 250) { doc.addPage(); yPos = 20; }
doc.setFontSize(12); doc.setTextColor(primaryColor);
doc.text("Effectiveness by Category:", 14, yPos); yPos += 7;
const categoryTableData = [];
if (wdetCategoryEffectivenessChartEl && wdetCategoryEffectivenessChartEl.children.length > 1) {
for (let i = 1; i < wdetCategoryEffectivenessChartEl.children.length; i++) {
const wrapper = wdetCategoryEffectivenessChartEl.children[i];
const label = wrapper.querySelector('.wdet-chart-label')?.textContent || '';
const value = wrapper.querySelector('.wdet-chart-bar .value-text')?.textContent || '';
categoryTableData.push([label.replace(/ \(\d+ sess\.\)/, ''), value]);
}
}
if (categoryTableData.length > 0) {
doc.autoTable({ head: [['Category', 'Avg. Effectiveness']], body: categoryTableData, startY: yPos, theme: 'grid', headStyles: { fillColor: secondaryColor } });
yPos = doc.lastAutoTable.finalY + 10;
} else { doc.text("No category analysis data.", 16, yPos); yPos +=7; }
if(wdetCategoryFindingsEl){
if (yPos > 270) { doc.addPage(); yPos = 20; }
doc.setFontSize(10); doc.setTextColor(50);
const findings2 = doc.splitTextToSize(wdetCategoryFindingsEl.textContent || "No specific findings.", doc.internal.pageSize.getWidth() - 28);
doc.text(findings2, 14, yPos); yPos += findings2.length * 5 + 5;
}
// Detailed Log
const detailedLogRows = [];
const logTable = document.getElementById('wdetAnalysisDetailedLogTable');
if (logTable) {
const rows = logTable.querySelectorAll('tbody tr');
rows.forEach(row => {
const rowData = [];
row.querySelectorAll('td').forEach(cell => rowData.push(cell.textContent));
if(rowData.length > 0) detailedLogRows.push(rowData); // Ensure row is not empty
});
}
if (detailedLogRows.length > 0) {
if (yPos > 230) { doc.addPage(); yPos = 20; } // Check space for table title + table
doc.setFontSize(12); doc.setTextColor(primaryColor);
doc.text("Detailed Log Entries:", 14, yPos); yPos += 7;
doc.autoTable({
head: [['Date', 'Activity', 'Category', 'Duration (m)', 'Effectiveness', 'Notes']],
body: detailedLogRows, startY: yPos, theme: 'grid',
headStyles: { fillColor: secondaryColor },
columnStyles: { 0: {cellWidth:25}, 1: {cellWidth:50}, 5: {cellWidth:'auto'} } // Example column widths
});
}
doc.save(`WorkEffectivenessReport_${periodStr.replace(/[^a-zA-Z0-9]/g, '_')}.pdf`);
}
// --- 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');
wdetTabButtons = document.querySelectorAll('#workDurationEffectivenessTool .wdet-tab-button');
wdetTabContents = document.querySelectorAll('#workDurationEffectivenessTool .wdet-tab-content');
wdetPrevTabBtn = document.getElementById('wdetPrevTabBtn');
wdetNextTabBtn = document.getElementById('wdetNextTabBtn');
// Attach event listeners
if(wdetAddCategoryForm) wdetAddCategoryForm.addEventListener('submit', handleAddCategoryFormSubmit);
if(wdetLogEntryForm) wdetLogEntryForm.addEventListener('submit', handleLogEntryFormSubmit);
if(wdetLogDateInput) wdetLogDateInput.addEventListener('change', wdetHandleLogDateChange);
if(wdetDownloadPdfBtn) wdetDownloadPdfBtn.addEventListener('click', handlePdfDownload);
const today = new Date(2025, 4, 14);
if(wdetLogDateInput) wdetLogDateInput.value = wdetFormatDateKey(today);
wdetLoadData();
// Initialize first tab and nav buttons
if (wdetTabButtons.length > 0) {
wdetOpenTab({ currentTarget: wdetTabButtons[0] }, wdetTabContents[0].id, 0);
}
window.addEventListener('click', function(event) {
if (event.target.classList.contains('wdet-modal')) {
wdetCloseModal(event.target.id);
}
});
});