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.
One of the most memorable parts was something we didn't plan: ${unexpected}
`; } if (feelings || favoriteMoment) { journalText += `${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); });