Job Description Generator

Job Description Generator

Create a professional job description in minutes.

Basic Information

Core Details

Qualifications & Skills

Compensation & Benefits

Generated Job Description

Copied to clipboard!

${jobSummary}

`; if (responsibilities.trim()) htmlOutput += '

Key Responsibilities

' + formatList(responsibilities); if (qualificationsReq.trim()) htmlOutput += '

Required Qualifications

' + formatList(qualificationsReq); if (qualificationsPref.trim()) htmlOutput += '

Preferred Qualifications

' + formatList(qualificationsPref); if (salaryRange) htmlOutput += `

Compensation

The anticipated salary range for this position is ${salaryRange}.

`; if (benefits.trim()) htmlOutput += '

Benefits

' + formatList(benefits); const outputDiv = document.getElementById('pdf-output'); if (outputDiv) { outputDiv.innerHTML = htmlOutput; } } 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); } /** * Generates a professional PDF report from the form inputs. */ function generatePdfReport() { const { jsPDF } = window.jspdf; const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); // --- Get Form Data --- const companyName = document.getElementById('company-name')?.value.trim() || 'Company Name'; const jobTitle = document.getElementById('job-title')?.value.trim() || 'N/A'; const department = document.getElementById('department')?.value.trim() || 'N/A'; const location = document.getElementById('location')?.value.trim() || 'N/A'; const jobType = document.getElementById('job-type')?.value.trim() || 'N/A'; const jobSummary = document.getElementById('job-summary')?.value.trim() || ''; const responsibilities = document.getElementById('responsibilities')?.value.trim().split('\n').filter(Boolean) || []; const qualificationsReq = document.getElementById('qualifications-req')?.value.trim().split('\n').filter(Boolean) || []; const qualificationsPref = document.getElementById('qualifications-pref')?.value.trim().split('\n').filter(Boolean) || []; const salaryRange = document.getElementById('salary-range')?.value.trim() || ''; const benefits = document.getElementById('benefits')?.value.trim().split('\n').filter(Boolean) || []; // --- PDF Styling & Layout Variables --- const pageW = pdf.internal.pageSize.getWidth(); const pageH = pdf.internal.pageSize.getHeight(); const margin = 15; const contentWidth = pageW - (margin * 2); let y = 20; // Initial Y position const lineSpacing = 6; const sectionSpacing = 10; const listIndent = 5; // --- Helper Function for page breaks and text wrapping --- const addText = (text, options) => { if (y + lineSpacing > pageH - margin) { pdf.addPage(); y = margin; } const splitText = pdf.splitTextToSize(text, options.maxWidth || contentWidth); pdf.setFontSize(options.size || 10); pdf.setFont(undefined, options.style || 'normal'); pdf.setTextColor(options.color || '#374151'); // gray-700 pdf.text(splitText, options.x || margin, y, { align: options.align || 'left' }); y += (splitText.length * lineSpacing * (options.spacingMultiplier || 0.8)); }; const addSection = (title, contentArray) => { if (!contentArray || (Array.isArray(contentArray) && contentArray.length === 0) || (typeof contentArray === 'string' && !contentArray.trim())) { return; // Skip empty sections } y += sectionSpacing / 2; addText(title, { size: 12, style: 'bold', color: '#1E3A8A' }); // blue-800 y += lineSpacing / 2; if (Array.isArray(contentArray)) { contentArray.forEach(item => { addText(`• ${item}`, { x: margin + listIndent, maxWidth: contentWidth - listIndent }); }); } else { addText(contentArray, {}); } y += sectionSpacing / 2; }; // --- Build PDF Document --- // Header pdf.setFillColor('#F3F4F6'); // gray-100 pdf.rect(0, 0, pageW, 45, 'F'); addText(companyName, { size: 16, style: 'bold', color: '#111827', align: 'center', x: pageW / 2 }); y += 2; addText(jobTitle, { size: 20, style: 'bold', color: '#1D4ED8', align: 'center', x: pageW / 2 }); // blue-700 y += 4; const subheader = `Department: ${department} | Location: ${location} | Type: ${jobType}`; addText(subheader, { size: 9, color: '#4B5563', align: 'center', x: pageW / 2 }); // gray-600 y = 55; // Reset y after header // Body Sections addSection('Job Summary', jobSummary); addSection('Key Responsibilities', responsibilities); addSection('Required Qualifications', qualificationsReq); addSection('Preferred Qualifications', qualificationsPref); if(salaryRange) addSection('Compensation', `The anticipated salary range for this position is ${salaryRange}.`); addSection('Benefits', benefits); // --- Save PDF --- const fileName = `${jobTitle.replace(/\s+/g, '_').toLowerCase()}_jd.pdf`; pdf.save(fileName); } // --- Event Listeners --- 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 outputDiv = document.getElementById('pdf-output'); if(outputDiv) { const textToCopy = outputDiv.innerText; const textArea = document.createElement("textarea"); textArea.value = textToCopy; textArea.style.position = "fixed"; document.body.appendChild(textArea); textArea.focus(); textArea.select(); try { document.execCommand('copy'); showMessage(); } catch (err) { console.error('Fallback: Oops, unable to copy', err); } document.body.removeChild(textArea); } }); pdfDownloadButton.addEventListener('click', generatePdfReport); // Initialize the UI updateTabUI(); });
Scroll to Top