| |
| const pdfFileInput = document.getElementById('pdfFile'); |
| const pdfUploadArea = document.getElementById('pdfUploadArea'); |
| const uploadedFileInfo = document.getElementById('uploadedFileInfo'); |
| const fileNameElement = document.getElementById('fileName'); |
| const fileSizeElement = document.getElementById('fileSize'); |
| const removeFileButton = document.getElementById('removeFile'); |
| const uploadProgressBar = document.getElementById('uploadProgressBar'); |
| const uploadPercent = document.getElementById('uploadPercent'); |
| const convertButton = document.getElementById('convertBtn'); |
| const processingState = document.getElementById('processingState'); |
| const initialPreview = document.getElementById('initialPreview'); |
| const resultsSection = document.getElementById('resultsSection'); |
| const processingProgressBar = document.getElementById('processingProgressBar'); |
| const processingPercent = document.getElementById('processingPercent'); |
| const textPreview = document.getElementById('textPreview'); |
| const downloadButton = document.getElementById('downloadBtn'); |
| const newConversionButton = document.getElementById('newConversionBtn'); |
| const copyTextButton = document.getElementById('copyTextBtn'); |
| const toast = document.getElementById('toast'); |
| const toastMessage = document.getElementById('toastMessage'); |
| const sectionCheckboxes = document.querySelectorAll('.section-checkbox'); |
| const sectionLabels = document.querySelectorAll('.section-label'); |
|
|
| |
| const sampleResumeData = { |
| contactInfo: "Jane Doe\n(123) 456-7890\njane.doe@email.com\n123 Main Street, New York, NY 10001", |
| socialMedia: "LinkedIn: linkedin.com/in/janedoe\nGitHub: github.com/janedoe\nPortfolio: janedoe.dev", |
| workExperience: "Senior Software Engineer, Tech Solutions Inc. (2020-Present)\n- Lead development of customer-facing web applications\n- Implemented Agile methodologies improving team productivity by 30%\n- Mentored 5 junior developers\n\nSoftware Developer, Innovate Corp. (2017-2020)\n- Developed and maintained internal tools using React and Node.js\n- Reduced application load time by 40% through performance optimization\n- Collaborated with cross-functional teams to deliver projects on schedule", |
| education: "Master of Science in Computer Science\nUniversity of Technology (2015-2017)\nGPA: 3.8/4.0\n\nBachelor of Science in Information Technology\nState College (2011-2015)", |
| certifications: "AWS Certified Solutions Architect - Associate\nGoogle Professional Cloud Architect\nScrum Master Certification (CSM)", |
| skills: "Programming: JavaScript, Python, Java, C#\nFrameworks: React, Node.js, Angular, .NET\nDatabases: MySQL, MongoDB, PostgreSQL\nTools: Git, Docker, AWS, Jenkins\nSoft Skills: Leadership, Problem-solving, Communication, Team Collaboration", |
| summary: "Senior Software Engineer with 8+ years of experience in full-stack development, specializing in scalable web applications. Proven track record of leading cross-functional teams, implementing Agile methodologies, and delivering projects that improve efficiency and user experience. Passionate about mentoring junior developers and staying current with emerging technologies." |
| }; |
|
|
| |
| let currentFile = null; |
| let selectedSections = ['contactInfo', 'socialMedia', 'workExperience', 'education', 'skills', 'summary']; |
|
|
| |
| function init() { |
| |
| pdfFileInput.addEventListener('change', handleFileSelect); |
| |
| |
| pdfUploadArea.addEventListener('dragover', handleDragOver); |
| pdfUploadArea.addEventListener('dragleave', handleDragLeave); |
| pdfUploadArea.addEventListener('drop', handleDrop); |
| |
| |
| removeFileButton.addEventListener('click', removeFile); |
| |
| |
| sectionCheckboxes.forEach(checkbox => { |
| checkbox.addEventListener('change', updateSectionSelection); |
| |
| if (checkbox.checked) { |
| const label = checkbox.nextElementSibling; |
| const checkIcon = label.querySelector('.check-icon'); |
| if (checkIcon) checkIcon.classList.remove('hidden'); |
| } |
| }); |
| |
| |
| convertButton.addEventListener('click', startConversion); |
| |
| |
| downloadButton.addEventListener('click', downloadTextFile); |
| newConversionButton.addEventListener('click', resetToInitialState); |
| copyTextButton.addEventListener('click', copyTextToClipboard); |
| |
| |
| updateTextPreview(); |
| } |
|
|
| |
| function handleFileSelect(event) { |
| const file = event.target.files[0]; |
| if (file && file.type === 'application/pdf') { |
| processFile(file); |
| } else { |
| showToast('Please select a valid PDF file', 'error'); |
| } |
| } |
|
|
| |
| function handleDragOver(event) { |
| event.preventDefault(); |
| event.stopPropagation(); |
| pdfUploadArea.classList.add('dragover'); |
| } |
|
|
| |
| function handleDragLeave(event) { |
| event.preventDefault(); |
| event.stopPropagation(); |
| pdfUploadArea.classList.remove('dragover'); |
| } |
|
|
| |
| function handleDrop(event) { |
| event.preventDefault(); |
| event.stopPropagation(); |
| pdfUploadArea.classList.remove('dragover'); |
| |
| const files = event.dataTransfer.files; |
| if (files.length > 0) { |
| const file = files[0]; |
| if (file.type === 'application/pdf') { |
| processFile(file); |
| } else { |
| showToast('Please drop a valid PDF file', 'error'); |
| } |
| } |
| } |
|
|
| |
| function processFile(file) { |
| currentFile = file; |
| |
| |
| fileNameElement.textContent = file.name; |
| fileSizeElement.textContent = formatFileSize(file.size); |
| |
| |
| uploadedFileInfo.classList.remove('hidden'); |
| simulateUploadProgress(); |
| |
| |
| convertButton.disabled = false; |
| convertButton.classList.remove('opacity-50'); |
| |
| showToast(`File "${file.name}" uploaded successfully`, 'success'); |
| } |
|
|
| |
| function simulateUploadProgress() { |
| let progress = 0; |
| const interval = setInterval(() => { |
| progress += Math.random() * 15; |
| if (progress >= 100) { |
| progress = 100; |
| clearInterval(interval); |
| } |
| |
| uploadProgressBar.style.width = `${progress}%`; |
| uploadPercent.textContent = `${Math.round(progress)}%`; |
| }, 100); |
| } |
|
|
| |
| function formatFileSize(bytes) { |
| if (bytes < 1024) return bytes + ' B'; |
| else if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'; |
| else return (bytes / (1024 * 1024)).toFixed(1) + ' MB'; |
| } |
|
|
| |
| function removeFile() { |
| currentFile = null; |
| pdfFileInput.value = ''; |
| uploadedFileInfo.classList.add('hidden'); |
| convertButton.disabled = true; |
| convertButton.classList.add('opacity-50'); |
| } |
|
|
| |
| function updateSectionSelection(event) { |
| const checkbox = event.target; |
| const label = checkbox.nextElementSibling; |
| const checkIcon = label.querySelector('.check-icon'); |
| |
| if (checkbox.checked) { |
| checkIcon.classList.remove('hidden'); |
| selectedSections.push(checkbox.id); |
| } else { |
| checkIcon.classList.add('hidden'); |
| selectedSections = selectedSections.filter(id => id !== checkbox.id); |
| } |
| |
| |
| if (resultsSection.classList.contains('hidden') === false) { |
| updateTextPreview(); |
| } |
| } |
|
|
| |
| function startConversion() { |
| if (!currentFile && selectedSections.length === 0) { |
| showToast('Please upload a PDF and select at least one section', 'error'); |
| return; |
| } |
| |
| if (!currentFile) { |
| showToast('Please upload a PDF file first', 'error'); |
| return; |
| } |
| |
| if (selectedSections.length === 0) { |
| showToast('Please select at least one section to include', 'error'); |
| return; |
| } |
| |
| |
| initialPreview.classList.add('hidden'); |
| processingState.classList.remove('hidden'); |
| processingState.classList.add('fade-in'); |
| |
| |
| simulateProcessing(); |
| } |
|
|
| |
| function simulateProcessing() { |
| let progress = 0; |
| const steps = document.querySelectorAll('.processing-step'); |
| |
| const interval = setInterval(() => { |
| progress += Math.random() * 8; |
| if (progress >= 100) { |
| progress = 100; |
| clearInterval(interval); |
| |
| |
| setTimeout(showResults, 500); |
| } |
| |
| |
| processingProgressBar.style.width = `${progress}%`; |
| processingPercent.textContent = `${Math.round(progress)}%`; |
| |
| |
| const stepProgress = progress / 100; |
| steps.forEach((step, index) => { |
| const stepNum = parseInt(step.getAttribute('data-step')); |
| const stepTarget = stepNum * 25; |
| const stepWidth = Math.min(Math.max(0, (progress - (stepTarget - 25)) / 25 * 100), 100); |
| step.style.width = `${stepWidth}%`; |
| }); |
| }, 200); |
| } |
|
|
| |
| function showResults() { |
| processingState.classList.add('hidden'); |
| resultsSection.classList.remove('hidden'); |
| resultsSection.classList.add('fade-in'); |
| |
| updateTextPreview(); |
| showToast('Resume successfully converted to ATS-optimized text!', 'success'); |
| } |
|
|
| ===========================\n"; |
| text += sampleResumeData.contactInfo + "\n\n"; |
| } |
| |
| if (selectedSections.includes('socialMedia')) { |
| text += "SOCIAL MEDIA & LINKS\n"; |
| text += "====================\n"; |
| text += sampleResumeData.socialMedia + "\n\n"; |
| } |
| |
| if (selectedSections.includes('workExperience')) { |
| text += "WORK EXPERIENCE\n"; |
| text += "================\n"; |
| text += sampleResumeData.workExperience + "\n\n"; |
| } |
| |
| if (selectedSections.includes('education')) { |
| text += "EDUCATION\n"; |
| text += "=========\n"; |
| text += sampleResumeData.education + "\n\n"; |
| } |
| |
| if (selectedSections.includes('certifications')) { |
| text += "CERTIFICATIONS\n"; |
| text += "==============\n"; |
| text += sampleResumeData.certifications + "\n\n"; |
| } |
| |
| if (selectedSections.includes('skills')) { |
| text += "SKILLS\n"; |
| text += "======\n"; |
| text += sampleResumeData.skills + "\n\n"; |
| } |
| |
| text += "\n=== END OF RESUME ==="; |
| text += "\n\n[This resume has been optimized for Applicant Tracking Systems by AI Resume ATS Optimizer]"; |
| |
| textPreview.textContent = text; |
| } |
| |
| // Download text file |
| function downloadTextFile() { |
| const text = textPreview.textContent; |
| const blob = new Blob([text], { type: 'text/plain' }); |
| const url = URL.createObjectURL(blob); |
| |
| const a = document.createElement('a'); |
| a.href = url; |
| a.download = 'ats_optimized_resume.txt'; |
| document.body.appendChild(a); |
| a.click(); |
| |
| setTimeout(() => { |
| document.body.removeChild(a); |
| URL.revokeObjectURL(url); |
| }, 100); |
| |
| showToast('Text file downloaded successfully!', 'success'); |
| } |
| |
| // Copy text to clipboard |
| function copyTextToClipboard() { |
| const text = textPreview.textContent; |
| |
| navigator.clipboard.writeText(text).then(() => { |
| showToast('Text copied to clipboard!', 'success'); |
| }).catch(err => { |
| console.error('Failed to copy text: ', err); |
| showToast('Failed to copy text to clipboard', 'error'); |
| }); |
| } |
| |
| // Reset to initial state |
| function resetToInitialState() { |
| // Reset file |
| removeFile(); |
| |
| // Reset sections |
| sectionCheckboxes.forEach(checkbox => { |
| if (checkbox.id !== 'certifications') { |
| checkbox.checked = true; |
| const label = checkbox.nextElementSibling; |
| const checkIcon = label.querySelector('.check-icon'); |
| checkIcon.classList.remove('hidden'); |
| } else { |
| checkbox.checked = false; |
| const label = checkbox.nextElementSibling; |
| const checkIcon = label.querySelector('.check-icon'); |
| checkIcon.classList.add('hidden'); |
| } |
| }); |
| |
| selectedSections = ['contactInfo', 'socialMedia', 'workExperience', 'education', 'skills', 'summary']; |
| |
| // Hide results and show initial preview |
| resultsSection.classList.add('hidden'); |
| initialPreview.classList.remove('hidden'); |
| initialPreview.classList.add('fade-in'); |
| |
| showToast('Ready for a new conversion!', 'success'); |
| } |
| |
| // Show toast notification |
| function showToast(message, type = 'success') { |
| toastMessage.textContent = message; |
| |
| // Set color based on type |
| if (type === 'error') { |
| toast.style.backgroundColor = '#ef4444'; |
| } else if (type === 'success') { |
| toast.style.backgroundColor = '#10b981'; |
| } else { |
| toast.style.backgroundColor = '#3b82f6'; |
| } |
| |
| // Show toast |
| toast.classList.remove('translate-y-full'); |
| |
| // Hide after 3 seconds |
| setTimeout(() => { |
| toast.classList.add('translate-y-full'); |
| }, 3000); |
| } |
| |
| // Initialize the application when DOM is loaded |
| document.addEventListener('DOMContentLoaded', init); |
| |
| // Add some interactivity to section labels |
| sectionLabels.forEach(label => { |
| label.addEventListener('click', function() { |
| this.classList.add('transform', 'scale-[1.02]', 'transition-transform'); |
| setTimeout(() => { |
| this.classList.remove('transform', 'scale-[1.02]'); |
| }, 150); |
| }); |
| }); |