|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>ATS-Friendly CV Maker</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/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/docx/7.8.2/docx.js"></script> |
|
<style> |
|
.fade-in { |
|
animation: fadeIn 0.5s ease-in-out; |
|
} |
|
@keyframes fadeIn { |
|
from { opacity: 0; transform: translateY(10px); } |
|
to { opacity: 1; transform: translateY(0); } |
|
} |
|
.fade-out { |
|
animation: fadeOut 0.3s ease-in-out; |
|
} |
|
@keyframes fadeOut { |
|
from { opacity: 1; transform: translateY(0); } |
|
to { opacity: 0; transform: translateY(10px); } |
|
} |
|
.section-highlight { |
|
transition: all 0.3s ease; |
|
} |
|
.section-highlight:hover { |
|
transform: translateY(-3px); |
|
box-shadow: 0 10px 20px rgba(0,0,0,0.1); |
|
} |
|
.progress-bar { |
|
height: 6px; |
|
transition: width 0.5s ease; |
|
} |
|
.resume-paper { |
|
background: linear-gradient(to bottom, #ffffff 0%, #f9f9f9 100%); |
|
box-shadow: 0 5px 15px rgba(0,0,0,0.1); |
|
} |
|
.skill-level { |
|
position: relative; |
|
} |
|
.skill-level::after { |
|
content: ''; |
|
position: absolute; |
|
bottom: -5px; |
|
left: 0; |
|
width: 100%; |
|
height: 3px; |
|
background: #e2e8f0; |
|
border-radius: 3px; |
|
} |
|
.skill-level-fill { |
|
position: absolute; |
|
bottom: -5px; |
|
left: 0; |
|
height: 3px; |
|
border-radius: 3px; |
|
background: #3b82f6; |
|
transition: width 0.5s ease; |
|
} |
|
</style> |
|
</head> |
|
<body class="bg-gray-50 font-sans"> |
|
<div class="container mx-auto px-4 py-8 max-w-7xl"> |
|
|
|
<header class="text-center mb-12"> |
|
<h1 class="text-4xl font-bold text-blue-800 mb-2">ATS-Friendly CV Maker</h1> |
|
<p class="text-lg text-gray-600">Create a resume that beats Applicant Tracking Systems</p> |
|
<div class="w-full bg-gray-200 rounded-full h-2.5 mt-4"> |
|
<div id="completion-progress" class="progress-bar bg-blue-600 h-2.5 rounded-full" style="width: 0%"></div> |
|
</div> |
|
<p id="completion-text" class="text-sm text-gray-500 mt-1">0% Complete</p> |
|
</header> |
|
|
|
<div class="flex flex-col lg:flex-row gap-8"> |
|
|
|
<div class="lg:w-2/3"> |
|
<div class="bg-white rounded-xl shadow-md p-6 mb-6 section-highlight"> |
|
<h2 class="text-2xl font-semibold text-gray-800 mb-4 flex items-center"> |
|
<i class="fas fa-user-circle text-blue-500 mr-2"></i> Personal Information |
|
</h2> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Full Name*</label> |
|
<input type="text" id="full-name" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="John Doe"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Professional Title*</label> |
|
<input type="text" id="professional-title" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="Software Engineer"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Email*</label> |
|
<input type="email" id="email" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="[email protected]"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Phone*</label> |
|
<input type="tel" id="phone" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="+1 (555) 123-4567"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Location*</label> |
|
<input type="text" id="location" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="New York, USA"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">LinkedIn Profile</label> |
|
<input type="url" id="linkedin" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="https://linkedin.com/in/username"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">GitHub/Portfolio</label> |
|
<input type="url" id="portfolio" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="https://github.com/username"> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="bg-white rounded-xl shadow-md p-6 mb-6 section-highlight"> |
|
<h2 class="text-2xl font-semibold text-gray-800 mb-4 flex items-center"> |
|
<i class="fas fa-briefcase text-blue-500 mr-2"></i> Work Experience |
|
</h2> |
|
<div id="experience-container"> |
|
<div class="experience-item mb-6 p-4 border rounded-lg"> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Job Title*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 experience-title" placeholder="Senior Developer"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Company Name*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 experience-company" placeholder="Tech Corp Inc."> |
|
</div> |
|
</div> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Start Date*</label> |
|
<input type="month" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 experience-start"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">End Date (or present)</label> |
|
<input type="month" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 experience-end"> |
|
<div class="flex items-center mt-2"> |
|
<input type="checkbox" class="mr-2 experience-current"> |
|
<span class="text-sm text-gray-600">I currently work here</span> |
|
</div> |
|
</div> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Responsibilities & Achievements*</label> |
|
<textarea class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 experience-description" rows="3" placeholder="Describe your responsibilities and key achievements using action verbs (e.g., Developed, Led, Optimized)"></textarea> |
|
<p class="text-xs text-gray-500 mt-1">Use bullet points for better ATS parsing. Example: "• Led a team of 5 developers to deliver a SaaS product"</p> |
|
</div> |
|
<button class="remove-experience mt-2 text-red-500 text-sm flex items-center"> |
|
<i class="fas fa-trash mr-1"></i> Remove this experience |
|
</button> |
|
</div> |
|
</div> |
|
<button id="add-experience" class="bg-blue-50 text-blue-600 px-4 py-2 rounded-lg hover:bg-blue-100 transition flex items-center"> |
|
<i class="fas fa-plus mr-2"></i> Add Another Experience |
|
</button> |
|
</div> |
|
|
|
<div class="bg-white rounded-xl shadow-md p-6 mb-6 section-highlight"> |
|
<h2 class="text-2xl font-semibold text-gray-800 mb-4 flex items-center"> |
|
<i class="fas fa-graduation-cap text-blue-500 mr-2"></i> Education |
|
</h2> |
|
<div id="education-container"> |
|
<div class="education-item mb-6 p-4 border rounded-lg"> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Degree*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 education-degree" placeholder="Bachelor of Science in Computer Science"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Institution*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 education-institution" placeholder="University of Technology"> |
|
</div> |
|
</div> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Start Date*</label> |
|
<input type="month" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 education-start"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">End Date (or expected)</label> |
|
<input type="month" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 education-end"> |
|
<div class="flex items-center mt-2"> |
|
<input type="checkbox" class="mr-2 education-current"> |
|
<span class="text-sm text-gray-600">Currently studying here</span> |
|
</div> |
|
</div> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Notable Achievements (optional)</label> |
|
<textarea class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 education-achievements" rows="2" placeholder="Honors, awards, relevant coursework"></textarea> |
|
</div> |
|
<button class="remove-education mt-2 text-red-500 text-sm flex items-center"> |
|
<i class="fas fa-trash mr-1"></i> Remove this education |
|
</button> |
|
</div> |
|
</div> |
|
<button id="add-education" class="bg-blue-50 text-blue-600 px-4 py-2 rounded-lg hover:bg-blue-100 transition flex items-center"> |
|
<i class="fas fa-plus mr-2"></i> Add Another Education |
|
</button> |
|
</div> |
|
|
|
<div class="bg-white rounded-xl shadow-md p-6 mb-6 section-highlight"> |
|
<h2 class="text-2xl font-semibold text-gray-800 mb-4 flex items-center"> |
|
<i class="fas fa-code text-blue-500 mr-2"></i> Skills |
|
</h2> |
|
<div id="skills-container"> |
|
<div class="skill-item mb-4 p-4 border rounded-lg"> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Skill Name*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 skill-name" placeholder="JavaScript"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Skill Level*</label> |
|
<select class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 skill-level"> |
|
<option value="beginner">Beginner</option> |
|
<option value="intermediate">Intermediate</option> |
|
<option value="advanced" selected>Advanced</option> |
|
<option value="expert">Expert</option> |
|
</select> |
|
</div> |
|
</div> |
|
<button class="remove-skill text-red-500 text-sm flex items-center"> |
|
<i class="fas fa-trash mr-1"></i> Remove this skill |
|
</button> |
|
</div> |
|
</div> |
|
<button id="add-skill" class="bg-blue-50 text-blue-600 px-4 py-2 rounded-lg hover:bg-blue-100 transition flex items-center"> |
|
<i class="fas fa-plus mr-2"></i> Add Another Skill |
|
</button> |
|
<div class="mt-4"> |
|
<label class="block text-gray-700 mb-1">Additional Skills (comma separated)</label> |
|
<textarea id="additional-skills" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" rows="2" placeholder="Project Management, Public Speaking, etc."></textarea> |
|
<p class="text-xs text-gray-500 mt-1">These will appear as tags in your resume</p> |
|
</div> |
|
</div> |
|
|
|
<div class="bg-white rounded-xl shadow-md p-6 mb-6 section-highlight"> |
|
<h2 class="text-2xl font-semibold text-gray-800 mb-4 flex items-center"> |
|
<i class="fas fa-project-diagram text-blue-500 mr-2"></i> Projects |
|
</h2> |
|
<div id="projects-container"> |
|
<div class="project-item mb-6 p-4 border rounded-lg"> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Project Name*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 project-name" placeholder="E-commerce Website"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Project URL (optional)</label> |
|
<input type="url" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 project-url" placeholder="https://example.com"> |
|
</div> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Project Description*</label> |
|
<textarea class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 project-description" rows="3" placeholder="Describe the project, technologies used, and your role"></textarea> |
|
<p class="text-xs text-gray-500 mt-1">Use action verbs and quantify results when possible (e.g., "Increased performance by 30%")</p> |
|
</div> |
|
<button class="remove-project mt-2 text-red-500 text-sm flex items-center"> |
|
<i class="fas fa-trash mr-1"></i> Remove this project |
|
</button> |
|
</div> |
|
</div> |
|
<button id="add-project" class="bg-blue-50 text-blue-600 px-4 py-2 rounded-lg hover:bg-blue-100 transition flex items-center"> |
|
<i class="fas fa-plus mr-2"></i> Add Another Project |
|
</button> |
|
</div> |
|
|
|
<div class="bg-white rounded-xl shadow-md p-6 mb-6 section-highlight"> |
|
<h2 class="text-2xl font-semibold text-gray-800 mb-4 flex items-center"> |
|
<i class="fas fa-certificate text-blue-500 mr-2"></i> Certifications |
|
</h2> |
|
<div id="certifications-container"> |
|
<div class="certification-item mb-4 p-4 border rounded-lg"> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Certification Name*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 certification-name" placeholder="AWS Certified Solutions Architect"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Issuing Organization*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 certification-org" placeholder="Amazon Web Services"> |
|
</div> |
|
</div> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Date Earned*</label> |
|
<input type="month" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 certification-date"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Credential ID (optional)</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 certification-id" placeholder="Credential ID or URL"> |
|
</div> |
|
</div> |
|
<button class="remove-certification mt-2 text-red-500 text-sm flex items-center"> |
|
<i class="fas fa-trash mr-1"></i> Remove this certification |
|
</button> |
|
</div> |
|
</div> |
|
<button id="add-certification" class="bg-blue-50 text-blue-600 px-4 py-2 rounded-lg hover:bg-blue-100 transition flex items-center"> |
|
<i class="fas fa-plus mr-2"></i> Add Another Certification |
|
</button> |
|
</div> |
|
|
|
<div class="bg-white rounded-xl shadow-md p-6 mb-6 section-highlight"> |
|
<h2 class="text-2xl font-semibold text-gray-800 mb-4 flex items-center"> |
|
<i class="fas fa-language text-blue-500 mr-2"></i> Languages |
|
</h2> |
|
<div id="languages-container"> |
|
<div class="language-item mb-4 p-4 border rounded-lg"> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Language*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 language-name" placeholder="English"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Proficiency Level*</label> |
|
<select class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 language-level"> |
|
<option value="native">Native</option> |
|
<option value="fluent" selected>Fluent</option> |
|
<option value="intermediate">Intermediate</option> |
|
<option value="basic">Basic</option> |
|
</select> |
|
</div> |
|
</div> |
|
<button class="remove-language mt-2 text-red-500 text-sm flex items-center"> |
|
<i class="fas fa-trash mr-1"></i> Remove this language |
|
</button> |
|
</div> |
|
</div> |
|
<button id="add-language" class="bg-blue-50 text-blue-600 px-4 py-2 rounded-lg hover:bg-blue-100 transition flex items-center"> |
|
<i class="fas fa-plus mr-2"></i> Add Another Language |
|
</button> |
|
</div> |
|
|
|
<div class="bg-white rounded-xl shadow-md p-6 mb-6 section-highlight"> |
|
<h2 class="text-2xl font-semibold text-gray-800 mb-4 flex items-center"> |
|
<i class="fas fa-pencil-alt text-blue-500 mr-2"></i> Customize Resume |
|
</h2> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
|
<div> |
|
<label class="block text-gray-700 mb-2">Resume Template</label> |
|
<div class="grid grid-cols-2 gap-4"> |
|
<div> |
|
<input type="radio" id="template-modern" name="template" value="modern" class="hidden peer" checked> |
|
<label for="template-modern" class="block p-4 border rounded-lg cursor-pointer peer-checked:border-blue-500 peer-checked:ring-2 peer-checked:ring-blue-200"> |
|
<div class="h-24 bg-gradient-to-r from-blue-100 to-blue-50 rounded"></div> |
|
<p class="text-center mt-2">Modern</p> |
|
</label> |
|
</div> |
|
<div> |
|
<input type="radio" id="template-classic" name="template" value="classic" class="hidden peer"> |
|
<label for="template-classic" class="block p-4 border rounded-lg cursor-pointer peer-checked:border-blue-500 peer-checked:ring-2 peer-checked:ring-blue-200"> |
|
<div class="h-24 bg-gradient-to-r from-gray-100 to-gray-50 rounded"></div> |
|
<p class="text-center mt-2">Classic</p> |
|
</label> |
|
</div> |
|
</div> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-2">Color Scheme</label> |
|
<div class="flex flex-wrap gap-2"> |
|
<input type="radio" id="color-blue" name="color" value="blue" class="hidden peer" checked> |
|
<label for="color-blue" class="w-10 h-10 rounded-full bg-blue-500 cursor-pointer peer-checked:ring-2 peer-checked:ring-blue-300"></label> |
|
|
|
<input type="radio" id="color-green" name="color" value="green" class="hidden peer"> |
|
<label for="color-green" class="w-10 h-10 rounded-full bg-green-500 cursor-pointer peer-checked:ring-2 peer-checked:ring-green-300"></label> |
|
|
|
<input type="radio" id="color-purple" name="color" value="purple" class="hidden peer"> |
|
<label for="color-purple" class="w-10 h-10 rounded-full bg-purple-500 cursor-pointer peer-checked:ring-2 peer-checked:ring-purple-300"></label> |
|
|
|
<input type="radio" id="color-red" name="color" value="red" class="hidden peer"> |
|
<label for="color-red" class="w-10 h-10 rounded-full bg-red-500 cursor-pointer peer-checked:ring-2 peer-checked:ring-red-300"></label> |
|
|
|
<input type="radio" id="color-indigo" name="color" value="indigo" class="hidden peer"> |
|
<label for="color-indigo" class="w-10 h-10 rounded-full bg-indigo-500 cursor-pointer peer-checked:ring-2 peer-checked:ring-indigo-300"></label> |
|
</div> |
|
</div> |
|
</div> |
|
<div class="mt-6"> |
|
<label class="block text-gray-700 mb-2">Professional Summary</label> |
|
<textarea id="professional-summary" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" rows="4" placeholder="A brief summary of your professional background, skills, and career objectives (3-5 sentences recommended)"></textarea> |
|
<p class="text-xs text-gray-500 mt-1">This will appear at the top of your resume. Include relevant keywords for ATS.</p> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="lg:w-1/3"> |
|
<div class="sticky top-4"> |
|
<div class="bg-white rounded-xl shadow-lg p-6 mb-6"> |
|
<h2 class="text-2xl font-semibold text-gray-800 mb-4 flex items-center"> |
|
<i class="fas fa-eye text-blue-500 mr-2"></i> Resume Preview |
|
</h2> |
|
<div class="flex justify-between mb-4"> |
|
<div class="text-sm"> |
|
<span class="font-medium">ATS Score:</span> |
|
<span id="ats-score" class="ml-2 px-2 py-1 bg-blue-100 text-blue-800 rounded-full text-xs">Calculating...</span> |
|
</div> |
|
<div class="text-sm"> |
|
<span class="font-medium">Keywords:</span> |
|
<span id="keyword-count" class="ml-2 px-2 py-1 bg-green-100 text-green-800 rounded-full text-xs">0</span> |
|
</div> |
|
</div> |
|
|
|
<div id="resume-preview" class="resume-paper p-6 rounded-lg border border-gray-200 overflow-y-auto" style="height: 500px;"> |
|
|
|
<div class="text-center py-12 text-gray-400"> |
|
<i class="fas fa-file-alt text-4xl mb-2"></i> |
|
<p>Your resume preview will appear here</p> |
|
</div> |
|
</div> |
|
|
|
<div class="mt-6 grid grid-cols-1 gap-3"> |
|
<button id="download-pdf" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-3 rounded-lg font-medium flex items-center justify-center"> |
|
<i class="fas fa-file-pdf mr-2"></i> Download as PDF |
|
</button> |
|
<button id="download-doc" class="bg-green-600 hover:bg-green-700 text-white px-4 py-3 rounded-lg font-medium flex items-center justify-center"> |
|
<i class="fas fa-file-word mr-2"></i> Download as DOC |
|
</button> |
|
<button id="download-html" class="bg-purple-600 hover:bg-purple-700 text-white px-4 py-3 rounded-lg font-medium flex items-center justify-center"> |
|
<i class="fas fa-code mr-2"></i> Download as HTML |
|
</button> |
|
</div> |
|
|
|
<div class="mt-6 bg-yellow-50 border-l-4 border-yellow-400 p-4"> |
|
<div class="flex"> |
|
<div class="flex-shrink-0"> |
|
<i class="fas fa-lightbulb text-yellow-400"></i> |
|
</div> |
|
<div class="ml-3"> |
|
<p class="text-sm text-yellow-700"> |
|
<span class="font-medium">ATS Tip:</span> Use specific job titles, skills from the job description, and quantify achievements for better results. |
|
</p> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
// DOM Elements |
|
const fullNameInput = document.getElementById('full-name'); |
|
const professionalTitleInput = document.getElementById('professional-title'); |
|
const emailInput = document.getElementById('email'); |
|
const phoneInput = document.getElementById('phone'); |
|
const locationInput = document.getElementById('location'); |
|
const linkedinInput = document.getElementById('linkedin'); |
|
const portfolioInput = document.getElementById('portfolio'); |
|
const professionalSummaryInput = document.getElementById('professional-summary'); |
|
const additionalSkillsInput = document.getElementById('additional-skills'); |
|
const resumePreview = document.getElementById('resume-preview'); |
|
const completionProgress = document.getElementById('completion-progress'); |
|
const completionText = document.getElementById('completion-text'); |
|
const atsScoreElement = document.getElementById('ats-score'); |
|
const keywordCountElement = document.getElementById('keyword-count'); |
|
const downloadPdfBtn = document.getElementById('download-pdf'); |
|
const downloadDocBtn = document.getElementById('download-doc'); |
|
const downloadHtmlBtn = document.getElementById('download-html'); |
|
|
|
// Add event listeners to all inputs to update the preview |
|
document.querySelectorAll('input, textarea, select').forEach(input => { |
|
input.addEventListener('input', updateResumePreview); |
|
}); |
|
|
|
// Template and color selection |
|
document.querySelectorAll('input[name="template"], input[name="color"]').forEach(input => { |
|
input.addEventListener('change', updateResumePreview); |
|
}); |
|
|
|
// Download buttons |
|
downloadPdfBtn.addEventListener('click', downloadAsPDF); |
|
downloadDocBtn.addEventListener('click', downloadAsDOC); |
|
downloadHtmlBtn.addEventListener('click', downloadAsHTML); |
|
|
|
// Initialize the resume preview |
|
updateResumePreview(); |
|
|
|
// Function to update the resume preview |
|
function updateResumePreview() { |
|
// Calculate completion percentage |
|
const totalFields = document.querySelectorAll('input[required], textarea[required], select[required]').length; |
|
let filledFields = 0; |
|
|
|
document.querySelectorAll('input[required], textarea[required], select[required]').forEach(field => { |
|
if (field.value.trim() !== '') filledFields++; |
|
}); |
|
|
|
const completionPercentage = Math.round((filledFields / totalFields) * 100); |
|
completionProgress.style.width = `${completionPercentage}%`; |
|
completionText.textContent = `${completionPercentage}% Complete`; |
|
|
|
// Update ATS score (simplified for this example) |
|
const atsScore = Math.min(100, completionPercentage + Math.floor(Math.random() * 20)); |
|
atsScoreElement.textContent = `${atsScore}/100`; |
|
|
|
if (atsScore > 80) { |
|
atsScoreElement.className = 'ml-2 px-2 py-1 bg-green-100 text-green-800 rounded-full text-xs'; |
|
} else if (atsScore > 60) { |
|
atsScoreElement.className = 'ml-2 px-2 py-1 bg-yellow-100 text-yellow-800 rounded-full text-xs'; |
|
} else { |
|
atsScoreElement.className = 'ml-2 px-2 py-1 bg-red-100 text-red-800 rounded-full text-xs'; |
|
} |
|
|
|
// Count keywords (simplified for this example) |
|
const keywordCount = professionalSummaryInput.value.split(' ').length; |
|
keywordCountElement.textContent = keywordCount; |
|
|
|
// Get selected template and color |
|
const selectedTemplate = document.querySelector('input[name="template"]:checked').value; |
|
const selectedColor = document.querySelector('input[name="color"]:checked').value; |
|
|
|
// Generate the resume HTML based on the selected template |
|
let resumeHTML = ''; |
|
|
|
if (selectedTemplate === 'modern') { |
|
resumeHTML = generateModernResume(selectedColor); |
|
} else { |
|
resumeHTML = generateClassicResume(selectedColor); |
|
} |
|
|
|
resumePreview.innerHTML = resumeHTML; |
|
} |
|
|
|
// Function to generate modern resume template |
|
function generateModernResume(color) { |
|
const colorClasses = { |
|
blue: { bg: 'bg-blue-600', text: 'text-blue-600', light: 'bg-blue-50', border: 'border-blue-200' }, |
|
green: { bg: 'bg-green-600', text: 'text-green-600', light: 'bg-green-50', border: 'border-green-200' }, |
|
purple: { bg: 'bg-purple-600', text: 'text-purple-600', light: 'bg-purple-50', border: 'border-purple-200' }, |
|
red: { bg: 'bg-red-600', text: 'text-red-600', light: 'bg-red-50', border: 'border-red-200' }, |
|
indigo: { bg: 'bg-indigo-600', text: 'text-indigo-600', light: 'bg-indigo-50', border: 'border-indigo-200' } |
|
}; |
|
|
|
const colorScheme = colorClasses[color] || colorClasses.blue; |
|
|
|
// Personal Information |
|
const name = fullNameInput.value || 'Your Name'; |
|
const title = professionalTitleInput.value || 'Professional Title'; |
|
const email = emailInput.value || '[email protected]'; |
|
const phone = phoneInput.value || '(123) 456-7890'; |
|
const location = locationInput.value || 'City, Country'; |
|
const linkedin = linkedinInput.value || ''; |
|
const portfolio = portfolioInput.value || ''; |
|
const summary = professionalSummaryInput.value || 'Professional summary highlighting your experience, skills, and achievements. Keep it concise (3-5 sentences).'; |
|
|
|
// Generate contact info HTML |
|
let contactHTML = ` |
|
<div class="mb-1"><i class="fas fa-envelope mr-2 ${colorScheme.text}"></i> ${email}</div> |
|
<div class="mb-1"><i class="fas fa-phone mr-2 ${colorScheme.text}"></i> ${phone}</div> |
|
<div class="mb-1"><i class="fas fa-map-marker-alt mr-2 ${colorScheme.text}"></i> ${location}</div> |
|
`; |
|
|
|
if (linkedin) { |
|
contactHTML += `<div class="mb-1"><i class="fab fa-linkedin mr-2 ${colorScheme.text}"></i> ${linkedin.replace('https://', '').replace('www.', '')}</div>`; |
|
} |
|
|
|
if (portfolio) { |
|
contactHTML += `<div class="mb-1"><i class="fas fa-globe mr-2 ${colorScheme.text}"></i> ${portfolio.replace('https://', '').replace('www.', '')}</div>`; |
|
} |
|
|
|
// Work Experience |
|
let experienceHTML = ''; |
|
document.querySelectorAll('.experience-item').forEach((exp, index) => { |
|
const title = exp.querySelector('.experience-title').value || 'Job Title'; |
|
const company = exp.querySelector('.experience-company').value || 'Company Name'; |
|
const start = exp.querySelector('.experience-start').value || 'YYYY-MM'; |
|
const end = exp.querySelector('.experience-current').checked ? 'Present' : (exp.querySelector('.experience-end').value || 'YYYY-MM'); |
|
const description = exp.querySelector('.experience-description').value || 'Responsibilities and achievements in this role.'; |
|
|
|
// Format description with bullet points |
|
const formattedDescription = description.split('\n') |
|
.filter(line => line.trim() !== '') |
|
.map(line => line.startsWith('•') ? line : `• ${line}`) |
|
.join('<br>'); |
|
|
|
experienceHTML += ` |
|
<div class="mb-6 ${index > 0 ? 'mt-6' : ''}"> |
|
<h3 class="text-lg font-semibold">${title}</h3> |
|
<div class="flex justify-between items-center mb-1"> |
|
<span class="text-gray-600">${company}</span> |
|
<span class="text-sm text-gray-500">${start} - ${end}</span> |
|
</div> |
|
<div class="text-gray-700 mt-2">${formattedDescription}</div> |
|
</div> |
|
`; |
|
}); |
|
|
|
if (!experienceHTML) { |
|
experienceHTML = '<div class="text-gray-500 italic">Add your work experience</div>'; |
|
} |
|
|
|
// Education |
|
let educationHTML = ''; |
|
document.querySelectorAll('.education-item').forEach((edu, index) => { |
|
const degree = edu.querySelector('.education-degree').value || 'Degree'; |
|
const institution = edu.querySelector('.education-institution').value || 'Institution'; |
|
const start = edu.querySelector('.education-start').value || 'YYYY-MM'; |
|
const end = edu.querySelector('.education-current').checked ? 'Present' : (edu.querySelector('.education-end').value || 'YYYY-MM'); |
|
const achievements = edu.querySelector('.education-achievements').value || ''; |
|
|
|
educationHTML += ` |
|
<div class="mb-4 ${index > 0 ? 'mt-4' : ''}"> |
|
<h3 class="text-lg font-semibold">${degree}</h3> |
|
<div class="flex justify-between items-center mb-1"> |
|
<span class="text-gray-600">${institution}</span> |
|
<span class="text-sm text-gray-500">${start} - ${end}</span> |
|
</div> |
|
${achievements ? `<div class="text-gray-700 mt-1">${achievements.replace(/\n/g, '<br>')}</div>` : ''} |
|
</div> |
|
`; |
|
}); |
|
|
|
if (!educationHTML) { |
|
educationHTML = '<div class="text-gray-500 italic">Add your education</div>'; |
|
} |
|
|
|
// Skills |
|
let skillsHTML = ''; |
|
document.querySelectorAll('.skill-item').forEach(skill => { |
|
const name = skill.querySelector('.skill-name').value || 'Skill'; |
|
const level = skill.querySelector('.skill-level').value || 'advanced'; |
|
|
|
const levelMap = { |
|
beginner: '25%', |
|
intermediate: '50%', |
|
advanced: '75%', |
|
expert: '100%' |
|
}; |
|
|
|
skillsHTML += ` |
|
<div class="mb-3"> |
|
<div class="flex justify-between items-center mb-1"> |
|
<span class="font-medium">${name}</span> |
|
<span class="text-xs text-gray-500 capitalize">${level}</span> |
|
</div> |
|
<div class="relative skill-level"> |
|
<div class="skill-level-fill" style="width: ${levelMap[level]}; background-color: ${colorScheme.text.replace('text-', 'bg-')}"></div> |
|
</div> |
|
</div> |
|
`; |
|
}); |
|
|
|
// Additional skills |
|
const additionalSkills = additionalSkillsInput.value; |
|
if (additionalSkills) { |
|
skillsHTML += ` |
|
<div class="mt-4"> |
|
<h4 class="font-medium mb-2">Additional Skills</h4> |
|
<div class="flex flex-wrap gap-2"> |
|
${additionalSkills.split(',').map(skill => ` |
|
<span class="text-xs px-3 py-1 rounded-full ${colorScheme.light} ${colorScheme.text}">${skill.trim()}</span> |
|
`).join('')} |
|
</div> |
|
</div> |
|
`; |
|
} |
|
|
|
if (!skillsHTML) { |
|
skillsHTML = '<div class="text-gray-500 italic">Add your skills</div>'; |
|
} |
|
|
|
// Projects |
|
let projectsHTML = ''; |
|
document.querySelectorAll('.project-item').forEach(project => { |
|
const name = project.querySelector('.project-name').value || 'Project Name'; |
|
const url = project.querySelector('.project-url').value || ''; |
|
const description = project.querySelector('.project-description').value || 'Project description and your role.'; |
|
|
|
projectsHTML += ` |
|
<div class="mb-4"> |
|
<h3 class="font-semibold">${name}</h3> |
|
${url ? `<div class="text-sm mb-1"><i class="fas fa-link mr-1 ${colorScheme.text}"></i> <a href="${url}" class="text-blue-600 hover:underline">${url.replace('https://', '').replace('www.', '')}</a></div>` : ''} |
|
<div class="text-gray-700">${description.replace(/\n/g, '<br>')}</div> |
|
</div> |
|
`; |
|
}); |
|
|
|
if (!projectsHTML) { |
|
projectsHTML = '<div class="text-gray-500 italic">Add your projects</div>'; |
|
} |
|
|
|
// Certifications |
|
let certificationsHTML = ''; |
|
document.querySelectorAll('.certification-item').forEach(cert => { |
|
const name = cert.querySelector('.certification-name').value || 'Certification Name'; |
|
const org = cert.querySelector('.certification-org').value || 'Issuing Organization'; |
|
const date = cert.querySelector('.certification-date').value || 'YYYY-MM'; |
|
const id = cert.querySelector('.certification-id').value || ''; |
|
|
|
certificationsHTML += ` |
|
<div class="mb-3"> |
|
<h3 class="font-semibold">${name}</h3> |
|
<div class="flex justify-between items-center"> |
|
<span class="text-gray-600">${org}</span> |
|
<span class="text-sm text-gray-500">${date}</span> |
|
</div> |
|
${id ? `<div class="text-xs mt-1 text-gray-500">${id}</div>` : ''} |
|
</div> |
|
`; |
|
}); |
|
|
|
if (!certificationsHTML) { |
|
certificationsHTML = '<div class="text-gray-500 italic">Add your certifications</div>'; |
|
} |
|
|
|
// Languages |
|
let languagesHTML = ''; |
|
document.querySelectorAll('.language-item').forEach(lang => { |
|
const name = lang.querySelector('.language-name').value || 'Language'; |
|
const level = lang.querySelector('.language-level').value || 'fluent'; |
|
|
|
const levelText = { |
|
native: 'Native', |
|
fluent: 'Fluent', |
|
intermediate: 'Intermediate', |
|
basic: 'Basic' |
|
}; |
|
|
|
languagesHTML += ` |
|
<div class="flex justify-between items-center mb-2"> |
|
<span class="font-medium">${name}</span> |
|
<span class="text-sm text-gray-500">${levelText[level]}</span> |
|
</div> |
|
`; |
|
}); |
|
|
|
if (!languagesHTML) { |
|
languagesHTML = '<div class="text-gray-500 italic">Add your languages</div>'; |
|
} |
|
|
|
// Generate the full resume HTML |
|
return ` |
|
<div class="resume-paper p-8"> |
|
<div class="${colorScheme.bg} text-white p-6 rounded-lg mb-6"> |
|
<h1 class="text-3xl font-bold mb-1">${name}</h1> |
|
<h2 class="text-xl">${title}</h2> |
|
</div> |
|
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6"> |
|
<div class="md:col-span-2"> |
|
<div class="mb-6"> |
|
<h2 class="text-xl font-semibold mb-3 ${colorScheme.text} border-b ${colorScheme.border} pb-1">Professional Summary</h2> |
|
<p class="text-gray-700">${summary.replace(/\n/g, '<br>')}</p> |
|
</div> |
|
|
|
<div class="mb-6"> |
|
<h2 class="text-xl font-semibold mb-3 ${colorScheme.text} border-b ${colorScheme.border} pb-1">Work Experience</h2> |
|
${experienceHTML} |
|
</div> |
|
|
|
<div class="mb-6"> |
|
<h2 class="text-xl font-semibold mb-3 ${colorScheme.text} border-b ${colorScheme.border} pb-1">Projects</h2> |
|
${projectsHTML} |
|
</div> |
|
</div> |
|
|
|
<div> |
|
<div class="mb-6"> |
|
<h2 class="text-xl font-semibold mb-3 ${colorScheme.text} border-b ${colorScheme.border} pb-1">Contact</h2> |
|
${contactHTML} |
|
</div> |
|
|
|
<div class="mb-6"> |
|
<h2 class="text-xl font-semibold mb-3 ${colorScheme.text} border-b ${colorScheme.border} pb-1">Skills</h2> |
|
${skillsHTML} |
|
</div> |
|
|
|
<div class="mb-6"> |
|
<h2 class="text-xl font-semibold mb-3 ${colorScheme.text} border-b ${colorScheme.border} pb-1">Education</h2> |
|
${educationHTML} |
|
</div> |
|
|
|
<div class="mb-6"> |
|
<h2 class="text-xl font-semibold mb-3 ${colorScheme.text} border-b ${colorScheme.border} pb-1">Certifications</h2> |
|
${certificationsHTML} |
|
</div> |
|
|
|
<div class="mb-6"> |
|
<h2 class="text-xl font-semibold mb-3 ${colorScheme.text} border-b ${colorScheme.border} pb-1">Languages</h2> |
|
${languagesHTML} |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
`; |
|
} |
|
|
|
// Function to generate classic resume template |
|
function generateClassicResume(color) { |
|
const colorClasses = { |
|
blue: { text: 'text-blue-600', border: 'border-blue-200' }, |
|
green: { text: 'text-green-600', border: 'border-green-200' }, |
|
purple: { text: 'text-purple-600', border: 'border-purple-200' }, |
|
red: { text: 'text-red-600', border: 'border-red-200' }, |
|
indigo: { text: 'text-indigo-600', border: 'border-indigo-200' } |
|
}; |
|
|
|
const colorScheme = colorClasses[color] || colorClasses.blue; |
|
|
|
// Personal Information |
|
const name = fullNameInput.value || 'Your Name'; |
|
const title = professionalTitleInput.value || 'Professional Title'; |
|
const email = emailInput.value || '[email protected]'; |
|
const phone = phoneInput.value || '(123) 456-7890'; |
|
const location = locationInput.value || 'City, Country'; |
|
const linkedin = linkedinInput.value || ''; |
|
const portfolio = portfolioInput.value || ''; |
|
const summary = professionalSummaryInput.value || 'Professional summary highlighting your experience, skills, and achievements. Keep it concise (3-5 sentences).'; |
|
|
|
// Generate contact info HTML |
|
let contactHTML = ` |
|
<div class="flex flex-wrap gap-4 text-sm"> |
|
<div><i class="fas fa-envelope mr-1 ${colorScheme.text}"></i> ${email}</div> |
|
<div><i class="fas fa-phone mr-1 ${colorScheme.text}"></i> ${phone}</div> |
|
<div><i class="fas fa-map-marker-alt mr-1 ${colorScheme.text}"></i> ${location}</div> |
|
${linkedin ? `<div><i class="fab fa-linkedin mr-1 ${colorScheme.text}"></i> ${linkedin.replace('https://', '').replace('www.', '')}</div>` : ''} |
|
${portfolio ? `<div><i class="fas fa-globe mr-1 ${colorScheme.text}"></i> ${portfolio.replace('https://', '').replace('www.', '')}</div>` : ''} |
|
</div> |
|
`; |
|
|
|
// Work Experience |
|
let experienceHTML = ''; |
|
document.querySelectorAll('.experience-item').forEach((exp, index) => { |
|
const title = exp.querySelector('.experience-title').value || 'Job Title'; |
|
const company = exp.querySelector('.experience-company').value || 'Company Name'; |
|
const start = exp.querySelector('.experience-start').value || 'YYYY-MM'; |
|
const end = exp.querySelector('.experience-current').checked ? 'Present' : (exp.querySelector('.experience-end').value || 'YYYY-MM'); |
|
const description = exp.querySelector('.experience-description').value || 'Responsibilities and achievements in this role.'; |
|
|
|
// Format description with bullet points |
|
const formattedDescription = description.split('\n') |
|
.filter(line => line.trim() !== '') |
|
.map(line => line.startsWith('•') ? line : `• ${line}`) |
|
.join('<br>'); |
|
|
|
experienceHTML += ` |
|
<div class="mb-4 ${index > 0 ? 'mt-4' : ''}"> |
|
<div class="flex justify-between items-center"> |
|
<h3 class="font-semibold">${title}</h3> |
|
<span class="text-sm text-gray-500">${start} - ${end}</span> |
|
</div> |
|
<div class="text-gray-600 mb-1">${company}</div> |
|
<div class="text-gray-700 ml-4">${formattedDescription}</div> |
|
</div> |
|
`; |
|
}); |
|
|
|
if (!experienceHTML) { |
|
experienceHTML = '<div class="text-gray-500 italic">Add your work experience</div>'; |
|
} |
|
|
|
// Education |
|
let educationHTML = ''; |
|
document.querySelectorAll('.education-item').forEach((edu, index) => { |
|
const degree = edu.querySelector('.education-degree').value || 'Degree'; |
|
const institution = edu.querySelector('.education-institution').value || 'Institution'; |
|
const start = edu.querySelector('.education-start').value || 'YYYY-MM'; |
|
const end = edu.querySelector('.education-current').checked ? 'Present' : (edu.querySelector('.education-end').value || 'YYYY-MM'); |
|
const achievements = edu.querySelector('.education-achievements').value || ''; |
|
|
|
educationHTML += ` |
|
<div class="mb-3 ${index > 0 ? 'mt-3' : ''}"> |
|
<div class="flex justify-between items-center"> |
|
<h3 class="font-semibold">${degree}</h3> |
|
<span class="text-sm text-gray-500">${start} - ${end}</span> |
|
</div> |
|
<div class="text-gray-600">${institution}</div> |
|
${achievements ? `<div class="text-gray-700 mt-1">${achievements.replace(/\n/g, '<br>')}</div>` : ''} |
|
</div> |
|
`; |
|
}); |
|
|
|
if (!educationHTML) { |
|
educationHTML = '<div class="text-gray-500 italic">Add your education</div>'; |
|
} |
|
|
|
// Skills |
|
let skillsHTML = ''; |
|
document.querySelectorAll('.skill-item').forEach(skill => { |
|
const name = skill.querySelector('.skill-name').value || 'Skill'; |
|
const level = skill.querySelector('.skill-level').value || 'advanced'; |
|
|
|
skillsHTML += ` |
|
<div class="mb-1"> |
|
<span class="font-medium">${name}</span> |
|
<span class="text-xs text-gray-500 ml-1 capitalize">(${level})</span> |
|
</div> |
|
`; |
|
}); |
|
|
|
// Additional skills |
|
const additionalSkills = additionalSkillsInput.value; |
|
if (additionalSkills) { |
|
skillsHTML += ` |
|
<div class="mt-2"> |
|
<div class="text-sm font-medium mb-1">Additional:</div> |
|
<div class="text-sm text-gray-700">${additionalSkills}</div> |
|
</div> |
|
`; |
|
} |
|
|
|
if (!skillsHTML) { |
|
skillsHTML = '<div class="text-gray-500 italic">Add your skills</div>'; |
|
} |
|
|
|
// Projects |
|
let projectsHTML = ''; |
|
document.querySelectorAll('.project-item').forEach(project => { |
|
const name = project.querySelector('.project-name').value || 'Project Name'; |
|
const url = project.querySelector('.project-url').value || ''; |
|
const description = project.querySelector('.project-description').value || 'Project description and your role.'; |
|
|
|
projectsHTML += ` |
|
<div class="mb-3"> |
|
<h3 class="font-semibold">${name}</h3> |
|
${url ? `<div class="text-sm mb-1"><i class="fas fa-link mr-1 ${colorScheme.text}"></i> <a href="${url}" class="text-blue-600 hover:underline">${url.replace('https://', '').replace('www.', '')}</a></div>` : ''} |
|
<div class="text-gray-700">${description.replace(/\n/g, '<br>')}</div> |
|
</div> |
|
`; |
|
}); |
|
|
|
if (!projectsHTML) { |
|
projectsHTML = '<div class="text-gray-500 italic">Add your projects</div>'; |
|
} |
|
|
|
// Certifications |
|
let certificationsHTML = ''; |
|
document.querySelectorAll('.certification-item').forEach(cert => { |
|
const name = cert.querySelector('.certification-name').value || 'Certification Name'; |
|
const org = cert.querySelector('.certification-org').value || 'Issuing Organization'; |
|
const date = cert.querySelector('.certification-date').value || 'YYYY-MM'; |
|
const id = cert.querySelector('.certification-id').value || ''; |
|
|
|
certificationsHTML += ` |
|
<div class="mb-2"> |
|
<h3 class="font-semibold">${name}</h3> |
|
<div class="flex justify-between items-center"> |
|
<span class="text-gray-600">${org}</span> |
|
<span class="text-sm text-gray-500">${date}</span> |
|
</div> |
|
${id ? `<div class="text-xs mt-1 text-gray-500">${id}</div>` : ''} |
|
</div> |
|
`; |
|
}); |
|
|
|
if (!certificationsHTML) { |
|
certificationsHTML = '<div class="text-gray-500 italic">Add your certifications</div>'; |
|
} |
|
|
|
// Languages |
|
let languagesHTML = ''; |
|
document.querySelectorAll('.language-item').forEach(lang => { |
|
const name = lang.querySelector('.language-name').value || 'Language'; |
|
const level = lang.querySelector('.language-level').value || 'fluent'; |
|
|
|
const levelText = { |
|
native: 'Native', |
|
fluent: 'Fluent', |
|
intermediate: 'Intermediate', |
|
basic: 'Basic' |
|
}; |
|
|
|
languagesHTML += ` |
|
<div class="flex justify-between items-center mb-1"> |
|
<span class="font-medium">${name}</span> |
|
<span class="text-sm text-gray-500">${levelText[level]}</span> |
|
</div> |
|
`; |
|
}); |
|
|
|
if (!languagesHTML) { |
|
languagesHTML = '<div class="text-gray-500 italic">Add your languages</div>'; |
|
} |
|
|
|
// Generate the full resume HTML |
|
return ` |
|
<div class="resume-paper p-8"> |
|
<div class="text-center mb-6"> |
|
<h1 class="text-3xl font-bold mb-1">${name}</h1> |
|
<h2 class="text-xl text-gray-600 mb-3">${title}</h2> |
|
${contactHTML} |
|
</div> |
|
|
|
<div class="mb-6"> |
|
<h2 class="text-xl font-semibold mb-3 ${colorScheme.text} border-b ${colorScheme.border} pb-1">Summary</h2> |
|
<p class="text-gray-700">${summary.replace(/\n/g, '<br>')}</p> |
|
</div> |
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8"> |
|
<div> |
|
<div class="mb-6"> |
|
<h2 class="text-xl font-semibold mb-3 ${colorScheme.text} border-b ${colorScheme.border} pb-1">Experience</h2> |
|
${experienceHTML} |
|
</div> |
|
|
|
<div class="mb-6"> |
|
<h2 class="text-xl font-semibold mb-3 ${colorScheme.text} border-b ${colorScheme.border} pb-1">Projects</h2> |
|
${projectsHTML} |
|
</div> |
|
|
|
<div class="mb-6"> |
|
<h2 class="text-xl font-semibold mb-3 ${colorScheme.text} border-b ${colorScheme.border} pb-1">Education</h2> |
|
${educationHTML} |
|
</div> |
|
</div> |
|
|
|
<div> |
|
<div class="mb-6"> |
|
<h2 class="text-xl font-semibold mb-3 ${colorScheme.text} border-b ${colorScheme.border} pb-1">Skills</h2> |
|
${skillsHTML} |
|
</div> |
|
|
|
<div class="mb-6"> |
|
<h2 class="text-xl font-semibold mb-3 ${colorScheme.text} border-b ${colorScheme.border} pb-1">Certifications</h2> |
|
${certificationsHTML} |
|
</div> |
|
|
|
<div class="mb-6"> |
|
<h2 class="text-xl font-semibold mb-3 ${colorScheme.text} border-b ${colorScheme.border} pb-1">Languages</h2> |
|
${languagesHTML} |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
`; |
|
} |
|
|
|
// Function to add a new experience section |
|
document.getElementById('add-experience').addEventListener('click', function() { |
|
const container = document.getElementById('experience-container'); |
|
const newItem = document.createElement('div'); |
|
newItem.className = 'experience-item mb-6 p-4 border rounded-lg fade-in'; |
|
newItem.innerHTML = ` |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Job Title*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 experience-title" placeholder="Senior Developer"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Company Name*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 experience-company" placeholder="Tech Corp Inc."> |
|
</div> |
|
</div> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Start Date*</label> |
|
<input type="month" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 experience-start"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">End Date (or present)</label> |
|
<input type="month" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 experience-end"> |
|
<div class="flex items-center mt-2"> |
|
<input type="checkbox" class="mr-2 experience-current"> |
|
<span class="text-sm text-gray-600">I currently work here</span> |
|
</div> |
|
</div> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Responsibilities & Achievements*</label> |
|
<textarea class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 experience-description" rows="3" placeholder="Describe your responsibilities and key achievements using action verbs (e.g., Developed, Led, Optimized)"></textarea> |
|
<p class="text-xs text-gray-500 mt-1">Use bullet points for better ATS parsing. Example: "• Led a team of 5 developers to deliver a SaaS product"</p> |
|
</div> |
|
<button class="remove-experience mt-2 text-red-500 text-sm flex items-center"> |
|
<i class="fas fa-trash mr-1"></i> Remove this experience |
|
</button> |
|
`; |
|
|
|
container.appendChild(newItem); |
|
|
|
// Add event listeners to new inputs |
|
newItem.querySelectorAll('input, textarea, select').forEach(input => { |
|
input.addEventListener('input', updateResumePreview); |
|
}); |
|
|
|
// Add event listener to remove button |
|
newItem.querySelector('.remove-experience').addEventListener('click', function() { |
|
newItem.classList.add('fade-out'); |
|
setTimeout(() => { |
|
container.removeChild(newItem); |
|
updateResumePreview(); |
|
}, 300); |
|
}); |
|
|
|
// Add event listener to current job checkbox |
|
newItem.querySelector('.experience-current').addEventListener('change', function() { |
|
const endDateInput = newItem.querySelector('.experience-end'); |
|
if (this.checked) { |
|
endDateInput.disabled = true; |
|
endDateInput.value = ''; |
|
} else { |
|
endDateInput.disabled = false; |
|
} |
|
updateResumePreview(); |
|
}); |
|
|
|
updateResumePreview(); |
|
}); |
|
|
|
// Function to add a new education section |
|
document.getElementById('add-education').addEventListener('click', function() { |
|
const container = document.getElementById('education-container'); |
|
const newItem = document.createElement('div'); |
|
newItem.className = 'education-item mb-6 p-4 border rounded-lg fade-in'; |
|
newItem.innerHTML = ` |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Degree*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 education-degree" placeholder="Bachelor of Science in Computer Science"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Institution*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 education-institution" placeholder="University of Technology"> |
|
</div> |
|
</div> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Start Date*</label> |
|
<input type="month" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 education-start"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">End Date (or expected)</label> |
|
<input type="month" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 education-end"> |
|
<div class="flex items-center mt-2"> |
|
<input type="checkbox" class="mr-2 education-current"> |
|
<span class="text-sm text-gray-600">Currently studying here</span> |
|
</div |
|
</div> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Notable Achievements (optional)</label> |
|
<textarea class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 education-achievements" rows="2" placeholder="Honors, awards, relevant coursework"></textarea> |
|
</div> |
|
<button class="remove-education mt-2 text-red-500 text-sm flex items-center"> |
|
<i class="fas fa-trash mr-1"></i> Remove this education |
|
</button> |
|
`; |
|
|
|
container.appendChild(newItem); |
|
|
|
// Add event listeners to new inputs |
|
newItem.querySelectorAll('input, textarea, select').forEach(input => { |
|
input.addEventListener('input', updateResumePreview); |
|
}); |
|
|
|
// Add event listener to remove button |
|
newItem.querySelector('.remove-education').addEventListener('click', function() { |
|
newItem.classList.add('fade-out'); |
|
setTimeout(() => { |
|
container.removeChild(newItem); |
|
updateResumePreview(); |
|
}, 300); |
|
}); |
|
|
|
// Add event listener to current study checkbox |
|
newItem.querySelector('.education-current').addEventListener('change', function() { |
|
const endDateInput = newItem.querySelector('.education-end'); |
|
if (this.checked) { |
|
endDateInput.disabled = true; |
|
endDateInput.value = ''; |
|
} else { |
|
endDateInput.disabled = false; |
|
} |
|
updateResumePreview(); |
|
}); |
|
|
|
updateResumePreview(); |
|
}); |
|
|
|
// Function to add a new skill section |
|
document.getElementById('add-skill').addEventListener('click', function() { |
|
const container = document.getElementById('skills-container'); |
|
const newItem = document.createElement('div'); |
|
newItem.className = 'skill-item mb-4 p-4 border rounded-lg fade-in'; |
|
newItem.innerHTML = ` |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Skill Name*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 skill-name" placeholder="JavaScript"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Skill Level*</label> |
|
<select class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 skill-level"> |
|
<option value="beginner">Beginner</option> |
|
<option value="intermediate">Intermediate</option> |
|
<option value="advanced" selected>Advanced</option> |
|
<option value="expert">Expert</option> |
|
</select> |
|
</div> |
|
</div> |
|
<button class="remove-skill text-red-500 text-sm flex items-center"> |
|
<i class="fas fa-trash mr-1"></i> Remove this skill |
|
</button> |
|
`; |
|
|
|
container.appendChild(newItem); |
|
|
|
// Add event listeners to new inputs |
|
newItem.querySelectorAll('input, textarea, select').forEach(input => { |
|
input.addEventListener('input', updateResumePreview); |
|
}); |
|
|
|
// Add event listener to remove button |
|
newItem.querySelector('.remove-skill').addEventListener('click', function() { |
|
newItem.classList.add('fade-out'); |
|
setTimeout(() => { |
|
container.removeChild(newItem); |
|
updateResumePreview(); |
|
}, 300); |
|
}); |
|
|
|
updateResumePreview(); |
|
}); |
|
|
|
// Function to add a new project section |
|
document.getElementById('add-project').addEventListener('click', function() { |
|
const container = document.getElementById('projects-container'); |
|
const newItem = document.createElement('div'); |
|
newItem.className = 'project-item mb-6 p-4 border rounded-lg fade-in'; |
|
newItem.innerHTML = ` |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Project Name*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 project-name" placeholder="E-commerce Website"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Project URL (optional)</label> |
|
<input type="url" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 project-url" placeholder="https://example.com"> |
|
</div> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Project Description*</label> |
|
<textarea class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 project-description" rows="3" placeholder="Describe the project, technologies used, and your role"></textarea> |
|
<p class="text-xs text-gray-500 mt-1">Use action verbs and quantify results when possible (e.g., "Increased performance by 30%")</p> |
|
</div> |
|
<button class="remove-project mt-2 text-red-500 text-sm flex items-center"> |
|
<i class="fas fa-trash mr-1"></i> Remove this project |
|
</button> |
|
`; |
|
|
|
container.appendChild(newItem); |
|
|
|
// Add event listeners to new inputs |
|
newItem.querySelectorAll('input, textarea, select').forEach(input => { |
|
input.addEventListener('input', updateResumePreview); |
|
}); |
|
|
|
// Add event listener to remove button |
|
newItem.querySelector('.remove-project').addEventListener('click', function() { |
|
newItem.classList.add('fade-out'); |
|
setTimeout(() => { |
|
container.removeChild(newItem); |
|
updateResumePreview(); |
|
}, 300); |
|
}); |
|
|
|
updateResumePreview(); |
|
}); |
|
|
|
// Function to add a new certification section |
|
document.getElementById('add-certification').addEventListener('click', function() { |
|
const container = document.getElementById('certifications-container'); |
|
const newItem = document.createElement('div'); |
|
newItem.className = 'certification-item mb-4 p-4 border rounded-lg fade-in'; |
|
newItem.innerHTML = ` |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Certification Name*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 certification-name" placeholder="AWS Certified Solutions Architect"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Issuing Organization*</label> |
|
<input type="text" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 certification-org" placeholder="Amazon Web Services"> |
|
</div> |
|
</div> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-3"> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Date Earned*</label> |
|
<input type="month" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 certification-date"> |
|
</div> |
|
<div> |
|
<label class="block text-gray-700 mb-1">Credential ID (optional)</label> |
|
<input type="text" class="w-full px-4 py |
|
</html> |