Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Resume Optimizer</title> | |
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> | |
<style> | |
:root { | |
--primary-color: #003366; | |
--secondary-color: #f0f2f5; | |
--accent-color: #ff6b6b; | |
} | |
body { | |
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
line-height: 1.6; | |
margin: 0; | |
padding: 20px; | |
background-color: var(--secondary-color); | |
color: #333; | |
} | |
.container { | |
max-width: 1200px; | |
margin: 0 auto; | |
} | |
h1, h2 { | |
color: var(--primary-color); | |
} | |
h1 { | |
text-align: center; | |
margin-bottom: 30px; | |
} | |
form { | |
background: #ffffff; | |
padding: 20px; | |
border-radius: 8px; | |
box-shadow: 0 2px 10px rgba(0,0,0,0.1); | |
margin-bottom: 30px; | |
display: flex; | |
flex-wrap: wrap; | |
gap: 20px; | |
align-items: flex-start; | |
} | |
.form-group { | |
flex: 1 1 calc(50% - 10px); | |
min-width: 250px; | |
} | |
label { | |
display: block; | |
margin-bottom: 8px; | |
color: var(--primary-color); | |
font-weight: bold; | |
} | |
input[type="text"], input[type="file"], textarea { | |
width: 100%; | |
padding: 10px; | |
margin-bottom: 10px; | |
border: 1px solid #ccc; | |
border-radius: 4px; | |
font-size: 14px; | |
transition: border-color 0.3s ease; | |
box-sizing: border-box; | |
} | |
input[type="text"]:focus, textarea:focus { | |
border-color: var(--accent-color); | |
outline: none; | |
} | |
textarea { | |
height: 150px; | |
resize: vertical; | |
} | |
.button-container { | |
flex-basis: 100%; | |
display: flex; | |
justify-content: center; | |
margin-top: 20px; | |
} | |
button { | |
background: var(--primary-color); | |
color: #fff; | |
padding: 10px 20px; | |
border: none; | |
border-radius: 4px; | |
cursor: pointer; | |
font-size: 16px; | |
transition: background-color 0.3s ease; | |
width: auto; | |
min-width: 200px; | |
} | |
button:hover { | |
background: var(--accent-color); | |
} | |
.report-section { | |
background-color: #ffffff; | |
padding: 40px; | |
border-radius: 8px; | |
box-shadow: 0 2px 10px rgba(0,0,0,0.1); | |
margin-top: 30px; | |
display: none; | |
} | |
.report-section h2 { | |
border-bottom: 2px solid var(--accent-color); | |
padding-bottom: 10px; | |
margin-top: 0; | |
} | |
.markdown-body { | |
font-size: 14px; | |
line-height: 1.6; | |
} | |
pre { | |
background-color: #f6f8fa; | |
border-radius: 4px; | |
padding: 15px; | |
overflow-x: auto; | |
font-size: 12px; | |
} | |
#loading { | |
text-align: center; | |
display: none; | |
padding: 20px; | |
} | |
.spinner { | |
display: inline-block; | |
width: 50px; | |
height: 50px; | |
border: 3px solid rgba(0,51,102,.3); | |
border-radius: 50%; | |
border-top-color: var(--primary-color); | |
animation: spin 1s ease-in-out infinite; | |
-webkit-animation: spin 1s ease-in-out infinite; | |
} | |
@keyframes spin { | |
to { -webkit-transform: rotate(360deg); } | |
} | |
@-webkit-keyframes spin { | |
to { -webkit-transform: rotate(360deg); } | |
} | |
.loading-text { | |
margin-top: 10px; | |
font-weight: bold; | |
color: var(--primary-color); | |
} | |
@media (max-width: 768px) { | |
.form-group { | |
flex: 1 1 100%; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<h1>Resume Optimizer</h1> | |
<form id="optimizeForm"> | |
<div class="form-group"> | |
<label for="resumeText">Resume:</label> | |
<textarea id="resumeText" placeholder="Paste your resume here"></textarea> | |
<input type="file" id="resumeFile" accept=".txt,.pdf,.doc,.docx"> | |
</div> | |
<div class="form-group"> | |
<label for="jobDescriptionText">Job Description:</label> | |
<textarea id="jobDescriptionText" placeholder="Paste the job description here"></textarea> | |
<input type="text" id="jobDescriptionUrl" placeholder="Or enter job description URL"> | |
</div> | |
<div class="button-container"> | |
<button type="submit">Optimize Resume</button> | |
</div> | |
</form> | |
<div id="loading"> | |
<div class="spinner"></div> | |
<div class="loading-text">Optimizing your resume...</div> | |
</div> | |
<div id="optimizedResumeContainer" class="report-section"></div> | |
<div id="changesMadeContainer" class="report-section"></div> | |
</div> | |
<script> | |
const AUTH_TOKEN = "44d5c2ac18ced6fc25c1e57dcd06fc0b31fb4ad97bf56e67540671a647465df4"; | |
document.getElementById('optimizeForm').addEventListener('submit', async (e) => { | |
e.preventDefault(); | |
const optimizedResumeContainer = document.getElementById('optimizedResumeContainer'); | |
const changesMadeContainer = document.getElementById('changesMadeContainer'); | |
const loadingDiv = document.getElementById('loading'); | |
// Hide result containers and show loading animation | |
optimizedResumeContainer.style.display = 'none'; | |
changesMadeContainer.style.display = 'none'; | |
loadingDiv.style.display = 'block'; | |
const formData = new FormData(); | |
// Handle resume input | |
const resumeText = document.getElementById('resumeText').value; | |
const resumeFile = document.getElementById('resumeFile').files[0]; | |
if (resumeText) { | |
formData.append('resumeText', resumeText); | |
} else if (resumeFile) { | |
formData.append('resume', resumeFile); | |
} else { | |
loadingDiv.innerHTML = '<div class="loading-text" style="color: red;">Please provide a resume (text or file).</div>'; | |
return; | |
} | |
// Handle job description input | |
const jobDescriptionText = document.getElementById('jobDescriptionText').value; | |
const jobDescriptionUrl = document.getElementById('jobDescriptionUrl').value; | |
if (jobDescriptionText) { | |
formData.append('jobDescription', jobDescriptionText); | |
} else if (jobDescriptionUrl) { | |
formData.append('jobDescriptionUrl', jobDescriptionUrl); | |
} else { | |
loadingDiv.innerHTML = '<div class="loading-text" style="color: red;">Please provide a job description (text or URL).</div>'; | |
return; | |
} | |
try { | |
const response = await fetch('https://pvanand-specialized-agents.hf.space/api/v1/optimize-resume', { | |
method: 'POST', | |
headers: { | |
'Authorization': `Bearer ${AUTH_TOKEN}` | |
}, | |
body: formData | |
}); | |
if (!response.ok) { | |
throw new Error(`HTTP error! status: ${response.status}`); | |
} | |
const data = await response.json(); | |
// Parse optimized resume | |
const optimizedResumeMatch = data.optimizedResume.match(/<optimized_resume>([\s\S]*?)<\/optimized_resume>/); | |
const optimizedResume = optimizedResumeMatch ? optimizedResumeMatch[1] : 'Optimized resume not found.'; | |
// Parse changes made | |
const changesMadeMatch = data.optimizedResume.match(/<changes_made>([\s\S]*?)<\/changes_made>/); | |
const changesMade = changesMadeMatch ? changesMadeMatch[1] : 'Changes not found.'; | |
// Render the optimized resume using Markdown | |
const optimizedResumeHtml = marked.parse(optimizedResume); | |
optimizedResumeContainer.innerHTML = ` | |
<h2>Optimized Resume</h2> | |
<div class="markdown-body">${optimizedResumeHtml}</div> | |
`; | |
changesMadeContainer.innerHTML = ` | |
<h2>Changes Made</h2> | |
<div class="markdown-body">${marked.parse(changesMade)}</div> | |
`; | |
// Hide loading animation and show result containers | |
loadingDiv.style.display = 'none'; | |
optimizedResumeContainer.style.display = 'block'; | |
changesMadeContainer.style.display = 'block'; | |
} catch (error) { | |
loadingDiv.innerHTML = ` | |
<div class="loading-text" style="color: red;">Error: ${error.message}</div> | |
`; | |
} | |
}); | |
</script> | |
</body> | |
</html> |