No logs available or found for the selected date range. Please add check-ins in Tab 1.
';
const dashboardDisplayEl = document.getElementById('mbpt-dashboard-display');
const insightsListEl = document.getElementById('mbpt-insights-list');
const avgSummaryEl = document.getElementById('mbpt-average-summary-list');
if (mbptSessionLogs.length === 0 && mbptCurrentTabIndex === 1) {
if(dashboardDisplayEl) dashboardDisplayEl.innerHTML = noDataMsg;
if(insightsListEl) insightsListEl.innerHTML = '
No data to analyze.';
if(avgSummaryEl) avgSummaryEl.innerHTML = '
No data for averages.';
Object.values(mbptChartInstances).forEach(chart => chart ? chart.destroy() : null);
return;
}
const startDateStr = document.getElementById('mbpt-analysis-start-date').value;
const endDateStr = document.getElementById('mbpt-analysis-end-date').value;
if(!startDateStr || !endDateStr) return;
const startDate = new Date(startDateStr + "T00:00:00");
const endDate = new Date(endDateStr + "T23:59:59");
const filteredLogs = mbptSessionLogs.filter(log => log.datetime >= startDate && log.datetime <= endDate);
if (filteredLogs.length === 0 && mbptCurrentTabIndex === 1) {
if(dashboardDisplayEl) dashboardDisplayEl.innerHTML = noDataMsg;
if(insightsListEl) insightsListEl.innerHTML = '
No data in selected range for insights.';
if(avgSummaryEl) avgSummaryEl.innerHTML = '
No data in range for averages.';
Object.values(mbptChartInstances).forEach(chart => chart ? chart.destroy() : null);
return;
}
// Calculate Averages
if(avgSummaryEl){
if(filteredLogs.length > 0){
const avgPreAwareness = filteredLogs.reduce((s,l)=>s+l.preAwareness,0)/filteredLogs.length;
const avgFocus = filteredLogs.reduce((s,l)=>s+l.focusLevel,0)/filteredLogs.length;
const avgPresence = filteredLogs.reduce((s,l)=>s+l.presenceLevel,0)/filteredLogs.length;
const avgMindWandering = filteredLogs.reduce((s,l)=>s+l.mindWandering,0)/filteredLogs.length;
const avgSleepQuality = filteredLogs.reduce((s,l)=>s+l.sleepQuality,0)/filteredLogs.length;
const avgSleepHours = filteredLogs.reduce((s,l)=>s+l.sleepHours,0)/filteredLogs.length;
avgSummaryEl.innerHTML = `
Avg. Pre-Session Awareness: ${avgPreAwareness.toFixed(1)}/5
Avg. In-Session Focus: ${avgFocus.toFixed(1)}/5
Avg. In-Session Presence: ${avgPresence.toFixed(1)}/5
Avg. Mind Wandering Count: ${avgMindWandering.toFixed(1)}
Avg. Sleep Quality: ${avgSleepQuality.toFixed(1)}/5 | Avg. Sleep Hours: ${avgSleepHours.toFixed(1)}h
`;
} else {
avgSummaryEl.innerHTML = '
No data in range for averages.';
}
}
// Prepare chart data
const awarenessData = filteredLogs.map(log => ({x: log.datetime, y: log.preAwareness}));
const focusData = filteredLogs.map(log => ({x: log.datetime, y: log.focusLevel}));
const presenceData = filteredLogs.map(log => ({x: log.datetime, y: log.presenceLevel}));
const mindWanderingData = filteredLogs.map(log => ({x: log.datetime, y: log.mindWandering}));
const sleepQualityData = filteredLogs.map(log => ({x: log.datetime, y: log.sleepQuality}));
const sleepHoursData = filteredLogs.map(log => ({x: log.datetime, y: log.sleepHours}));
// Dashboard HTML (Chart Canvases)
if(dashboardDisplayEl) dashboardDisplayEl.innerHTML = `
Mindful Awareness (Pre-Session)
Focus Level (In-Session)
Presence Level (In-Session)
Mind Wandering Count
Sleep Quality & Hours
`;
// Render Charts
mbptRenderLineChart('mbpt-awareness-chart', awarenessData, 'Awareness (1-5)', 'var(--primary-color)');
mbptRenderLineChart('mbpt-focus-chart', focusData, 'Focus (1-5)', 'var(--accent-color)');
mbptRenderLineChart('mbpt-presence-chart', presenceData, 'Presence (1-5)', 'var(--success-color)');
mbptRenderLineChart('mbpt-wandering-chart', mindWanderingData, 'Mind Wanders', 'var(--danger-color)');
// Combined Sleep Chart
const sleepCtx = document.getElementById('mbpt-sleep-chart');
if (sleepCtx) {
if (mbptChartInstances['mbpt-sleep-chart']) mbptChartInstances['mbpt-sleep-chart'].destroy();
mbptChartInstances['mbpt-sleep-chart'] = new Chart(sleepCtx.getContext('2d'), {
type: 'line',
data: {
datasets: [
{ label: 'Sleep Quality (1-5)', data: sleepQualityData, borderColor: 'var(--primary-color)', yAxisID: 'yQuality', tension: 0.1 },
{ label: 'Sleep Hours', data: sleepHoursData, borderColor: 'var(--secondary-color)', yAxisID: 'yHours', tension: 0.1 }
]
},
options: { responsive: true, maintainAspectRatio: false,
scales: {
x: { type: 'time', time: { unit: 'day', tooltipFormat: 'MMM dd, yy' } },
yQuality: { type: 'linear', position: 'left', min:0, max:5, title:{display:true, text:'Quality (1-5)'} },
yHours: { type: 'linear', position: 'right', min:0, title:{display:true, text:'Hours'}, grid: { drawOnChartArea: false } }
}
}
});
}
// Generate Insights
if(insightsListEl){
insightsListEl.innerHTML = ''; let insightsGeneratedCount = 0;
if (filteredLogs.length >= 3) { // Need some data for basic insights
const lastThreeLogs = filteredLogs.slice(-3);
const avgFocusLastThree = lastThreeLogs.reduce((sum, l) => sum + l.focusLevel, 0) / lastThreeLogs.length;
const avgWanderingLastThree = lastThreeLogs.reduce((sum, l) => sum + l.mindWandering, 0) / lastThreeLogs.length;
const avgSleepHoursLastThree = lastThreeLogs.reduce((sum, l) => sum + l.sleepHours, 0) / lastThreeLogs.length;
if(avgFocusLastThree < 2.5) { insightsListEl.innerHTML += `
Your average focus level in recent sessions is low (${avgFocusLastThree.toFixed(1)}/5). Review 'Challenged Mindfulness' notes for patterns.`; insightsGeneratedCount++;}
if(avgWanderingLastThree > 5) { insightsListEl.innerHTML += `
Mind wandering count is frequently high (avg ${avgWanderingLastThree.toFixed(1)}). Short mindfulness exercises before or during tasks might help anchor attention.`; insightsGeneratedCount++;}
if(avgSleepHoursLastThree < 6.5) { insightsListEl.innerHTML += `
Recent sleep duration averaged ${avgSleepHoursLastThree.toFixed(1)} hours. Aiming for 7-9 hours can significantly impact daytime focus and energy.`; insightsGeneratedCount++;}
let helpedItems = {};
filteredLogs.forEach(log => { if(log.helpedMindfulness) helpedItems[log.helpedMindfulness.toLowerCase().trim()] = (helpedItems[log.helpedMindfulness.toLowerCase().trim()] || 0 ) + 1; });
const sortedHelped = Object.entries(helpedItems).sort((a,b)=>b[1]-a[1]);
if(sortedHelped.length > 0 && sortedHelped[0][1] > 1) { insightsListEl.innerHTML += `
You've frequently noted that '${sortedHelped[0][0]}' helps mindfulness. Keep leveraging this!`; insightsGeneratedCount++;}
}
if(insightsGeneratedCount === 0 && filteredLogs.length > 0) insightsListEl.innerHTML += `
Continue logging to discover more personalized trends. Review your charts and notes regularly.`;
else if (filteredLogs.length === 0) insightsListEl.innerHTML += `
No data in selected range to provide insights.`;
}
}
function mbptRenderLineChart(canvasId, dataPoints, label, color) {
const ctx = document.getElementById(canvasId);
if (!ctx) return;
if (mbptChartInstances[canvasId]) mbptChartInstances[canvasId].destroy();
mbptChartInstances[canvasId] = new Chart(ctx.getContext('2d'), {
type: 'line',
data: { datasets: [{ label: label, data: dataPoints, borderColor: color, tension: 0.1, fill: false }] },
options: {
responsive: true, maintainAspectRatio: false,
scales: { x: { type: 'time', time: { unit: 'day', tooltipFormat: 'MMM dd, yy', displayFormats: {'day': 'MMM dd'} } },
y: { beginAtZero: true, title: {display:true, text:label.split('(')[0].trim()}} } // Only show unit if it exists
}
});
}
// PDF Download
function mbptDownloadPDF() {
const dashboardDisplayEl = document.getElementById('mbpt-dashboard-display');
if (!dashboardDisplayEl || dashboardDisplayEl.innerHTML.includes("Log work sessions") || mbptSessionLogs.length === 0) {
alert("Please log some data and generate the dashboard first."); return;
}
const analysisStartDate = document.getElementById('mbpt-analysis-start-date').value;
const analysisEndDate = document.getElementById('mbpt-analysis-end-date').value;
let pdfHTML = `
Mindfulness-Based Productivity Report
`;
pdfHTML += `
Analysis Period: ${analysisStartDate} to ${analysisEndDate}
`;
const avgSummaryContent = document.getElementById('mbpt-average-summary-list').outerHTML;
if(avgSummaryContent) pdfHTML += `
Well-Being Averages (Selected Period)
${avgSummaryContent}`;
const chartsToInclude = [
{instance: mbptChartInstances['mbpt-awareness-chart'], title: "Mindful Awareness (Pre-Session)"},
{instance: mbptChartInstances['mbpt-focus-chart'], title: "Focus Level (In-Session)"},
{instance: mbptChartInstances['mbpt-presence-chart'], title: "Presence Level (In-Session)"},
{instance: mbptChartInstances['mbpt-wandering-chart'], title: "Mind Wandering Count"},
{instance: mbptChartInstances['mbpt-sleep-chart'], title: "Sleep Quality & Hours"}
];
chartsToInclude.forEach(chartInfo => {
if(chartInfo.instance){
try {
pdfHTML += `
${chartInfo.title}
`;
} catch (e) { console.error("Error converting chart to image for PDF: ", chartInfo.title, e); }
}
});
const insightsContent = document.getElementById('mbpt-insights-list').outerHTML;
if(insightsContent) pdfHTML += `
Key Insights & Gentle Reminders
${insightsContent}`;
const filteredLogsForPDF = mbptSessionLogs.filter(log => {
const logDateOnly = log.datetime.toISOString().split('T')[0];
return logDateOnly >= analysisStartDate && logDateOnly <= analysisEndDate;
});
if (filteredLogsForPDF.length > 0 && confirm("Include detailed session logs in PDF? This can make the PDF long.")) {
pdfHTML += `
Detailed Session Logs (${analysisStartDate} to ${analysisEndDate})
`;
pdfHTML += `
| Date | Intention | Pre-Aware | Focus | Presence | Wandered | Sleep(H) | Sleep(Q) | Post-Feeling | Notes |
`;
filteredLogsForPDF.forEach(log => {
pdfHTML += `
| ${log.datetime.toLocaleString([],{dateStyle:'short',timeStyle:'short'})} | ${log.intention.substring(0,20)}... | ${log.preAwareness} |
${log.focusLevel} | ${log.presenceLevel} | ${log.mindWandering} |
${log.sleepHours.toFixed(1)} | ${log.sleepQuality} | ${log.postFeeling} |
${log.generalNotes.substring(0,30)}${log.generalNotes.length > 30 ? '...' : ''} |
`;
});
pdfHTML += `
`;
}
const pdfContainer = document.getElementById('mbpt-report-content-for-pdf');
pdfContainer.innerHTML = pdfHTML;
const opt = {
margin: [0.5, 0.4, 0.5, 0.4], filename: `Mindful_Productivity_Report_${analysisStartDate}_to_${analysisEndDate}.pdf`,
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2, useCORS: true, logging: false, scrollX:0, scrollY: -window.scrollY, windowWidth: pdfContainer.scrollWidth + 100 },
jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' },
pagebreak: { mode: ['avoid-all', 'css', 'legacy'] }
};
html2pdf().from(pdfContainer).set(opt).save().then(() => {
pdfContainer.innerHTML = '';
}).catch(err => {
console.error("Error generating PDF:", err);
pdfContainer.innerHTML = '';
alert("An error occurred while generating the PDF. Check console for details.");
});
}