Press Release Draft Builder

Press Release Draft Builder

1. Release Timing
2. Headline
3. Dateline
4. Body Content
5. Boilerplate
6. Media Contact

${data.body}

${quoteHTML}
About ${data.contact.name.split(' ')[0]} Corp.

${data.boilerplate}

###
Media Contact:

${data.contact.name}
${data.contact.title}
${data.contact.email}
${data.contact.phone}

`; } function downloadPDF() { const { jsPDF } = window.jspdf; const doc = new jsPDF(); const data = getFormData(); const pageHeight = doc.internal.pageSize.height; const pageWidth = doc.internal.pageSize.width; const margin = 20; const maxWidth = pageWidth - (margin * 2); let currentY = margin; doc.setFont('Times', 'normal'); const checkPageBreak = (spaceNeeded) => { if (currentY + spaceNeeded > pageHeight - margin) { doc.addPage(); currentY = margin; } }; // Helper to add text and increment Y const addText = (text, options, yIncrement) => { checkPageBreak(yIncrement); doc.setFont(options.font || 'Times', options.style || 'normal'); doc.setFontSize(options.size || 11); doc.setTextColor(options.color || '#000000'); const lines = doc.splitTextToSize(text, options.maxWidth || maxWidth); doc.text(lines, options.x || (options.align === 'center' ? pageWidth / 2 : margin), currentY, { align: options.align || 'left' }); currentY += (lines.length * (options.size * 0.5)) + yIncrement; }; // --- PDF Content --- addText(data.releaseTiming, { align: 'center', style: 'bold', size: 12 }, 10); addText(data.headline, { align: 'center', style: 'bold', size: 16 }, 10); if (data.subheadline) { addText(data.subheadline, { align: 'center', style: 'bold', size: 12, color: '#444444' }, 15); } // Dateline + Intro const datelineText = data.dateline.replace(//g, '').replace(/<\/strong>/g, ''); addText(`${datelineText} -- ${data.intro.replace(/
/g, '\n')}`, { size: 12 }, 10); // Body addText(data.body.replace(/
/g, '\n'), { size: 12 }, 10); // Quote if (data.quote) { checkPageBreak(30); doc.setFont('Times', 'italic'); doc.setFontSize(12); const quoteLines = doc.splitTextToSize(`"${data.quote}"`, maxWidth - 20); doc.text(quoteLines, margin + 10, currentY); currentY += (quoteLines.length * (12 * 0.5)) + 5; doc.setFont('Times', 'bold'); const attribLines = doc.splitTextToSize(`— ${data.quoteAttrib}`, maxWidth - 20); doc.text(attribLines, margin + 15, currentY); currentY += (attribLines.length * (12 * 0.5)) + 15; } // Boilerplate addText("About Acme Corp.", { style: 'bold', size: 12 }, 8); addText(data.boilerplate.replace(/
/g, '\n'), { size: 12 }, 10); // End addText("###", { align: 'center', style: 'bold', size: 12 }, 15); // Contact addText("Media Contact:", { style: 'bold', size: 12 }, 8); addText( `${data.contact.name}\n${data.contact.title}\n${data.contact.email}\n${data.contact.phone}`, { size: 12 }, 10 ); doc.save('press-release.pdf'); } // --- Tab Navigation --- function switchTab(tabIndex) { tabs.forEach((tab, index) => { tab.classList.toggle('active', index === tabIndex); contents[index].classList.toggle('active', index === tabIndex); }); currentTab = tabIndex; updateNavButtons(); } function updateNavButtons() { prevBtn.disabled = currentTab === 0; nextBtn.disabled = currentTab === tabs.length - 1; } tabs.forEach((tab, index) => { tab.addEventListener('click', () => switchTab(index)); }); nextBtn.addEventListener('click', () => { if (currentTab < tabs.length - 1) switchTab(currentTab + 1); }); prevBtn.addEventListener('click', () => { if (currentTab > 0) switchTab(currentTab - 1); }); // --- Event Listeners --- generateBtn.addEventListener('click', () => { // IV.D.1: This is type="button" renderReviewSheet(); switchTab(1); // Switch to review tab }); pdfDownloadBtn.addEventListener('click', downloadPDF); // --- Initial Setup --- setInitialDate(); updateNavButtons(); });
Scroll to Top