Spaces:
Paused
Paused
File size: 7,004 Bytes
504df0f 3c4bd31 504df0f 3c4bd31 504df0f af02e64 504df0f 3c4bd31 504df0f af02e64 d8acd61 4741385 504df0f 4741385 27994de 4741385 ce04e48 4741385 d8acd61 4741385 4991915 4741385 4991915 4741385 2ae57cb 504df0f 2ae57cb 4741385 2ae57cb 4741385 2ae57cb 4741385 2ae57cb 4741385 4991915 4741385 2ae57cb 4741385 2ae57cb 4741385 2ae57cb 4741385 2ae57cb 5c64dc0 4741385 5c64dc0 4741385 5c64dc0 4741385 5c64dc0 4741385 5c64dc0 4741385 5c64dc0 2ae57cb 5c64dc0 4741385 5c64dc0 4741385 4991915 4741385 5c64dc0 4741385 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
{% extends "base.html" %}
{% block title %}Apply for {{ job.role }} - Codingo{% endblock %}
{% block hero %}
<section class="hero" style="padding: 3rem 1rem;">
<div class="container">
<div class="hero-content">
<h1>Apply for {{ job.role }}</h1>
<p>{{ job.company }}{% if job.seniority %} • {{ job.seniority }}{% endif %}</p>
</div>
</div>
</section>
{% endblock %}
{% block content %}
<section class="content-section">
<!-- <ul class="breadcrumbs">
<li><a href="{{ url_for('index') }}">Home</a></li>
<li><a href="{{ url_for('jobs') }}">Jobs</a></li>
<li><a href="{{ url_for('job_detail', job_id=job.id) }}">{{ job.role }}</a></li>
<li>Apply</li>
</ul> -->
<div class="card">
<div class="card-header">
<h2>Submit Your Application</h2>
<p>Please upload your resume (PDF, DOCX). Your file will be saved securely for recruiters to review.</p>
</div>
<div class="card-body">
<!-- Application Form -->
<form method="POST" enctype="multipart/form-data">
<div class="form-group">
<label for="resume">Upload Resume</label>
<!-- Resume upload remains mandatory. The file will be stored for recruiter review but is no longer parsed automatically. -->
<input type="file" name="resume" id="resume" class="form-control" required accept=".pdf,.doc,.docx">
<!-- Parse Resume button sits beside the upload to allow users to extract information from their CV. It uses a
type="button" so that clicking it does not submit the form. The actual parsing logic is defined in
the script at the bottom of this template. -->
<button type="button" id="parse-resume" class="btn btn-secondary" style="margin-top:0.5rem;">Parse Resume</button>
</div>
<!-- Name field added to capture the applicant's full name. This input can be autofilled by the resume parser,
but remains editable so applicants can correct any mistakes. -->
<div class="form-group">
<label for="full-name">Full Name</label>
<input type="text" name="full_name" id="full-name" class="form-control" placeholder="e.g. Jane Doe" required>
</div>
<!--
Collect the candidate's skills, experience and education manually.
These fields allow applicants to highlight their background even when resume
parsing is disabled. Entries can be separated by commas, semicolons or newlines;
the backend will normalise them into lists.
-->
<div class="form-group">
<label for="skills">Skills</label>
<textarea name="skills" id="skills" class="form-control" rows="3" placeholder="e.g. Python, Data Analysis, Project Management" required></textarea>
</div>
<div class="form-group">
<label for="experience">Experience</label>
<textarea name="experience" id="experience" class="form-control" rows="3" placeholder="e.g. 3 years at TechCorp as a Backend Developer" required></textarea>
</div>
<div class="form-group">
<label for="education">Education</label>
<textarea name="education" id="education" class="form-control" rows="3" placeholder="e.g. B.Sc. in Computer Science, M.Sc. in Data Science" required></textarea>
</div>
<!-- Interview guidelines removed from this page. They are now displayed on the
"My Applications" page so applicants see them before taking the interview. -->
<div class="application-actions" style="margin-top: 2rem;">
<button type="submit" class="btn btn-primary">Submit Application</button>
</div>
</form>
<div style="margin-top: 1.5rem; text-align: center;">
<a href="{{ url_for('job_detail', job_id=job.id) }}" class="btn btn-outline">Back to Job Details</a>
</div>
</div>
</div>
</section>
<style>
.form-group label {
font-weight: 600;
color: var(--primary);
margin-bottom: 0.5rem;
display: block;
}
.form-control {
width: 100%;
padding: 0.75rem;
font-size: 1rem;
border-radius: 6px;
border: 1px solid #ccc;
}
.application-actions {
text-align: center;
}
.btn-primary {
background: linear-gradient(135deg, var(--primary), var(--secondary));
color: white;
padding: 0.75rem 1.5rem;
font-weight: 500;
border: none;
border-radius: 6px;
cursor: pointer;
}
.btn-primary:hover {
opacity: 0.9;
}
/* Secondary button styling used for the "Parse Resume" control */
.btn-secondary {
background: var(--secondary);
color: white;
padding: 0.75rem 1.5rem;
font-weight: 500;
border: none;
border-radius: 6px;
cursor: pointer;
}
.btn-secondary:hover {
opacity: 0.9;
}
</style>
{# Resume parsing script: attaches click handler to the Parse Resume button. It performs an asynchronous
POST to a placeholder endpoint (`/parse_resume`) with the uploaded file and, upon success,
populates the corresponding form fields. Users can still edit the populated fields. #}
<script>
document.addEventListener('DOMContentLoaded', function() {
const parseBtn = document.getElementById('parse-resume');
if (!parseBtn) return;
parseBtn.addEventListener('click', function() {
const resumeInput = document.getElementById('resume');
if (!resumeInput || !resumeInput.files || resumeInput.files.length === 0) {
alert('Please upload your resume before parsing.');
return;
}
const formData = new FormData();
formData.append('resume', resumeInput.files[0]);
fetch('/parse_resume', {
method: 'POST',
body: formData
}).then(resp => resp.json())
.then(data => {
if (data) {
if (data.name && document.getElementById('full-name')) {
document.getElementById('full-name').value = data.name;
}
if (data.skills && document.getElementById('skills')) {
document.getElementById('skills').value = data.skills;
}
if (data.education && document.getElementById('education')) {
document.getElementById('education').value = data.education;
}
if (data.experience && document.getElementById('experience')) {
document.getElementById('experience').value = data.experience;
}
}
})
.catch(err => {
console.error(err);
alert('Unable to parse resume. Please try again later.');
});
});
});
</script>
{% endblock %}
|