Home Improvement Blog Post Generator

Home Improvement Blog Post Generator

Create clear, step-by-step DIY project guides.

Project Overview

Materials List

Tools List

The Process

Step-by-Step Instructions

Generated Project Guide

Copied to clipboard!

${data.conclusion}

`; } function showMessage() { messageBox.classList.remove('opacity-0', 'translate-y-10'); messageBox.classList.add('opacity-100', 'translate-y-0'); setTimeout(() => { messageBox.classList.remove('opacity-100', 'translate-y-0'); messageBox.classList.add('opacity-0', 'translate-y-10'); }, 2000); } function generateDIYPdf() { const { jsPDF } = window.jspdf; const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const data = getFormData(); const pageW = pdf.internal.pageSize.getWidth(); const pageH = pdf.internal.pageSize.getHeight(); const margin = 20; const contentWidth = pageW - (margin * 2); let y = 0; const lineH = 7; const addHeaderFooter = () => { const pageCount = pdf.internal.getNumberOfPages(); for (let i = 1; i <= pageCount; i++) { pdf.setPage(i); pdf.setFontSize(9); pdf.setTextColor('#9ca3af'); if (i > 1) { pdf.text(data.title, margin, 12); } pdf.text(`Page ${i}`, pageW - margin, pageH - 10, { align: 'right' }); } }; const checkBreak = (needed = 20) => { if (y + needed > pageH - margin) { pdf.addPage(); y = margin; } }; const addText = (text, options = {}) => { const { size=11, style='normal', color='#374151', indent=0, spacing=1 } = options; if (!text && text !== '') return; checkBreak(15); pdf.setFontSize(size); pdf.setFont('helvetica', style); pdf.setTextColor(color); const splitText = pdf.splitTextToSize(text, contentWidth - indent); pdf.text(splitText, margin + indent, y); y += (splitText.length * lineH * 0.75) + (lineH * spacing); }; const addSectionHeader = (title) => { y += lineH * 1.5; checkBreak(20); pdf.setFontSize(16); pdf.setFont('helvetica', 'bold'); pdf.setTextColor('#047857'); // emerald-700 pdf.text(title, margin, y); y += lineH * 1.5; }; // --- Build PDF Document --- // Page 1: Title Page pdf.setFillColor('#ecfdf5'); // emerald-50 pdf.rect(0, 0, pageW, 60, 'F'); pdf.setFontSize(24); pdf.setFont('helvetica', 'bold'); pdf.setTextColor('#064e3b'); // emerald-900 const titleLines = pdf.splitTextToSize(data.title, contentWidth); pdf.text(titleLines, margin, 35); y = 80; addText(`Difficulty: ${data.difficulty} | Est. Time: ${data.time} | Est. Cost: $${data.cost}`, { size: 12, color: '#4b5563' }); y+=5; // Intro addSectionHeader("Introduction"); addText(data.introduction); // Supplies checkBreak(data.materials.length * lineH + data.tools.length * lineH + 40); addSectionHeader("Supplies Needed"); let initialY = y; let halfWidth = contentWidth / 2 - 5; addText('Materials:', {style: 'bold', size: 12}); data.materials.forEach(item => addText(`• ${item}`, {indent: 2})); y = initialY; pdf.setX(margin + halfWidth + 10); addText('Tools:', {style: 'bold', size: 12}); data.tools.forEach(item => addText(`• ${item}`, {indent: 2})); // Instructions addSectionHeader("Instructions"); data.steps.forEach((step, index) => { checkBreak(25); addText(`Step ${index + 1}: ${step.title}`, { style: 'bold', size: 14, color: '#111827', spacing: 0.5 }); addText(step.description, {spacing: 1.5, indent: 5}); }); // Conclusion addSectionHeader("Conclusion"); addText(data.conclusion); addHeaderFooter(); pdf.save(`DIY_${data.title.replace(/\s+/g, '_').substring(0,20)}.pdf`); } // --- Event Listeners & Init --- tabs.forEach(tab => tab.addEventListener('click', () => goToTab(parseInt(tab.dataset.tab)))); prevButton.addEventListener('click', () => goToTab(currentTab - 1)); nextButton.addEventListener('click', () => goToTab(currentTab + 1)); copyButton.addEventListener('click', () => { const preview = document.getElementById('report-preview-container'); if (preview) { navigator.clipboard.writeText(preview.innerText).then(() => { showMessage(); }).catch(err => console.error('Copy failed: ', err)); } }); pdfDownloadButton.addEventListener('click', generateDIYPdf); updateTabUI(); });
Scroll to Top