Political Speechwriter Assistant

Political Speechwriter Assistant

Craft compelling speeches by defining your audience, tone, and key messages.

We must focus on this core principle: ${msg}

`; }); speech += ``; speech += `

${getRandomElement(tonePhrases.closing)}

`; speechOutput.innerHTML = speech; generatedSpeechText = { topic, tone: speechTone.value, audience: targetAudience.value, messages, fullText: speechOutput.innerText }; pdfBtn.disabled = false; }; const generatePDF = () => { if (!generatedSpeechText) return; const { jsPDF } = window.jspdf; const doc = new jsPDF(); const pageHeight = doc.internal.pageSize.height; const pageWidth = doc.internal.pageSize.width; const margin = 15; const maxLineWidth = pageWidth - margin * 2; let y = margin; doc.setFont('times', 'bold'); doc.setFontSize(22); doc.text('Political Speech Draft', pageWidth / 2, y, { align: 'center' }); y += 15; doc.setDrawColor(200); doc.line(margin, y, pageWidth - margin, y); y += 10; const addMeta = (label, value) => { doc.setFontSize(11); doc.setFont('times', 'bold'); doc.text(label + ':', margin, y); doc.setFont('times', 'normal'); doc.text(value, margin + 40, y); y += 7; }; addMeta('Topic', generatedSpeechText.topic); addMeta('Tone', generatedSpeechText.tone); addMeta('Target Audience', generatedSpeechText.audience); y += 5; doc.setFontSize(12); doc.setFont('times', 'normal'); const speechLines = doc.splitTextToSize(generatedSpeechText.fullText, maxLineWidth); doc.text(speechLines, margin, y); const pageCount = doc.internal.getNumberOfPages(); for(let i = 1; i <= pageCount; i++) { doc.setPage(i); doc.setFontSize(9); doc.setTextColor(150); doc.text(`Page ${i} of ${pageCount}`, pageWidth / 2, pageHeight - 10, { align: 'center' }); } doc.save(`${generatedSpeechText.topic.replace(/\s+/g, '_')}_Speech.pdf`); }; const switchTab = (tabName) => { if (!tabs.includes(tabName)) return; currentTab = tabName; Object.values(tabContent).forEach(content => content.classList.add('hidden')); if(tabContent[tabName]) tabContent[tabName].classList.remove('hidden'); Object.values(tabButtons).forEach(button => button.classList.remove('active')); if(tabButtons[tabName]) tabButtons[tabName].classList.add('active'); updateNavButtons(); }; const updateNavButtons = () => { const currentIndex = tabs.indexOf(currentTab); prevBtn.disabled = currentIndex === 0; nextBtn.disabled = currentIndex === tabs.length - 1; }; const navigateTabs = (direction) => { const currentIndex = tabs.indexOf(currentTab); let newIndex = direction === 'next' ? Math.min(currentIndex + 1, tabs.length - 1) : Math.max(currentIndex - 1, 0); switchTab(tabs[newIndex]); }; generateBtn.addEventListener('click', generateSpeech); pdfBtn.addEventListener('click', generatePDF); window.app = { switchTab, navigateTabs, }; updateNavButtons(); });
Scroll to Top