let journalCurrentDate = ''; async function renderJournal() { const today = new Date().toISOString().split('T')[0]; journalCurrentDate = today; const content = document.getElementById('pageContent'); content.innerHTML = `
0
Total Entries
0
Words Today
0
Day Streak
${formatDateDisplay(today)}
Auto-save on
`; loadJournalEntry(today); loadJournalEntries(); } function formatDateDisplay(dateStr) { const d = new Date(dateStr + 'T00:00:00'); return d.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); } let journalSaveTimer = null; function scheduleJournalSave() { if (journalSaveTimer) clearTimeout(journalSaveTimer); journalSaveTimer = setTimeout(saveJournalEntry, 2000); const status = document.getElementById('journalSaveStatus'); if (status) status.textContent = 'Unsaved changes...'; } async function saveJournalEntry() { const textarea = document.getElementById('journalText'); if (!textarea) return; const content = textarea.value; const date = journalCurrentDate; try { await api.saveJournalEntry(date, content); const status = document.getElementById('journalSaveStatus'); if (status) status.textContent = 'Saved ✓'; const words = content.trim() ? content.trim().split(/\s+/).length : 0; const wc = document.getElementById('journalWordCount'); if (wc) wc.textContent = words; } catch (err) { const status = document.getElementById('journalSaveStatus'); if (status) status.textContent = 'Save failed: ' + err.message; console.error('Journal save error:', err); } } async function loadJournalEntry(date) { journalCurrentDate = date; const label = document.getElementById('journalDateLabel'); if (label) label.textContent = formatDateDisplay(date); const textarea = document.getElementById('journalText'); if (!textarea) return; try { const data = await api.getJournalEntry(date); textarea.value = data.content || ''; const words = data.content ? data.content.trim().split(/\s+/).length : 0; const wc = document.getElementById('journalWordCount'); if (wc) wc.textContent = words; const status = document.getElementById('journalSaveStatus'); if (status) status.textContent = 'Loaded ✓'; } catch (err) { textarea.value = ''; } } async function loadJournalEntries() { try { const data = await api.getJournalEntries(); const entries = data.entries || []; const totalEl = document.getElementById('journalTotalCount'); if (totalEl) totalEl.textContent = entries.length; let streak = 0; const today = new Date(); for (let i = 0; i < 365; i++) { const d = new Date(today); d.setDate(d.getDate() - i); const ds = d.toISOString().split('T')[0]; if (entries.some(e => e.date === ds)) { streak++; } else if (i > 0) break; } const streakEl = document.getElementById('journalStreak'); if (streakEl) streakEl.textContent = streak; const list = document.getElementById('journalEntriesList'); if (!list) return; if (entries.length === 0) { list.innerHTML = `
📓
No journal entries yet
Write your first entry above
`; return; } list.innerHTML = `
Recent Entries
${entries.slice(0, 30).map(e => ` `).join('')}
`; } catch (err) { showToast('Failed to load entries: ' + err.message, 'error'); } } async function searchJournal() { const q = document.getElementById('journalSearchInput').value.trim(); if (!q) { loadJournalEntries(); return; } try { const data = await api.searchJournal(q); const results = data.results || []; const list = document.getElementById('journalEntriesList'); if (!list) return; if (results.length === 0) { list.innerHTML = `
🔍
No results for "${escapeHtml(q)}"
`; return; } list.innerHTML = `
Results for "${escapeHtml(q)}"
${results.map(r => `
${r.date}
${escapeHtml(r.preview)}
`).join('')} `; } catch (err) { showToast('Search failed: ' + err.message, 'error'); } }