Mood Tracking Dashboard

Mood Tracking Dashboard

Log your feelings and visualize your emotional well-being.

Your Mood Overview

Monthly Mood Calendar

Mood Distribution

${mood}

`; option.addEventListener('click', () => { document.querySelectorAll('.mood-option').forEach(el => el.classList.remove('selected')); option.classList.add('selected'); }); elements.logForm.moodSelector.appendChild(option); }); }; const renderHistoryTable = () => { elements.historyTableBody.innerHTML = ''; if (moodEntries.length === 0) { elements.historyTableBody.innerHTML = `No mood entries yet.`; return; } [...moodEntries].sort((a, b) => new Date(b.date) - new Date(a.date)).forEach((entry, index) => { const tr = document.createElement('tr'); const moodInfo = moodTypes[entry.mood]; tr.innerHTML = ` ${entry.date} ${moodInfo ? moodInfo.emoji : ''} ${entry.mood} ${entry.notes || '-'} `; elements.historyTableBody.appendChild(tr); }); }; const renderMoodChart = () => { const moodCounts = moodEntries.reduce((acc, entry) => { acc[entry.mood] = (acc[entry.mood] || 0) + 1; return acc; }, {}); const labels = Object.keys(moodCounts); const series = Object.values(moodCounts); const colors = labels.map(label => moodTypes[label].color); if (labels.length === 0) { elements.chart.innerHTML = `

No data to display. Log your mood to see a chart.

`; if(moodChart) moodChart.destroy(); moodChart = null; return; } const options = { chart: { type: 'donut', height: '100%' }, series: series, labels: labels, colors: colors, legend: { position: 'bottom' }, responsive: [{ breakpoint: 480, options: { chart: { width: '100%' } } }] }; if (moodChart) { moodChart.updateOptions(options); } else { moodChart = new ApexCharts(elements.chart, options); moodChart.render(); } }; const renderCalendar = () => { // This is a simplified calendar representation. elements.calendar.innerHTML = '

Calendar view coming soon. Check your history tab for entries.

'; // A full calendar implementation is complex; this focuses on core requirements. }; // --- IV. EVENT HANDLING & LOGIC --- const saveEntry = () => { const date = elements.logForm.date.value; const selectedMoodEl = document.querySelector('.mood-option.selected'); const notes = elements.logForm.notes.value.trim(); if (!date) { showMessage('Please select a date.', 'error'); return; } if (!selectedMoodEl) { showMessage('Please select a mood.', 'error'); return; } const mood = selectedMoodEl.dataset.mood; // Remove any existing entry for the same date before adding the new one moodEntries = moodEntries.filter(entry => entry.date !== date); moodEntries.push({ date, mood, notes }); saveToLocalStorage(); renderAll(); showMessage('Mood entry saved successfully!'); switchTab('dashboard'); // Switch to dashboard after saving }; window.deleteEntry = (date) => { moodEntries = moodEntries.filter(entry => entry.date !== date); saveToLocalStorage(); renderAll(); showMessage('Entry deleted.', 'success'); }; const downloadPdf = async () => { const { jsPDF } = window.jspdf; const title = "Mood History Report"; // Create a clean table for PDF export let tableHtml = `

${title}

`; [...moodEntries].sort((a, b) => new Date(b.date) - new Date(a.date)).forEach(entry => { // Basic sanitation for notes to prevent HTML issues const notesText = entry.notes ? entry.notes.replace(//g, ">") : ''; tableHtml += ``; }); tableHtml += `
DateMoodNotes
${entry.date}${entry.mood}${notesText}
`; elements.historyTableForPdf.innerHTML = tableHtml; showMessage('Generating PDF, please wait...'); elements.downloadPdfBtn.disabled = true; setTimeout(async () => { try { const canvas = await html2canvas(elements.historyTableForPdf, { scale: 2, useCORS: true }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const margin = 15; const contentWidth = pdfWidth - (2 * margin); const imgProps = pdf.getImageProperties(imgData); const aspectRatio = imgProps.height / imgProps.width; let finalImgHeight = contentWidth * aspectRatio; pdf.addImage(imgData, 'PNG', margin, margin, contentWidth, finalImgHeight); pdf.save('mood-history.pdf'); showMessage('PDF downloaded successfully!', 'success'); } catch (error) { console.error("Error generating PDF:", error); showMessage('Failed to generate PDF.', 'error'); } finally { elements.downloadPdfBtn.disabled = false; elements.historyTableForPdf.innerHTML = ''; // Clean up } }, 500); }; // --- V. INITIALIZATION --- elements.logForm.date.valueAsDate = new Date(); populateMoodSelector(); loadFromLocalStorage(); renderAll(); updateNavButtons(); elements.logForm.saveBtn.addEventListener('click', saveEntry); elements.downloadPdfBtn.addEventListener('click', downloadPdf); elements.nextTabBtn.addEventListener('click', () => navigateTabs(1)); elements.prevTabBtn.addEventListener('click', () => navigateTabs(-1)); });
Scroll to Top