`;
}).join('');
}
function renderMoodChart() {
const ctx = document.getElementById('moodChart');
if (!ctx) return;
const chartData = entries
.map(e => ({ x: new Date(e.date), y: parseInt(e.mood) }))
.sort((a, b) => a.x - b.x); // Sort by date for the chart
if (moodChart) {
moodChart.destroy();
}
moodChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
label: 'Daily Mood',
data: chartData,
borderColor: '#4F46E5',
backgroundColor: 'rgba(79, 70, 229, 0.1)',
fill: true,
tension: 0.3
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
type: 'time',
time: { unit: 'day' },
title: { display: true, text: 'Date' }
},
y: {
beginAtZero: true,
max: 5.5,
title: { display: true, text: 'Mood Level' },
ticks: {
stepSize: 1,
callback: function(value) {
const emojis = { 5: '😊', 4: '🙂', 3: '😐', 2: '😟', 1: '😭' };
return emojis[value] || value;
}
}
}
}
}
});
}
// --- PDF GENERATION --- //
function generatePDF(entry) {
const { jsPDF } = window.jspdf;
const pdf = new jsPDF({ unit: 'pt', format: 'a4' });
const moodEmojis = { '5': '😊', '4': '🙂', '3': '😐', '2': '😟', '1': '😭' };
const formattedDate = new Date(entry.date).toLocaleDateString('en-US', {
weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'
});
// Create a temporary div to render HTML content for text extraction
const tempDiv = document.createElement('div');
tempDiv.innerHTML = entry.content;
const margin = 40;
const pdfWidth = pdf.internal.pageSize.getWidth();
let y = margin;
pdf.setFontSize(18);
pdf.setFont('helvetica', 'bold');
pdf.text(`Journal Entry: ${formattedDate}`, pdfWidth / 2, y, { align: 'center' });
y += 40;
pdf.setFontSize(24);
pdf.text(`Mood: ${moodEmojis[entry.mood] || ''}`, margin, y);
y += 40;
pdf.setFontSize(12);
pdf.setFont('helvetica', 'normal');
// Split text to handle page breaks
const textLines = pdf.splitTextToSize(tempDiv.textContent, pdfWidth - margin * 2);
pdf.text(textLines, margin, y);
pdf.save(`Journal-Entry-${entry.date}.pdf`);
showNotification('PDF downloaded successfully!', 'success');
}
// --- TAB NAVIGATION --- //
function setActiveTab(index) {
if (index < 0 || index >= tabs.length) return;
tabs.forEach((tab, i) => {
tab.classList.toggle('active', i === index);
tabPanels[i].classList.toggle('hidden', i !== index);
});
currentTabIndex = index;
if (index === 2) { // Refresh chart when tab is viewed
renderMoodChart();
}
}
// --- KICK IT OFF --- //
initializeApp();
});