Personal Well-Being Tracker

Personal Well-Being Tracker

New Well-Being Check-in

Self-Assessment

Sleep & Physical Health

Activities

Reflection

Recent Check-in Log

DateMoodStressEnergySleep(H)Sleep(Q)Phys. Act.Mindful.Actions

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

Dashboard Filters

Well-Being Averages (Selected Period)

No data in selected range to calculate averages.

Log check-ins and select a date range to view the dashboard charts.

Key Insights & Gentle Reminders

  • No data to analyze.
'; document.getElementById('pwbt-insights-list').innerHTML = '
  • No data to analyze.
  • '; Object.values(pwbtChartInstances).forEach(chart => chart ? chart.destroy() : null); return; } // Calculate Averages const avgSummaryContainer = document.getElementById('pwbt-average-summary-cards'); if (filteredLogs.length > 0) { const avgMood = filteredLogs.reduce((sum,l)=>sum+l.mood,0)/filteredLogs.length; const avgStress = filteredLogs.reduce((sum,l)=>sum+l.stressLevel,0)/filteredLogs.length; const avgEnergy = filteredLogs.reduce((sum,l)=>sum+l.energyLevel,0)/filteredLogs.length; const avgSleepHours = filteredLogs.reduce((sum,l)=>sum+l.sleepHours,0)/filteredLogs.length; const avgSleepQuality = filteredLogs.reduce((sum,l)=>sum+l.sleepQuality,0)/filteredLogs.length; avgSummaryContainer.innerHTML = `

    Avg Mood: ${avgMood.toFixed(1)}/5

    Avg Stress: ${avgStress.toFixed(1)}/5

    Avg Energy: ${avgEnergy.toFixed(1)}/5

    Avg Sleep: ${avgSleepHours.toFixed(1)}hrs (Quality: ${avgSleepQuality.toFixed(1)}/5)

    `; } else { avgSummaryContainer.innerHTML = '

    No data in selected range to calculate averages.

    '; } // Prepare chart data const moodData = filteredLogs.map(log => ({x: log.datetime, y: log.mood})); const stressData = filteredLogs.map(log => ({x: log.datetime, y: log.stressLevel})); const energyData = filteredLogs.map(log => ({x: log.datetime, y: log.energyLevel})); const sleepHoursData = filteredLogs.map(log => ({x: log.datetime, y: log.sleepHours})); const sleepQualityData = filteredLogs.map(log => ({x: log.datetime, y: log.sleepQuality})); const physActivityData = filteredLogs.map(log => ({x: log.datetime, y: log.physActivityDuration})); const mindfulnessData = filteredLogs.map(log => ({x: log.datetime, y: log.mindfulnessDuration})); document.getElementById('pwbt-dashboard-display').innerHTML = `

    Mood Over Time

    Stress Level Over Time

    Energy Level Over Time

    Sleep (Hours & Quality)

    Physical Activity Duration (min)

    Mindfulness/Relaxation Duration (min)

    `; // Render Charts pwbtRenderLineChart('pwbt-mood-chart', moodData, 'Mood (1-5)', 'var(--success-color)'); pwbtRenderLineChart('pwbt-stress-chart', stressData, 'Stress (1-5)', 'var(--danger-color)'); pwbtRenderLineChart('pwbt-energy-chart', energyData, 'Energy (1-5)', 'var(--info-color)'); pwbtRenderDualLineChart('pwbt-sleep-chart', sleepHoursData, 'Hours Slept', sleepQualityData, 'Sleep Quality (1-5)'); pwbtRenderBarChart('pwbt-phys-activity-chart', physActivityData, 'Physical Activity (min)', 'var(--accent-color)'); pwbtRenderBarChart('pwbt-mindfulness-chart', mindfulnessData, 'Mindfulness/Relaxation (min)', 'var(--primary-color)'); // Generate Insights const insightsListEl = document.getElementById('pwbt-insights-list'); insightsListEl.innerHTML = ''; let insightsGenerated = 0; if (filteredLogs.length >= 3) { // Need some data for meaningful insights const avgStress = filteredLogs.reduce((sum,l)=>sum+l.stressLevel,0)/filteredLogs.length; const avgSleepQ = filteredLogs.reduce((sum,l)=>sum+l.sleepQuality,0)/filteredLogs.length; const avgSleepHours = filteredLogs.reduce((sum,l)=>sum+l.sleepHours,0)/filteredLogs.length; const avgEnergy = filteredLogs.reduce((sum,l)=>sum+l.energyLevel,0)/filteredLogs.length; const physActivityDays = filteredLogs.filter(l => l.physActivityDuration > 15).length; if(avgStress > 3.5) { insightsListEl.innerHTML += `
  • Your average stress level (${avgStress.toFixed(1)}/5) is on the higher side. Consider incorporating more stress-reducing activities like mindfulness or ensuring adequate breaks.
  • `; insightsGenerated++;} if(avgSleepQ < 2.5 || avgSleepHours < 6.5) { insightsListEl.innerHTML += `
  • Average sleep quality (${avgSleepQ.toFixed(1)}/5) or duration (${avgSleepHours.toFixed(1)}hrs) appears low. Aim for 7-9 hours of quality sleep, as it significantly impacts mood and energy.
  • `; insightsGenerated++;} if(avgEnergy < 2.5) { insightsListEl.innerHTML += `
  • Low average energy (${avgEnergy.toFixed(1)}/5) can be linked to sleep, stress, or diet. Review these areas.
  • `; insightsGenerated++;} if(physActivityDays < filteredLogs.length / 2 && filteredLogs.length >= 5) { insightsListEl.innerHTML += `
  • Physical activity was logged on less than half the days in this period. Even short bursts of activity (15-30 min) can boost mood and energy.
  • `; insightsGenerated++;} // Simple trend check: compare first third to last third of data for mood const third = Math.floor(filteredLogs.length / 3); if (third >= 1) { const firstThirdMoodAvg = filteredLogs.slice(0, third).reduce((s, l) => s + l.mood, 0) / third; const lastThirdMoodAvg = filteredLogs.slice(-third).reduce((s, l) => s + l.mood, 0) / third; if (lastThirdMoodAvg > firstThirdMoodAvg + 0.5) { insightsListEl.innerHTML += `
  • Positive trend noted: Your mood seems to be improving over this period!
  • `; insightsGenerated++;} else if (lastThirdMoodAvg < firstThirdMoodAvg - 0.5) { insightsListEl.innerHTML += `
  • Observation: Your mood shows a declining trend in this period. Reflect on potential contributing factors.
  • `; insightsGenerated++;} } } if(insightsGenerated === 0 && filteredLogs.length > 0) insightsListEl.innerHTML += `
  • Consistent logging helps identify personal well-being patterns. Keep tracking to see what works for you!
  • `; else if (filteredLogs.length === 0) insightsListEl.innerHTML += `
  • No data in the selected range to provide insights.
  • `; } function pwbtRenderLineChart(canvasId, dataPoints, label, color) { /* ... (Same as sptaRenderLineChart, using pwbtChartInstances) ... */ const ctx = document.getElementById(canvasId); if (!ctx) return; if (pwbtChartInstances[canvasId]) pwbtChartInstances[canvasId].destroy(); pwbtChartInstances[canvasId] = new Chart(ctx.getContext('2d'), { type: 'line', data: { datasets: [{ label: label, data: dataPoints, borderColor: color, tension: 0.1, fill: false, pointRadius: 2, pointHoverRadius: 5 }] }, 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: (label.includes('(1-5)')) ? 5 : (label.includes('(1-10)') ? 10 : undefined), title: {display:true, text:label.split('(')[0].trim()} } } } }); } function pwbtRenderDualLineChart(canvasId, data1, label1, data2, label2) { const ctx = document.getElementById(canvasId); if (!ctx) return; if (pwbtChartInstances[canvasId]) pwbtChartInstances[canvasId].destroy(); pwbtChartInstances[canvasId] = new Chart(ctx.getContext('2d'), { type: 'line', data: { datasets: [ { label: label1, data: data1, borderColor: 'var(--primary-color)', yAxisID: 'yHours', tension: 0.1, fill:false, pointRadius: 2 }, { label: label2, data: data2, borderColor: 'var(--accent-color)', yAxisID: 'yQuality', tension: 0.1, fill:false, pointRadius: 2 } ] }, options: { responsive: true, maintainAspectRatio: false, scales: { x: { type: 'time', time: { unit: 'day', tooltipFormat: 'MMM dd, yy' } }, yHours: { type: 'linear', position: 'left', title: {display:true, text:'Hours Slept'}, suggestedMin:0, suggestedMax:12}, yQuality: { type: 'linear', position: 'right', title: {display:true, text:'Quality (1-5)'}, min:1, max:5, grid:{drawOnChartArea:false} } } } }); } function pwbtRenderBarChart(canvasId, dataPoints, label, color) { // dataPoints = [{x: Date, y: value}] const ctx = document.getElementById(canvasId); if (!ctx) return; if (pwbtChartInstances[canvasId]) pwbtChartInstances[canvasId].destroy(); pwbtChartInstances[canvasId] = new Chart(ctx.getContext('2d'), { type: 'bar', data: { datasets: [{ label: label, data: dataPoints, backgroundColor: color }] }, options: { responsive: true, maintainAspectRatio: false, scales: { x: { type: 'time', time: { unit: 'day' } }, y: { beginAtZero: true, title: {display:true, text:"Duration (min)"}} } } }); } // PDF Download function pwbtDownloadPDF() { /* ... (Similar to sptaDownloadPDF, adapt for well-being data and charts) ... */ if (pwbtWellBeingLogs.length === 0 || !document.getElementById('pwbt-mood-chart')) { // Check if dashboard has been rendered alert("Please log some data and view the dashboard first."); return; } const analysisStartDate = document.getElementById('pwbt-analysis-start-date').value; const analysisEndDate = document.getElementById('pwbt-analysis-end-date').value; let pdfHTML = `

    Personal Well-Being Report

    `; pdfHTML += `

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

    `; const avgSummaryHTML = document.getElementById('pwbt-average-summary-cards').innerHTML; if(avgSummaryHTML && !avgSummaryHTML.includes("No data")) pdfHTML += `

    Well-Being Averages

    ${avgSummaryHTML}`; const chartsToInclude = [ {instance: pwbtChartInstances['pwbt-mood-chart'], title: "Mood Over Time"}, {instance: pwbtChartInstances['pwbt-stress-chart'], title: "Stress Level Over Time"}, {instance: pwbtChartInstances['pwbt-energy-chart'], title: "Energy Level Over Time"}, {instance: pwbtChartInstances['pwbt-sleep-chart'], title: "Sleep (Hours & Quality)"}, {instance: pwbtChartInstances['pwbt-phys-activity-chart'], title: "Physical Activity Duration"}, {instance: pwbtChartInstances['pwbt-mindfulness-chart'], title: "Mindfulness/Relaxation Duration"} ]; chartsToInclude.forEach(chartInfo => { if(chartInfo.instance){ pdfHTML += `

    ${chartInfo.title}

    `; } }); const insightsContent = document.getElementById('pwbt-insights-list').outerHTML; if(insightsContent && !insightsContent.includes("No data")) pdfHTML += `

    Key Insights & Gentle Reminders

    ${insightsContent}
    `; const filteredLogsForPDF = pwbtWellBeingLogs.filter(log => { const logDateOnly = log.datetime.toISOString().split('T')[0]; return logDateOnly >= analysisStartDate && logDateOnly <= analysisEndDate; }); if (filteredLogsForPDF.length > 0) { pdfHTML += `

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

    `; pdfHTML += ``; filteredLogsForPDF.forEach(log => { pdfHTML += ``; }); pdfHTML += `
    DateMoodStressEnergySleep(H)Sleep(Q)Phys.Act(m)Mindful(m)HydrationPositive
    ${log.datetime.toLocaleDateString()}${log.mood}${log.stressLevel}${log.energyLevel} ${log.sleepHours.toFixed(1)}${log.sleepQuality}${log.physActivityDuration}${log.mindfulnessDuration} ${log.hydration}${log.positiveMoment.substring(0,30)}${log.positiveMoment.length > 30 ? '...' : ''}
    `; } const pdfContainer = document.getElementById('pwbt-report-content-for-pdf'); pdfContainer.innerHTML = pdfHTML; const opt = { margin: [0.5, 0.3, 0.5, 0.3], filename: `WellBeing_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."); }); }
    Scroll to Top