';
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, ' ')} ` : ''}
Edit
Delete
`;
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.)
`;
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.)
`;
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)