Travel Journal Writing Assistant
Capture your adventures with guided, reflective prompts.
This is your generated journal entry. You can go back to previous tabs to make edits before downloading.
${feelings} My favorite moment, without a doubt, was when ${favoriteMoment}
`; } journalOutputDiv.innerHTML = journalText; currentTab = tabs.length - 1; showTab(currentTab); }; const downloadPDF = () => { // Get all user inputs const location = document.getElementById('location').value.trim() || "An Unforgettable Place"; const travelDate = document.getElementById('travelDate').value; const companions = document.getElementById('companions').value.trim(); const sights = document.getElementById('sights').value.trim(); const soundsSmells = document.getElementById('soundsSmells').value.trim(); const mainActivity = document.getElementById('mainActivity').value.trim(); const unexpected = document.getElementById('unexpected').value.trim(); const feelings = document.getElementById('feelings').value.trim(); const favoriteMoment = document.getElementById('favoriteMoment').value.trim(); const filename = `Travel Journal - ${location}.pdf`; const { jsPDF } = window.jspdf; const doc = new jsPDF({ unit: 'pt', format: 'a4' }); // [FIX] REMOVED doc.addFont() calls which caused errors. // We will now use the standard built-in jsPDF fonts. const pageHeight = doc.internal.pageSize.height; const pageWidth = doc.internal.pageSize.width; const margin = 60; const contentWidth = pageWidth - margin * 2; let cursorY = margin; // Helper to add text and manage page breaks const addText = (text, options) => { if (!text) return; // [FIX] Use standard fonts like 'times' instead of custom 'Lora' const { size = 11, font = 'times', style = 'normal', spaceAfter = 12, isHeading = false } = options; doc.setFont(font, style); doc.setFontSize(size); const lines = doc.splitTextToSize(text, contentWidth); const blockHeight = lines.length * (size * 1.2) + spaceAfter; if (cursorY + blockHeight > pageHeight - margin) { doc.addPage(); cursorY = margin; } if (isHeading) cursorY += 10; doc.text(lines, margin, cursorY); cursorY += blockHeight; }; // --- Build PDF - Travel Journal Template --- // Main Title // [FIX] Use a standard font with a distinct style doc.setFont('times', 'italic'); doc.setFontSize(36); doc.text(location, pageWidth / 2, cursorY, { align: 'center' }); cursorY += 40; // Sub-header with Date and Companions if (travelDate) { const formattedDate = new Date(travelDate).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', timeZone: 'UTC' }); // [FIX] Use standard font doc.setFont('times', 'normal'); doc.setFontSize(11); doc.setTextColor(100); doc.text(formattedDate, pageWidth / 2, cursorY, { align: 'center' }); cursorY += 15; } if (companions) { // [FIX] Use standard font doc.setFont('times', 'normal'); doc.setFontSize(11); doc.setTextColor(100); doc.text(`With: ${companions}`, pageWidth / 2, cursorY, { align: 'center' }); cursorY += 30; } // Decorative Line doc.setDrawColor(200, 200, 200); doc.setLineWidth(0.5); doc.line(margin, cursorY, pageWidth - margin, cursorY); cursorY += 20; doc.setTextColor(0); // Reset text color // Content Sections addText('Setting the Scene', { size: 14, font: 'times', style: 'bold', isHeading: true }); addText(`${sights} ${soundsSmells}`, {}); addText("The Day's Adventures", { size: 14, font: 'times', style: 'bold', isHeading: true }); addText(mainActivity, {}); if(unexpected) addText(`The most unexpected thing happened: ${unexpected}`, {}); addText('Reflections', { size: 14, font: 'times', style: 'bold', isHeading: true }); addText(feelings, {}); if(favoriteMoment) addText(`My absolute favorite moment was when ${favoriteMoment}`, {}); doc.save(filename); }; // --- Event Handling --- nextButton.addEventListener('click', () => { if (currentTab < tabs.length - 2) { currentTab++; showTab(currentTab); } }); prevButton.addEventListener('click', () => { if (currentTab > 0) { currentTab--; showTab(currentTab); } }); generateButton.addEventListener('click', generateJournal); downloadPdfButton.addEventListener('click', downloadPDF); tabs.forEach(tab => { tab.addEventListener('click', () => { const tabIndex = parseInt(tab.dataset.tab, 10); if (tabIndex === tabs.length - 1 && journalOutputDiv.innerHTML.trim() === '') { generateJournal(); } else { currentTab = tabIndex; showTab(currentTab); } }); }); // --- Initialization --- showTab(0); });