| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Resume Tailor Pro</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.12.313/pdf.min.js"></script> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/mammoth/1.4.0/mammoth.browser.min.js"></script> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script> |
| <style> |
| .dropzone { |
| border: 2px dashed #3b82f6; |
| transition: all 0.3s ease; |
| } |
| .dropzone.active { |
| border-color: #10b981; |
| background-color: #f0f9ff; |
| } |
| .progress-bar { |
| transition: width 0.3s ease; |
| } |
| .resume-point { |
| transition: all 0.3s ease; |
| } |
| .resume-point.highlight { |
| background-color: #fef08a; |
| border-left: 4px solid #f59e0b; |
| } |
| .keyword-chip { |
| animation: pulse 1.5s infinite; |
| } |
| @keyframes pulse { |
| 0% { transform: scale(1); } |
| 50% { transform: scale(1.05); } |
| 100% { transform: scale(1); } |
| } |
| .fade-in { |
| animation: fadeIn 0.5s ease-in; |
| } |
| @keyframes fadeIn { |
| from { opacity: 0; transform: translateY(10px); } |
| to { opacity: 1; transform: translateY(0); } |
| } |
| </style> |
| </head> |
| <body class="bg-gray-50 min-h-screen"> |
| <div class="container mx-auto px-4 py-8 max-w-6xl"> |
| |
| <header class="text-center mb-12"> |
| <h1 class="text-4xl font-bold text-blue-600 mb-2">Resume Tailor Pro</h1> |
| <p class="text-lg text-gray-600">Transform your generic resume into a job-winning document in minutes</p> |
| <div class="w-24 h-1 bg-blue-500 mx-auto mt-4 rounded-full"></div> |
| </header> |
|
|
| |
| <div class="bg-white rounded-xl shadow-lg overflow-hidden"> |
| |
| <div class="flex justify-between px-8 py-4 bg-gray-100"> |
| <div class="step flex flex-col items-center relative w-1/4"> |
| <div class="w-10 h-10 rounded-full bg-blue-600 text-white flex items-center justify-center font-bold mb-2 z-10">1</div> |
| <span class="text-sm font-medium text-blue-600">Upload Resume</span> |
| <div class="absolute top-5 left-1/2 h-1 w-full bg-gray-300 -z-1"></div> |
| </div> |
| <div class="step flex flex-col items-center relative w-1/4"> |
| <div class="w-10 h-10 rounded-full bg-gray-300 text-white flex items-center justify-center font-bold mb-2 z-10">2</div> |
| <span class="text-sm font-medium text-gray-500">Job Description</span> |
| <div class="absolute top-5 left-1/2 h-1 w-full bg-gray-300 -z-1"></div> |
| </div> |
| <div class="step flex flex-col items-center relative w-1/4"> |
| <div class="w-10 h-10 rounded-full bg-gray-300 text-white flex items-center justify-center font-bold mb-2 z-10">3</div> |
| <span class="text-sm font-medium text-gray-500">Tailor Resume</span> |
| <div class="absolute top-5 left-1/2 h-1 w-full bg-gray-300 -z-1"></div> |
| </div> |
| <div class="step flex flex-col items-center relative w-1/4"> |
| <div class="w-10 h-10 rounded-full bg-gray-300 text-white flex items-center justify-center font-bold mb-2 z-10">4</div> |
| <span class="text-sm font-medium text-gray-500">Download</span> |
| </div> |
| </div> |
|
|
| |
| <div id="step1" class="p-8"> |
| <h2 class="text-2xl font-semibold text-gray-800 mb-6">Upload Your Resume</h2> |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-8"> |
| <div> |
| <div id="dropzone" class="dropzone rounded-lg p-8 text-center cursor-pointer h-64 flex flex-col items-center justify-center"> |
| <i class="fas fa-cloud-upload-alt text-4xl text-blue-500 mb-4"></i> |
| <p class="text-lg font-medium text-gray-700 mb-2">Drag & drop your resume here</p> |
| <p class="text-sm text-gray-500 mb-4">or</p> |
| <label for="fileInput" class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition cursor-pointer"> |
| Browse Files |
| </label> |
| <input type="file" id="fileInput" class="hidden" accept=".pdf,.doc,.docx"> |
| <p class="text-xs text-gray-500 mt-4">Supports: PDF, DOC, DOCX</p> |
| </div> |
| <div id="fileInfo" class="mt-4 hidden"> |
| <div class="flex items-center justify-between mb-2"> |
| <span class="font-medium text-gray-700 truncate max-w-xs" id="fileName"></span> |
| <button id="removeFile" class="text-red-500 hover:text-red-700"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| <div class="w-full bg-gray-200 rounded-full h-2.5"> |
| <div id="uploadProgress" class="progress-bar bg-blue-600 h-2.5 rounded-full" style="width: 0%"></div> |
| </div> |
| </div> |
| </div> |
| <div class="bg-blue-50 p-6 rounded-lg border border-blue-100"> |
| <h3 class="text-lg font-semibold text-blue-800 mb-3">Tips for Best Results</h3> |
| <ul class="space-y-3"> |
| <li class="flex items-start"> |
| <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i> |
| <span class="text-gray-700">Use a recent resume with clear section headings</span> |
| </li> |
| <li class="flex items-start"> |
| <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i> |
| <span class="text-gray-700">Ensure your document is readable (not scanned)</span> |
| </li> |
| <li class="flex items-start"> |
| <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i> |
| <span class="text-gray-700">Include measurable achievements in bullet points</span> |
| </li> |
| <li class="flex items-start"> |
| <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i> |
| <span class="text-gray-700">Remove personal information if concerned about privacy</span> |
| </li> |
| </ul> |
| </div> |
| </div> |
| <div class="flex justify-end mt-8"> |
| <button id="nextStep1" class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition disabled:opacity-50 disabled:cursor-not-allowed" disabled> |
| Next: Job Description <i class="fas fa-arrow-right ml-2"></i> |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="step2" class="p-8 hidden"> |
| <h2 class="text-2xl font-semibold text-gray-800 mb-6">Enter Job Description</h2> |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-8"> |
| <div> |
| <div class="mb-4"> |
| <label for="jobTitle" class="block text-sm font-medium text-gray-700 mb-1">Job Title</label> |
| <input type="text" id="jobTitle" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" placeholder="e.g. Senior Software Engineer"> |
| </div> |
| <div class="mb-4"> |
| <label for="jobDescription" class="block text-sm font-medium text-gray-700 mb-1">Paste Job Description</label> |
| <textarea id="jobDescription" rows="10" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" placeholder="Paste the full job description here..."></textarea> |
| </div> |
| <div class="flex space-x-3"> |
| <button id="analyzeJD" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition"> |
| Analyze Keywords <i class="fas fa-search ml-2"></i> |
| </button> |
| <button id="sampleJD" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition"> |
| Load Sample <i class="fas fa-lightbulb ml-2"></i> |
| </button> |
| </div> |
| </div> |
| <div> |
| <div class="bg-yellow-50 p-6 rounded-lg border border-yellow-200"> |
| <h3 class="text-lg font-semibold text-yellow-800 mb-3">Extracted Keywords</h3> |
| <div id="keywordsContainer" class="flex flex-wrap gap-2 mb-4"> |
| |
| </div> |
| <div class="space-y-3"> |
| <div> |
| <label class="flex items-center"> |
| <input type="checkbox" id="highlightKeywords" class="rounded text-blue-600 mr-2" checked> |
| <span class="text-gray-700">Highlight keywords in resume</span> |
| </label> |
| </div> |
| <div> |
| <label class="flex items-center"> |
| <input type="checkbox" id="addMissingKeywords" class="rounded text-blue-600 mr-2" checked> |
| <span class="text-gray-700">Add missing keywords to resume</span> |
| </label> |
| </div> |
| <div> |
| <label class="flex items-center"> |
| <input type="checkbox" id="reorderBullets" class="rounded text-blue-600 mr-2" checked> |
| <span class="text-gray-700">Reorder bullet points by relevance</span> |
| </label> |
| </div> |
| </div> |
| </div> |
| <div class="mt-4 bg-green-50 p-6 rounded-lg border border-green-200"> |
| <h3 class="text-lg font-semibold text-green-800 mb-3">Keyword Optimization Score</h3> |
| <div class="flex items-center mb-2"> |
| <div class="w-full bg-gray-200 rounded-full h-4"> |
| <div id="matchScoreBar" class="bg-green-600 h-4 rounded-full" style="width: 0%"></div> |
| </div> |
| <span id="matchScoreText" class="ml-3 font-bold text-green-700">0%</span> |
| </div> |
| <p class="text-sm text-gray-600">This score shows how well your current resume matches the job description keywords.</p> |
| </div> |
| </div> |
| </div> |
| <div class="flex justify-between mt-8"> |
| <button id="prevStep2" class="px-6 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition"> |
| <i class="fas fa-arrow-left mr-2"></i> Back |
| </button> |
| <button id="nextStep2" class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition disabled:opacity-50 disabled:cursor-not-allowed" disabled> |
| Next: Tailor Resume <i class="fas fa-arrow-right ml-2"></i> |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="step3" class="p-8 hidden"> |
| <h2 class="text-2xl font-semibold text-gray-800 mb-6">Tailor Your Resume</h2> |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> |
| <div class="lg:col-span-2"> |
| <div class="bg-white border border-gray-200 rounded-lg shadow-sm overflow-hidden"> |
| <div class="bg-gray-50 px-4 py-3 border-b border-gray-200"> |
| <h3 class="text-lg font-medium text-gray-800">Resume Preview</h3> |
| </div> |
| <div id="resumePreview" class="p-6 overflow-auto max-h-[600px]"> |
| |
| <div class="text-center py-12 text-gray-500"> |
| <i class="fas fa-file-alt text-4xl mb-4"></i> |
| <p>Your tailored resume will appear here</p> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div> |
| <div class="bg-white border border-gray-200 rounded-lg shadow-sm overflow-hidden mb-6"> |
| <div class="bg-gray-50 px-4 py-3 border-b border-gray-200"> |
| <h3 class="text-lg font-medium text-gray-800">Suggested Edits</h3> |
| </div> |
| <div id="suggestionsContainer" class="p-4 overflow-auto max-h-[300px]"> |
| |
| <div class="text-center py-8 text-gray-500"> |
| <i class="fas fa-lightbulb text-2xl mb-3"></i> |
| <p>AI-powered suggestions will appear here</p> |
| </div> |
| </div> |
| </div> |
| <div class="bg-white border border-gray-200 rounded-lg shadow-sm overflow-hidden"> |
| <div class="bg-gray-50 px-4 py-3 border-b border-gray-200"> |
| <h3 class="text-lg font-medium text-gray-800">Customize Output</h3> |
| </div> |
| <div class="p-4"> |
| <div class="mb-4"> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Output Format</label> |
| <div class="flex space-x-4"> |
| <label class="inline-flex items-center"> |
| <input type="radio" name="outputFormat" class="text-blue-600" value="pdf" checked> |
| <span class="ml-2 text-gray-700">PDF</span> |
| </label> |
| <label class="inline-flex items-center"> |
| <input type="radio" name="outputFormat" class="text-blue-600" value="docx"> |
| <span class="ml-2 text-gray-700">Word (DOCX)</span> |
| </label> |
| </div> |
| </div> |
| <div class="mb-4"> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Resume Style</label> |
| <select id="resumeStyle" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"> |
| <option value="modern">Modern</option> |
| <option value="professional">Professional</option> |
| <option value="creative">Creative</option> |
| <option value="minimal">Minimal</option> |
| </select> |
| </div> |
| <button id="generateResume" class="w-full px-4 py-3 bg-green-600 text-white rounded-md hover:bg-green-700 transition font-medium"> |
| Generate Tailored Resume <i class="fas fa-magic ml-2"></i> |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="flex justify-between mt-8"> |
| <button id="prevStep3" class="px-6 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition"> |
| <i class="fas fa-arrow-left mr-2"></i> Back |
| </button> |
| <button id="nextStep3" class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition hidden"> |
| Next: Download <i class="fas fa-arrow-right ml-2"></i> |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="step4" class="p-8 hidden"> |
| <div class="text-center py-12"> |
| <div class="mx-auto w-24 h-24 bg-green-100 rounded-full flex items-center justify-center mb-6"> |
| <i class="fas fa-check text-4xl text-green-600"></i> |
| </div> |
| <h2 class="text-2xl font-semibold text-gray-800 mb-3">Your Tailored Resume is Ready!</h2> |
| <p class="text-gray-600 mb-8 max-w-2xl mx-auto">We've optimized your resume to match the job description with relevant keywords and impactful bullet points.</p> |
| |
| <div class="flex flex-col sm:flex-row justify-center gap-4 mb-12"> |
| <button id="downloadResume" class="px-6 py-3 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition font-medium"> |
| <i class="fas fa-download mr-2"></i> Download Resume |
| </button> |
| <button id="viewChanges" class="px-6 py-3 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition font-medium"> |
| <i class="fas fa-file-diff mr-2"></i> View Changes Summary |
| </button> |
| <button id="newResume" class="px-6 py-3 bg-white border border-gray-300 text-gray-700 rounded-md hover:bg-gray-50 transition font-medium"> |
| <i class="fas fa-redo mr-2"></i> Tailor Another Resume |
| </button> |
| </div> |
| |
| <div class="bg-blue-50 p-6 rounded-lg border border-blue-200 max-w-2xl mx-auto text-left"> |
| <h3 class="text-lg font-semibold text-blue-800 mb-3">Next Steps</h3> |
| <ul class="space-y-2 text-gray-700"> |
| <li class="flex items-start"> |
| <i class="fas fa-check-circle text-blue-500 mt-1 mr-2"></i> |
| <span>Review your resume for accuracy and personal touch</span> |
| </li> |
| <li class="flex items-start"> |
| <i class="fas fa-check-circle text-blue-500 mt-1 mr-2"></i> |
| <span>Save with a descriptive filename (e.g., "JohnDoe_UX_Designer_Resume.pdf")</span> |
| </li> |
| <li class="flex items-start"> |
| <i class="fas fa-check-circle text-blue-500 mt-1 mr-2"></i> |
| <span>Combine with a tailored cover letter for best results</span> |
| </li> |
| </ul> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <footer class="mt-16 text-center text-gray-500 text-sm"> |
| <p>Resume Tailor Pro uses AI to help you create job-winning resumes. We don't store your personal data.</p> |
| <p class="mt-2">© 2023 Resume Tailor Pro. All rights reserved.</p> |
| </footer> |
| </div> |
|
|
| <script> |
| |
| let resumeFile = null; |
| let resumeText = ''; |
| let jobDescriptionText = ''; |
| let extractedKeywords = []; |
| let tailoredResumeHTML = ''; |
| |
| |
| const dropzone = document.getElementById('dropzone'); |
| const fileInput = document.getElementById('fileInput'); |
| const fileInfo = document.getElementById('fileInfo'); |
| const fileName = document.getElementById('fileName'); |
| const removeFile = document.getElementById('removeFile'); |
| const uploadProgress = document.getElementById('uploadProgress'); |
| const nextStep1 = document.getElementById('nextStep1'); |
| |
| const step1 = document.getElementById('step1'); |
| const step2 = document.getElementById('step2'); |
| const step3 = document.getElementById('step3'); |
| const step4 = document.getElementById('step4'); |
| |
| const prevStep2 = document.getElementById('prevStep2'); |
| const nextStep2 = document.getElementById('nextStep2'); |
| |
| const prevStep3 = document.getElementById('prevStep3'); |
| const nextStep3 = document.getElementById('nextStep3'); |
| |
| const jobTitle = document.getElementById('jobTitle'); |
| const jobDescription = document.getElementById('jobDescription'); |
| const analyzeJD = document.getElementById('analyzeJD'); |
| const sampleJD = document.getElementById('sampleJD'); |
| const keywordsContainer = document.getElementById('keywordsContainer'); |
| const matchScoreBar = document.getElementById('matchScoreBar'); |
| const matchScoreText = document.getElementById('matchScoreText'); |
| |
| const resumePreview = document.getElementById('resumePreview'); |
| const suggestionsContainer = document.getElementById('suggestionsContainer'); |
| const generateResume = document.getElementById('generateResume'); |
| |
| const downloadResume = document.getElementById('downloadResume'); |
| const viewChanges = document.getElementById('viewChanges'); |
| const newResume = document.getElementById('newResume'); |
| |
| |
| dropzone.addEventListener('click', () => fileInput.click()); |
| dropzone.addEventListener('dragover', (e) => { |
| e.preventDefault(); |
| dropzone.classList.add('active'); |
| }); |
| dropzone.addEventListener('dragleave', () => { |
| dropzone.classList.remove('active'); |
| }); |
| dropzone.addEventListener('drop', (e) => { |
| e.preventDefault(); |
| dropzone.classList.remove('active'); |
| if (e.dataTransfer.files.length) { |
| handleFileUpload(e.dataTransfer.files[0]); |
| } |
| }); |
| |
| fileInput.addEventListener('change', () => { |
| if (fileInput.files.length) { |
| handleFileUpload(fileInput.files[0]); |
| } |
| }); |
| |
| removeFile.addEventListener('click', (e) => { |
| e.stopPropagation(); |
| resetFileUpload(); |
| }); |
| |
| nextStep1.addEventListener('click', () => { |
| step1.classList.add('hidden'); |
| step2.classList.remove('hidden'); |
| updateStepProgress(2); |
| }); |
| |
| prevStep2.addEventListener('click', () => { |
| step2.classList.add('hidden'); |
| step1.classList.remove('hidden'); |
| updateStepProgress(1); |
| }); |
| |
| nextStep2.addEventListener('click', () => { |
| step2.classList.add('hidden'); |
| step3.classList.remove('hidden'); |
| updateStepProgress(3); |
| |
| displayResumePreview(); |
| }); |
| |
| prevStep3.addEventListener('click', () => { |
| step3.classList.add('hidden'); |
| step2.classList.remove('hidden'); |
| updateStepProgress(2); |
| }); |
| |
| nextStep3.addEventListener('click', () => { |
| step3.classList.add('hidden'); |
| step4.classList.remove('hidden'); |
| updateStepProgress(4); |
| }); |
| |
| analyzeJD.addEventListener('click', analyzeJobDescription); |
| sampleJD.addEventListener('click', loadSampleJobDescription); |
| generateResume.addEventListener('click', generateTailoredResume); |
| downloadResume.addEventListener('click', downloadTailoredResume); |
| viewChanges.addEventListener('click', showChangesSummary); |
| newResume.addEventListener('click', resetApplication); |
| |
| |
| function handleFileUpload(file) { |
| const validTypes = ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document']; |
| |
| if (!validTypes.includes(file.type) && !file.name.match(/\.(pdf|doc|docx)$/i)) { |
| alert('Please upload a PDF or Word document'); |
| return; |
| } |
| |
| resumeFile = file; |
| fileName.textContent = file.name; |
| fileInfo.classList.remove('hidden'); |
| nextStep1.disabled = false; |
| |
| |
| let progress = 0; |
| const interval = setInterval(() => { |
| progress += Math.random() * 10; |
| if (progress >= 100) { |
| progress = 100; |
| clearInterval(interval); |
| } |
| uploadProgress.style.width = `${progress}%`; |
| }, 200); |
| |
| |
| |
| } |
| |
| function resetFileUpload() { |
| resumeFile = null; |
| fileInput.value = ''; |
| fileInfo.classList.add('hidden'); |
| uploadProgress.style.width = '0%'; |
| nextStep1.disabled = true; |
| } |
| |
| function updateStepProgress(stepNumber) { |
| const steps = document.querySelectorAll('.step'); |
| |
| steps.forEach((step, index) => { |
| const number = step.querySelector('div:first-child'); |
| const text = step.querySelector('span'); |
| const line = step.querySelector('div:last-child'); |
| |
| if (index + 1 < stepNumber) { |
| |
| number.classList.remove('bg-gray-300'); |
| number.classList.add('bg-green-500'); |
| text.classList.remove('text-gray-500'); |
| text.classList.add('text-green-600'); |
| if (line) line.classList.remove('bg-gray-300'); |
| if (line) line.classList.add('bg-green-500'); |
| } else if (index + 1 === stepNumber) { |
| |
| number.classList.remove('bg-gray-300'); |
| number.classList.remove('bg-green-500'); |
| number.classList.add('bg-blue-600'); |
| text.classList.remove('text-gray-500'); |
| text.classList.remove('text-green-600'); |
| text.classList.add('text-blue-600'); |
| } else { |
| |
| number.classList.remove('bg-blue-600'); |
| number.classList.remove('bg-green-500'); |
| number.classList.add('bg-gray-300'); |
| text.classList.remove('text-blue-600'); |
| text.classList.remove('text-green-600'); |
| text.classList.add('text-gray-500'); |
| if (line) line.classList.remove('bg-green-500'); |
| if (line) line.classList.add('bg-gray-300'); |
| } |
| }); |
| } |
| |
| function analyzeJobDescription() { |
| jobDescriptionText = jobDescription.value.trim(); |
| |
| if (!jobDescriptionText) { |
| alert('Please enter a job description'); |
| return; |
| } |
| |
| |
| const words = jobDescriptionText.toLowerCase() |
| .replace(/[^\w\s]|_/g, '') |
| .replace(/\s+/g, ' ') |
| .split(' '); |
| |
| |
| const commonWords = ['the', 'and', 'a', 'an', 'in', 'on', 'at', 'to', 'for', 'with', 'of', 'as', 'is', 'are', 'be', 'this', 'that']; |
| const wordCounts = {}; |
| |
| words.forEach(word => { |
| if (word.length > 3 && !commonWords.includes(word)) { |
| wordCounts[word] = (wordCounts[word] || 0) + 1; |
| } |
| }); |
| |
| |
| extractedKeywords = Object.entries(wordCounts) |
| .sort((a, b) => b[1] - a[1]) |
| .slice(0, 15) |
| .map(item => item[0]); |
| |
| displayKeywords(); |
| calculateMatchScore(); |
| nextStep2.disabled = false; |
| } |
| |
| function displayKeywords() { |
| keywordsContainer.innerHTML = ''; |
| |
| extractedKeywords.forEach(keyword => { |
| const chip = document.createElement('div'); |
| chip.className = 'keyword-chip px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm font-medium'; |
| chip.textContent = keyword; |
| keywordsContainer.appendChild(chip); |
| }); |
| } |
| |
| function calculateMatchScore() { |
| |
| |
| const score = Math.floor(Math.random() * 30) + 20; |
| matchScoreBar.style.width = `${score}%`; |
| matchScoreText.textContent = `${score}%`; |
| |
| |
| if (score < 30) { |
| matchScoreBar.classList.remove('bg-green-600', 'bg-yellow-500'); |
| matchScoreBar.classList.add('bg-red-500'); |
| } else if (score < 60) { |
| matchScoreBar.classList.remove('bg-green-600', 'bg-red-500'); |
| matchScoreBar.classList.add('bg-yellow-500'); |
| } else { |
| matchScoreBar.classList.remove('bg-yellow-500', 'bg-red-500'); |
| matchScoreBar.classList.add('bg-green-600'); |
| } |
| } |
| |
| function loadSampleJobDescription() { |
| const sample = `Senior Software Engineer - Web Development |
| |
| We are looking for an experienced Senior Software Engineer to join our web development team. The ideal candidate will have strong expertise in JavaScript frameworks, cloud technologies, and agile methodologies. |
| |
| Responsibilities: |
| - Develop and maintain high-performance web applications using React.js and Node.js |
| - Design and implement RESTful APIs and microservices architecture |
| - Collaborate with cross-functional teams to define, design, and ship new features |
| - Optimize applications for maximum speed and scalability |
| - Implement automated testing platforms and unit tests |
| - Stay up-to-date with emerging technologies and industry trends |
| |
| Requirements: |
| - 5+ years of professional software development experience |
| - Strong proficiency in JavaScript, including DOM manipulation and JS object model |
| - Thorough understanding of React.js and its core principles |
| - Experience with popular React.js workflows (such as Redux or Context API) |
| - Familiarity with modern front-end build pipelines and tools |
| - Experience with cloud platforms (AWS, Azure, or GCP) |
| - Knowledge of modern authorization mechanisms (JWT, OAuth) |
| - Familiarity with code versioning tools (Git) |
| - Excellent problem-solving skills and attention to detail |
| |
| Preferred Qualifications: |
| - Experience with TypeScript |
| - Knowledge of server-side rendering and Next.js |
| - Familiarity with Docker and Kubernetes |
| - Understanding of CI/CD pipelines`; |
| |
| jobTitle.value = 'Senior Software Engineer'; |
| jobDescription.value = sample; |
| } |
| |
| function displayResumePreview() { |
| |
| |
| |
| const sampleResumeHTML = ` |
| <div class="font-sans"> |
| <div class="text-center mb-6"> |
| <h1 class="text-2xl font-bold text-gray-800">John Doe</h1> |
| <p class="text-gray-600">Senior Software Engineer | john.doe@example.com | (123) 456-7890</p> |
| </div> |
| |
| <div class="mb-6"> |
| <h2 class="text-xl font-semibold text-gray-800 border-b border-gray-200 pb-1 mb-3">Professional Summary</h2> |
| <p class="text-gray-700">Experienced software engineer with 7+ years in web development. Skilled in JavaScript, React, and Node.js. Passionate about building scalable web applications and mentoring junior developers.</p> |
| </div> |
| |
| <div class="mb-6"> |
| <h2 class="text-xl font-semibold text-gray-800 border-b border-gray-200 pb-1 mb-3">Technical Skills</h2> |
| <div class="flex flex-wrap gap-2"> |
| <span class="px-3 py-1 bg-gray-100 text-gray-800 rounded-full text-sm">JavaScript</span> |
| <span class="px-3 py-1 bg-gray-100 text-gray-800 rounded-full text-sm">React</span> |
| <span class="px-3 py-1 bg-gray-100 text-gray-800 rounded-full text-sm">Node.js</span> |
| <span class="px-3 py-1 bg-gray-100 text-gray-800 rounded-full text-sm">HTML/CSS</span> |
| <span class="px-3 py-1 bg-gray-100 text-gray-800 rounded-full text-sm">Git</span> |
| <span class="px-3 py-1 bg-gray-100 text-gray-800 rounded-full text-sm">REST APIs</span> |
| </div> |
| </div> |
| |
| <div class="mb-6"> |
| <h2 class="text-xl font-semibold text-gray-800 border-b border-gray-200 pb-1 mb-3">Work Experience</h2> |
| |
| <div class="mb-4"> |
| <div class="flex justify-between"> |
| <h3 class="font-medium text-gray-800">Senior Software Engineer</h3> |
| <span class="text-gray-600">2019 - Present</span> |
| </div> |
| <p class="text-gray-600 mb-2">Tech Solutions Inc., San Francisco, CA</p> |
| <ul class="list-disc list-inside space-y-1 text-gray-700"> |
| <li class="resume-point">Led a team of 5 developers to build a React-based customer portal</li> |
| <li class="resume-point">Improved application performance by 40% through code optimization</li> |
| <li class="resume-point">Implemented CI/CD pipeline reducing deployment time by 60%</li> |
| <li class="resume-point">Mentored junior developers in JavaScript best practices</li> |
| </ul> |
| </div> |
| |
| <div class="mb-4"> |
| <div class="flex justify-between"> |
| <h3 class="font-medium text-gray-800">Software Engineer</h3> |
| <span class="text-gray-600">2016 - 2019</span> |
| </div> |
| <p class="text-gray-600 mb-2">Digital Innovations LLC, Austin, TX</p> |
| <ul class="list-disc list-inside space-y-1 text-gray-700"> |
| <li class="resume-point">Developed Node.js microservices for e-commerce platform</li> |
| <li class="resume-point">Reduced server costs by 30% through AWS optimization</li> |
| <li class="resume-point">Collaborated with UX team to implement responsive designs</li> |
| </ul> |
| </div> |
| </div> |
| |
| <div> |
| <h2 class="text-xl font-semibold text-gray-800 border-b border-gray-200 pb-1 mb-3">Education</h2> |
| <div class="flex justify-between"> |
| <h3 class="font-medium text-gray-800">B.S. in Computer Science</h3> |
| <span class="text-gray-600">2012 - 2016</span> |
| </div> |
| <p class="text-gray-600">University of Texas at Austin</p> |
| </div> |
| </div> |
| `; |
| |
| resumePreview.innerHTML = sampleResumeHTML; |
| |
| |
| generateSuggestions(); |
| } |
| |
| function generateSuggestions() { |
| |
| |
| |
| const suggestions = [ |
| { |
| section: "Professional Summary", |
| suggestion: "Add mention of cloud technologies and agile methodologies to better match the job description." |
| }, |
| { |
| section: "Technical Skills", |
| suggestion: "Include keywords: TypeScript, AWS, Docker, Kubernetes, CI/CD to improve ATS compatibility." |
| }, |
| { |
| section: "Senior Software Engineer", |
| suggestion: "Modify bullet points to emphasize React workflows and API development experience." |
| }, |
| { |
| section: "All Experience", |
| suggestion: "Add metrics to achievements where possible (e.g., 'Improved performance by X%')." |
| } |
| ]; |
| |
| suggestionsContainer.innerHTML = ''; |
| |
| suggestions.forEach((item, index) => { |
| const suggestionDiv = document.createElement('div'); |
| suggestionDiv.className = `mb-4 pb-4 ${index < suggestions.length - 1 ? 'border-b border-gray-200' : ''}`; |
| suggestionDiv.innerHTML = ` |
| <div class="flex items-start"> |
| <div class="bg-blue-100 p-2 rounded-full mr-3"> |
| <i class="fas fa-lightbulb text-blue-600 text-sm"></i> |
| </div> |
| <div> |
| <h4 class="font-medium text-gray-800">${item.section}</h4> |
| <p class="text-gray-600 text-sm">${item.suggestion}</p> |
| <button class="mt-2 text-sm text-blue-600 hover:text-blue-800 font-medium"> |
| Apply Suggestion <i class="fas fa-check ml-1"></i> |
| </button> |
| </div> |
| </div> |
| `; |
| suggestionsContainer.appendChild(suggestionDiv); |
| }); |
| } |
| |
| function generateTailoredResume() { |
| |
| generateResume.disabled = true; |
| generateResume.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Processing...'; |
| |
| setTimeout(() => { |
| |
| |
| |
| |
| const resumePoints = document.querySelectorAll('.resume-point'); |
| resumePoints.forEach(point => { |
| extractedKeywords.forEach(keyword => { |
| if (point.textContent.toLowerCase().includes(keyword)) { |
| point.classList.add('highlight'); |
| } |
| }); |
| }); |
| |
| |
| const skillsSection = resumePreview.querySelector('.flex.flex-wrap.gap-2'); |
| if (skillsSection) { |
| const additionalSkills = ['TypeScript', 'AWS', 'Docker', 'CI/CD']; |
| additionalSkills.forEach(skill => { |
| const skillSpan = document.createElement('span'); |
| skillSpan.className = 'px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm'; |
| skillSpan.textContent = skill; |
| skillsSection.appendChild(skillSpan); |
| }); |
| } |
| |
| |
| const summary = resumePreview.querySelector('p.text-gray-700'); |
| if (summary) { |
| summary.textContent = "Experienced software engineer with 7+ years in web development. Skilled in JavaScript, React, Node.js and cloud technologies. Strong expertise in agile methodologies and building scalable web applications. Passionate about mentoring junior developers and implementing CI/CD pipelines."; |
| } |
| |
| |
| const successDiv = document.createElement('div'); |
| successDiv.className = 'mt-4 p-4 bg-green-50 text-green-800 rounded-lg fade-in'; |
| successDiv.innerHTML = ` |
| <div class="flex items-center"> |
| <i class="fas fa-check-circle mr-2"></i> |
| <span>Your resume has been successfully tailored to match the job description!</span> |
| </div> |
| `; |
| resumePreview.appendChild(successDiv); |
| |
| |
| nextStep3.classList.remove('hidden'); |
| generateResume.disabled = false; |
| generateResume.innerHTML = 'Generate Tailored Resume <i class="fas fa-magic ml-2"></i>'; |
| |
| |
| tailoredResumeHTML = resumePreview.innerHTML; |
| }, 2000); |
| } |
| |
| function downloadTailoredResume() { |
| |
| |
| |
| const format = document.querySelector('input[name="outputFormat"]:checked').value; |
| |
| |
| const link = document.createElement('a'); |
| link.href = format === 'pdf' ? |
| 'data:application/pdf;base64,JVBERi0xLjUK...' : |
| 'data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,UEsDBBQ...'; |
| |
| link.download = `Tailored_Resume_${jobTitle.value || 'Job'}.${format}`; |
| document.body.appendChild(link); |
| link.click(); |
| document.body.removeChild(link); |
| |
| |
| const downloadDiv = document.createElement('div'); |
| downloadDiv.className = 'mt-4 p-4 bg-blue-50 text-blue-800 rounded-lg fade-in'; |
| downloadDiv.innerHTML = ` |
| <div class="flex items-center"> |
| <i class="fas fa-check-circle mr-2"></i> |
| <span>Your ${format.toUpperCase()} file has been downloaded!</span> |
| </div> |
| `; |
| document.querySelector('#step4 .text-center').insertBefore(downloadDiv, document.querySelector('#step4 .flex.flex-col')); |
| } |
| |
| function showChangesSummary() { |
| |
| |
| |
| const modalHTML = ` |
| <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4"> |
| <div class="bg-white rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-auto"> |
| <div class="p-6"> |
| <div class="flex justify-between items-center mb-4"> |
| <h3 class="text-xl font-semibold text-gray-800">Resume Changes Summary</h3> |
| <button id="closeModal" class="text-gray-500 hover:text-gray-700"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| |
| <div class="space-y-4"> |
| <div class="border-b border-gray-200 pb-4"> |
| <h4 class="font-medium text-gray-800 mb-2">Added Keywords</h4> |
| <div class="flex flex-wrap gap-2"> |
| <span class="px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm">TypeScript</span> |
| <span class="px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm">AWS</span> |
| <span class="px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm">Docker</span> |
| <span class="px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm">CI/CD</span> |
| <span class="px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm">Agile</span> |
| </div> |
| </div> |
| |
| <div class="border-b border-gray-200 pb-4"> |
| <h4 class="font-medium text-gray-800 mb-2">Modified Sections</h4> |
| <ul class="space-y-3"> |
| <li class="flex items-start"> |
| <i class="fas fa-pen text-blue-500 mt-1 mr-2"></i> |
| <div> |
| <span class="font-medium">Professional Summary</span> |
| <p class="text-sm text-gray-600">Added cloud technologies and agile methodologies</p> |
| </div> |
| </li> |
| <li class="flex items-start"> |
| <i class="fas fa-pen text-blue-500 mt-1 mr-2"></i> |
| <div> |
| <span class="font-medium">Technical Skills</span> |
| <p class="text-sm text-gray-600">Added 4 new relevant skills</p> |
| </div> |
| </li> |
| </ul> |
| </div> |
| |
| <div> |
| <h4 class="font-medium text-gray-800 mb-2">Optimization Score</h4> |
| <div class="flex items-center"> |
| <div class="w-full bg-gray-200 rounded-full h-4 mr-3"> |
| <div class="bg-green-600 h-4 rounded-full" style="width: 78%"></div> |
| </div> |
| <span class="font-bold text-green-700">78%</span> |
| </div> |
| <p class="text-sm text-gray-600 mt-2">Your resume now matches 78% of the job description keywords (up from 32%).</p> |
| </div> |
| </div> |
| |
| <div class="mt-6 flex justify-end"> |
| <button id="closeModalBtn" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition"> |
| Close |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
| `; |
| |
| const modal = document.createElement('div'); |
| modal.innerHTML = modalHTML; |
| document.body.appendChild(modal); |
| |
| const closeModal = document.getElementById('closeModal'); |
| const closeModalBtn = document.getElementById('closeModalBtn'); |
| |
| closeModal.addEventListener('click', () => modal.remove()); |
| closeModalBtn.addEventListener('click', () => modal.remove()); |
| } |
| |
| function resetApplication() { |
| |
| resetFileUpload(); |
| jobTitle.value = ''; |
| jobDescription.value = ''; |
| keywordsContainer.innerHTML = ''; |
| matchScoreBar.style.width = '0%'; |
| matchScoreText.textContent = '0%'; |
| resumePreview.innerHTML = ` |
| <div class="text-center py-12 text-gray-500"> |
| <i class="fas fa-file-alt text-4xl mb-4"></i> |
| <p>Your tailored resume will appear here</p> |
| </div> |
| `; |
| suggestionsContainer.innerHTML = ` |
| <div class="text-center py-8 text-gray-500"> |
| <i class="fas fa-lightbulb text-2xl mb-3"></i> |
| <p>AI-powered suggestions will appear here</p> |
| </div> |
| `; |
| |
| |
| step4.classList.add('hidden'); |
| step1.classList.remove('hidden'); |
| updateStepProgress(1); |
| nextStep2.disabled = true; |
| nextStep3.classList.add('hidden'); |
| } |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=illumnati/test" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |