Portfolio Layout Generator

1. Customization

2. Your Information

3. Skills & Projects

Email: ${email}

` : ''} ${linkedin ? `

LinkedIn: ${linkedin}

` : ''} `; // HTML structure for different layouts let finalHtml = ''; const headerHtml = `

${name || "Your Name"}

${tagline || "Your Tagline / Job Title"}

`; switch (layout) { case 'modern': finalHtml = ` ${headerHtml}

About Me

${about || "A brief description about you..."}

Projects

${projectsHtml}

Contact

${contactHtml}

Skills

${skillsHtml}
`; break; case 'minimalist': case 'classic': default: finalHtml = ` ${headerHtml}

About Me

${about || "A brief description about you..."}

Skills

${skillsHtml}

Projects

${projectsHtml}

Contact

${contactHtml}
`; break; } previewArea.innerHTML = finalHtml; } function renderProjectControls() { controls.projectsList.innerHTML = portfolioData.projects.map((p, index) => `
Project ${index + 1}
`).join(''); } // --- DATA UPDATE FUNCTIONS --- function updateData() { portfolioData.name = controls.name.value; portfolioData.tagline = controls.tagline.value; portfolioData.about = controls.about.value; portfolioData.email = controls.email.value; portfolioData.linkedin = controls.linkedin.value; portfolioData.skills = controls.skills.value.split('\n').map(s => s.trim()).filter(Boolean); renderPortfolio(); } function handleProjectUpdate(e) { const target = e.target; if (target.matches('[data-field]')) { const card = target.closest('.plg-project-card'); const id = parseInt(card.dataset.id); const field = target.dataset.field; const project = portfolioData.projects.find(p => p.id === id); if (project) { project[field] = target.value; renderPortfolio(); } } } function addProject() { portfolioData.projects.push({ id: nextProjectId++, title: '', description: '', link: '' }); renderProjectControls(); } function removeProject(e) { if (e.target.dataset.action === 'remove-project') { const card = e.target.closest('.plg-project-card'); const id = parseInt(card.dataset.id); portfolioData.projects = portfolioData.projects.filter(p => p.id !== id); renderProjectControls(); renderPortfolio(); } } // 7. USA-relevant sample data function loadSampleData() { nextProjectId = 0; portfolioData = { name: "John Doe", tagline: "Creative UX/UI Designer & Frontend Developer", about: "A passionate and detail-oriented designer with 5+ years of experience creating intuitive and user-friendly web applications. Proficient in bridging the gap between design and development to deliver seamless digital experiences.", email: "john.doe@email.com", linkedin: "https://linkedin.com/in/johndoe-sample", skills: ["UX Research", "Figma & Sketch", "HTML & CSS", "JavaScript", "React.js", "Agile Methodologies"], projects: [ { id: nextProjectId++, title: "E-Commerce Platform Redesign", description: "Led the UX redesign for a major online retailer, resulting in a 20% increase in conversion rates.", link: "https://example.com/project1" }, { id: nextProjectId++, title: "SaaS Dashboard UI Kit", description: "Designed and developed a comprehensive UI kit for a data analytics SaaS product, improving development speed and UI consistency.", link: "https://example.com/project2" } ] }; // Update control panel inputs controls.name.value = portfolioData.name; controls.tagline.value = portfolioData.tagline; controls.about.value = portfolioData.about; controls.email.value = portfolioData.email; controls.linkedin.value = portfolioData.linkedin; controls.skills.value = portfolioData.skills.join('\n'); renderProjectControls(); renderPortfolio(); } async function handleDownloadPDF() { const originalBtnText = controls.pdfDownloadBtn.textContent; controls.pdfDownloadBtn.textContent = "Generating..."; controls.pdfDownloadBtn.disabled = true; try { const { jsPDF } = window.jspdf; container.classList.add("plg-pdf-export-mode"); const canvas = await html2canvas(previewArea, { scale: 2 }); container.classList.remove("plg-pdf-export-mode"); const imgData = canvas.toDataURL("image/png"); const pdf = new jsPDF({ orientation: "p", unit: "mm", format: "a4" }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const canvasWidth = canvas.width; const canvasHeight = canvas.height; const ratio = canvasWidth / canvasHeight; const imgWidth = pdfWidth; const imgHeight = imgWidth / ratio; pdf.addImage(imgData, "PNG", 0, 0, imgWidth, imgHeight); pdf.save(`${(portfolioData.name || "Portfolio").replace(/ /g, "_")}.pdf`); } catch (error) { console.error("PDF Generation Error:", error); alert("An error occurred while creating the PDF."); } finally { controls.pdfDownloadBtn.textContent = originalBtnText; controls.pdfDownloadBtn.disabled = false; } } // --- Initial Setup & Event Listeners --- Object.values(controls).forEach(el => { if (el && (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.tagName === 'SELECT')) { el.addEventListener('input', updateData); } }); controls.layout.addEventListener('change', renderPortfolio); controls.theme.addEventListener('change', renderPortfolio); controls.addProjectBtn.addEventListener('click', addProject); controls.projectsList.addEventListener('input', handleProjectUpdate); controls.projectsList.addEventListener('click', removeProject); controls.loadSampleBtn.addEventListener('click', loadSampleData); controls.pdfDownloadBtn.addEventListener('click', handleDownloadPDF); // Initial render on load loadSampleData(); });
Scroll to Top