Smart Healthy Productivity Insights

Smart Healthy Productivity Insights

New Daily Log

Sleep (Previous Night)

Well-being & Productivity (Today)

Recent Log Entries

DateSleep(H)Sleep(Q)StressMoodEnergy Activity(m)TasksProductivityFocusNotesDel

Note: Log data is stored in your browser's LocalStorage.

Dashboard Filters

Overall Averages (Selected Period)

  • No data in selected range.

Log daily data and select a date range to view the dashboard.

"Smart" Insights & Recommendations

  • No data to analyze.

No logs available or found for the selected date range. Please add logs in Tab 1.

'; const dashboardDisplayEl = document.getElementById('shpi-dashboard-display'); const insightsListEl = document.getElementById('shpi-insights-list'); const avgSummaryEl = document.getElementById('shpi-average-summary-list'); if (shpiSessionLogs.length === 0 && shpiCurrentTabIndex === 1) { if(dashboardDisplayEl) dashboardDisplayEl.innerHTML = noDataMsg; if(insightsListEl) insightsListEl.innerHTML = '
  • No data to analyze.
  • '; if(avgSummaryEl) avgSummaryEl.innerHTML = '
  • No data for averages.
  • '; Object.values(shpiChartInstances).forEach(chart => chart ? chart.destroy() : null); return; } const startDateStr = document.getElementById('shpi-analysis-start-date').value; const endDateStr = document.getElementById('shpi-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 = shpiSessionLogs.filter(log => log.date >= startDate && log.date <= endDate); if (filteredLogs.length === 0 && shpiCurrentTabIndex === 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(shpiChartInstances).forEach(chart => chart ? chart.destroy() : null); return; } // Calculate Averages if(avgSummaryEl){ if(filteredLogs.length > 0){ const calcAvg = (key) => filteredLogs.reduce((s,l)=>s+l[key],0)/filteredLogs.length; avgSummaryEl.innerHTML = `
  • Avg. Sleep: ${calcAvg('sleepHours').toFixed(1)}h (Quality: ${calcAvg('sleepQuality').toFixed(1)}/5)
  • Avg. Mood: ${calcAvg('mood').toFixed(1)}/5 | Avg. Stress: ${calcAvg('stressLevel').toFixed(1)}/5 | Avg. Energy: ${calcAvg('energyLevel').toFixed(1)}/5
  • Avg. Tasks Completed: ${calcAvg('tasksCompleted').toFixed(1)}
  • Avg. Productivity: ${calcAvg('productivity').toFixed(1)}/5 | Avg. Focus: ${calcAvg('focus').toFixed(1)}/5
  • Avg. Physical Activity: ${calcAvg('physicalActivity').toFixed(1)} min
  • `; } else { avgSummaryEl.innerHTML = '
  • No data in range for averages.
  • '; } } // Prepare chart data const chartData = (key) => filteredLogs.map(log => ({x: log.date, y: log[key]})); if(dashboardDisplayEl) dashboardDisplayEl.innerHTML = `

    Sleep Duration & Quality

    Mood Over Time

    Stress Level Over Time

    Energy Level Over Time

    Productivity Rating Over Time

    Focus Level Over Time

    Physical Activity (min)

    `; // Render Charts shpiRenderLineChart('shpi-mood-chart', chartData('mood'), 'Mood (1-5)', 'var(--success-color)', 5); shpiRenderLineChart('shpi-stress-chart', chartData('stressLevel'), 'Stress (1-5)', 'var(--danger-color)', 5); shpiRenderLineChart('shpi-energy-chart', chartData('energyLevel'), 'Energy (1-5)', 'var(--accent-color)', 5); shpiRenderLineChart('shpi-productivity-chart', chartData('productivity'), 'Productivity (1-5)', 'var(--primary-color)', 5); shpiRenderLineChart('shpi-focus-chart', chartData('focus'), 'Focus (1-5)', 'var(--dark-color)', 5); shpiRenderLineChart('shpi-activity-chart', chartData('physicalActivity'), 'Physical Activity (min)', 'var(--secondary-color)'); const sleepQualityData = filteredLogs.map(log => ({x: log.date, y: log.sleepQuality})); const sleepHoursData = filteredLogs.map(log => ({x: log.date, y: log.sleepHours})); const sleepCtx = document.getElementById('shpi-sleep-chart'); if (sleepCtx) { if (shpiChartInstances['shpi-sleep-chart']) shpiChartInstances['shpi-sleep-chart'].destroy(); shpiChartInstances['shpi-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(--accent-color)', yAxisID: 'yHours', tension: 0.1 } ]}, options: { responsive: true, maintainAspectRatio: false, interaction: { mode: 'index', intersect: 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 >= 5) { // Need some data for robust insights // Simple correlation: Sleep Quality vs Next Day Mood let goodSleepGoodMoodCount = 0; let lowSleepLowMoodCount = 0; for(let i=0; i < filteredLogs.length -1; i++){ if(filteredLogs[i].sleepQuality >=4 && filteredLogs[i+1].mood >=4) goodSleepGoodMoodCount++; if(filteredLogs[i].sleepQuality <=2 && filteredLogs[i+1].mood <=2) lowSleepLowMoodCount++; } if(goodSleepGoodMoodCount > filteredLogs.length / 4) { insightsListEl.innerHTML += `
  • Good sleep quality often seems to lead to a better mood the next day for you. Prioritize restful sleep!
  • `; insightsGeneratedCount++;} if(lowSleepLowMoodCount > filteredLogs.length / 4) { insightsListEl.innerHTML += `
  • Poor sleep quality frequently appears to impact your mood negatively the following day. Focus on improving sleep hygiene.
  • `; insightsGeneratedCount++;} const avgTasksOnActiveDays = filteredLogs.filter(l => l.physicalActivity > 0).reduce((s,l,_,a)=>s+l.tasksCompleted/a.length,0); const avgTasksOnInactiveDays = filteredLogs.filter(l => l.physicalActivity === 0).reduce((s,l,_,a)=>s+l.tasksCompleted/a.length,0); if(filteredLogs.filter(l=>l.physicalActivity > 0).length > 2 && filteredLogs.filter(l=>l.physicalActivity === 0).length > 2 && avgTasksOnActiveDays > avgTasksOnInactiveDays * 1.1){ insightsListEl.innerHTML += `
  • You tend to complete more tasks on days you engage in physical activity. Even short bursts of exercise can help!
  • `; insightsGeneratedCount++; } const highStressDays = filteredLogs.filter(l => l.stressLevel >=4); if(highStressDays.length > filteredLogs.length / 3){ const avgFocusOnHighStress = highStressDays.reduce((s,l)=>s+l.focus,0) / highStressDays.length; const avgFocusOverall = filteredLogs.reduce((s,l)=>s+l.focus,0) / filteredLogs.length; if(avgFocusOnHighStress < avgFocusOverall * 0.8) {insightsListEl.innerHTML += `
  • High stress days show a noticeable drop in your average focus level. Consider stress-reduction techniques on demanding days.
  • `; insightsGeneratedCount++;} } } if(insightsGeneratedCount === 0 && filteredLogs.length > 0) insightsListEl.innerHTML += `
  • Consistent logging will reveal more personalized insights. Pay attention to how different factors influence each other in your charts.
  • `; else if (filteredLogs.length === 0) insightsListEl.innerHTML += `
  • No data in selected range to provide insights.
  • `; } } function shpiRenderLineChart(canvasId, dataPoints, label, color, suggestedMax = undefined) { const ctx = document.getElementById(canvasId); if (!ctx) return; if (shpiChartInstances[canvasId]) shpiChartInstances[canvasId].destroy(); shpiChartInstances[canvasId] = new Chart(ctx.getContext('2d'), { type: 'line', data: { datasets: [{ label: label, data: dataPoints, borderColor: color, tension: 0.1, fill: false, borderWidth: 2 }] }, options: { responsive: true, maintainAspectRatio: false, scales: { x: { type: 'time', time: { unit: 'day', tooltipFormat: 'MMM dd, yy', displayFormats: {'day': 'MMM dd'} } }, y: { beginAtZero: false, suggestedMin:1, suggestedMax: suggestedMax, title: {display:true, text:label.split('(')[0].trim()}} } } }); } // PDF Download function shpiDownloadPDF() { const dashboardDisplayEl = document.getElementById('shpi-dashboard-display'); if (!dashboardDisplayEl || dashboardDisplayEl.innerHTML.includes("Log daily data") || shpiSessionLogs.length === 0) { alert("Please log some data and view the dashboard first."); return; } const analysisStartDate = document.getElementById('shpi-analysis-start-date').value; const analysisEndDate = document.getElementById('shpi-analysis-end-date').value; let pdfHTML = `

    Healthy Productivity Insights Report

    `; pdfHTML += `

    Analysis Period: ${analysisStartDate} to ${analysisEndDate}

    `; const avgSummaryContent = document.getElementById('shpi-average-summary-list').outerHTML; if(avgSummaryContent) pdfHTML += `

    Overall Averages (Selected Period)

    ${avgSummaryContent}`; const chartsToInclude = [ {instance: shpiChartInstances['shpi-sleep-chart'], title: "Sleep Duration & Quality"}, {instance: shpiChartInstances['shpi-mood-chart'], title: "Mood Over Time"}, {instance: shpiChartInstances['shpi-stress-chart'], title: "Stress Level Over Time"}, {instance: shpiChartInstances['shpi-energy-chart'], title: "Energy Level Over Time"}, {instance: shpiChartInstances['shpi-productivity-chart'], title: "Productivity Rating Over Time"}, {instance: shpiChartInstances['shpi-focus-chart'], title: "Focus Level Over Time"}, {instance: shpiChartInstances['shpi-activity-chart'], title: "Physical Activity (min)"} ]; chartsToInclude.forEach(chartInfo => { if(chartInfo.instance){ try { // Adding a border to charts in PDF for better visual separation pdfHTML += `

    ${chartInfo.title}

    `; } catch (e) { console.error("Error converting chart to image for PDF: ", chartInfo.title, e); } } }); const insightsContent = document.getElementById('shpi-insights-list').outerHTML; if(insightsContent) pdfHTML += `

    "Smart" Insights & Recommendations

    ${insightsContent}
    `; const filteredLogsForPDF = shpiSessionLogs.filter(log => { const logDateOnly = log.date.toISOString().split('T')[0]; return logDateOnly >= analysisStartDate && logDateOnly <= analysisEndDate; }); if (filteredLogsForPDF.length > 0 && confirm("Include detailed daily logs in PDF? This can make the PDF long.")) { pdfHTML += `

    Detailed Logs (${analysisStartDate} to ${analysisEndDate})

    `; pdfHTML += ``; filteredLogsForPDF.forEach(log => { pdfHTML += ``; }); pdfHTML += `
    DateSleep(H)Sleep(Q)StressMoodEnergyActivity(m)TasksProductivityFocusNotes
    ${log.date.toLocaleDateString()}${log.sleepHours.toFixed(1)}${log.sleepQuality} ${log.stressLevel}${log.mood}${log.energyLevel}${log.physicalActivity} ${log.tasksCompleted}${log.productivity}${log.focus} ${log.notes.substring(0,50)}${log.notes.length > 50 ? '...' : ''}
    `; } const pdfContainer = document.getElementById('shpi-report-content-for-pdf'); pdfContainer.innerHTML = pdfHTML; const opt = { margin: [0.5, 0.4, 0.5, 0.4], filename: `Healthy_Productivity_Insights_${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."); }); }
    Scroll to Top