Rehyor commited on
Commit
6f0605d
·
verified ·
1 Parent(s): fc1f6b3

perfect, now:

Browse files

Implement Step 1 and the Skill Extraction Feature
Goal: Build the "Job Details" section and add the (simulated) JavaScript logic to "extract" skills and reveal the next step.

Instructions:

Build "Job Details" UI:

Inside the "1. Enter Job Details" card, add:

A large textarea for the job description.

A dropdown (select) for "Seniority Level" (Internship, Junior, Mid-Level, Senior, Lead, Manager).

An input field for "Minimum Years of Experience".

A primary button labeled "Extract Key Skills & Responsibilities".

Build "Define Screening Criteria" UI:

Inside the "2. Define Screening Criteria" card, add placeholders for the different criteria:

A section with the title Must-Have Skills and a div where skill tags will be added.

A section with the title Nice-to-Have Skills and another div for skill tags.

A textarea for Key Responsibilities & Phrases.

An input field for Negative Keywords.

Add JavaScript Logic:

When the "Extract..." button is clicked:

Show a temporary loading indicator.

After a short delay (e.g., setTimeout(..., 1000)), hide the loading indicator.

Simulate skill extraction: Create a JavaScript function that looks for keywords in the job description textarea and returns an array of strings (e.g., ["JavaScript", "React", "Python", "Agile", "CSS"]).

Dynamically add skills: Populate the "Must-Have Skills" and "Nice-to-Have Skills" divs with the extracted keywords, rendering each as a clickable tag or pill.

Reveal the section: Make the "2. Define Screening Criteria" card visible.

Files changed (1) hide show
  1. index.html +155 -10
index.html CHANGED
@@ -66,26 +66,69 @@
66
  <div class="space-y-4">
67
  <div>
68
  <label class="block text-sm font-medium text-slate-700 mb-2">Job Title</label>
69
- <input type="text" class="w-full px-3 py-2 border border-slate-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" placeholder="e.g., Senior Software Engineer">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  </div>
71
  <div>
72
  <label class="block text-sm font-medium text-slate-700 mb-2">Job Description</label>
73
- <textarea class="w-full px-3 py-2 border border-slate-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 h-32" placeholder="Describe the role, responsibilities, and requirements..."></textarea>
 
 
 
 
 
74
  </div>
75
  </div>
76
  </div>
77
-
78
  <!-- Section 2: Define Screening Criteria -->
79
  <div id="screening-criteria" class="bg-white rounded-lg shadow-sm border border-slate-200 p-6 hidden">
80
  <h2 class="text-xl font-semibold text-slate-800 mb-4">2. Define Screening Criteria</h2>
81
- <div class="space-y-4">
82
- <div class="text-slate-500 italic">
83
- Screening criteria section will appear here after job details are entered.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  </div>
85
  </div>
86
  </div>
87
-
88
- <!-- Section 3: Set Education & Upload CVs -->
89
  <div class="bg-white rounded-lg shadow-sm border border-slate-200 p-6">
90
  <h2 class="text-xl font-semibold text-slate-800 mb-4">3. Set Education & Upload CVs</h2>
91
  <div class="space-y-4">
@@ -106,9 +149,111 @@
106
  </div>
107
  </div>
108
  </main>
109
-
110
  <script>
111
- // JavaScript will be added in subsequent steps
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  </script>
113
  </body>
114
  </html>
 
66
  <div class="space-y-4">
67
  <div>
68
  <label class="block text-sm font-medium text-slate-700 mb-2">Job Title</label>
69
+ <input type="text" id="job-title" class="w-full px-3 py-2 border border-slate-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" placeholder="e.g., Senior Software Engineer">
70
+ </div>
71
+ <div>
72
+ <label class="block text-sm font-medium text-slate-700 mb-2">Seniority Level</label>
73
+ <select id="seniority-level" class="w-full px-3 py-2 border border-slate-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
74
+ <option value="">Select seniority level</option>
75
+ <option value="internship">Internship</option>
76
+ <option value="junior">Junior</option>
77
+ <option value="mid-level">Mid-Level</option>
78
+ <option value="senior">Senior</option>
79
+ <option value="lead">Lead</option>
80
+ <option value="manager">Manager</option>
81
+ </select>
82
+ </div>
83
+ <div>
84
+ <label class="block text-sm font-medium text-slate-700 mb-2">Minimum Years of Experience</label>
85
+ <input type="number" id="min-experience" class="w-full px-3 py-2 border border-slate-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" placeholder="e.g., 5" min="0">
86
  </div>
87
  <div>
88
  <label class="block text-sm font-medium text-slate-700 mb-2">Job Description</label>
89
+ <textarea id="job-description" class="w-full px-3 py-2 border border-slate-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 h-32" placeholder="Describe the role, responsibilities, and requirements..."></textarea>
90
+ </div>
91
+ <div>
92
+ <button id="extract-skills-btn" class="bg-indigo-600 text-white px-6 py-2 rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition-colors">
93
+ Extract Key Skills & Responsibilities
94
+ </button>
95
  </div>
96
  </div>
97
  </div>
 
98
  <!-- Section 2: Define Screening Criteria -->
99
  <div id="screening-criteria" class="bg-white rounded-lg shadow-sm border border-slate-200 p-6 hidden">
100
  <h2 class="text-xl font-semibold text-slate-800 mb-4">2. Define Screening Criteria</h2>
101
+ <div class="space-y-6">
102
+ <!-- Must-Have Skills -->
103
+ <div>
104
+ <h3 class="text-lg font-medium text-slate-800 mb-3">Must-Have Skills</h3>
105
+ <div id="must-have-skills" class="flex flex-wrap gap-2 min-h-12 p-2 border border-slate-200 rounded-md">
106
+ <div class="text-slate-500 italic text-sm">Extracted skills will appear here</div>
107
+ </div>
108
+ </div>
109
+
110
+ <!-- Nice-to-Have Skills -->
111
+ <div>
112
+ <h3 class="text-lg font-medium text-slate-800 mb-3">Nice-to-Have Skills</h3>
113
+ <div id="nice-to-have-skills" class="flex flex-wrap gap-2 min-h-12 p-2 border border-slate-200 rounded-md">
114
+ <div class="text-slate-500 italic text-sm">Extracted skills will appear here</div>
115
+ </div>
116
+ </div>
117
+
118
+ <!-- Key Responsibilities & Phrases -->
119
+ <div>
120
+ <label class="block text-sm font-medium text-slate-700 mb-2">Key Responsibilities & Phrases</label>
121
+ <textarea id="key-responsibilities" class="w-full px-3 py-2 border border-slate-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 h-24" placeholder="Key responsibilities and phrases to look for..."></textarea>
122
+ </div>
123
+
124
+ <!-- Negative Keywords -->
125
+ <div>
126
+ <label class="block text-sm font-medium text-slate-700 mb-2">Negative Keywords</label>
127
+ <input type="text" id="negative-keywords" class="w-full px-3 py-2 border border-slate-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" placeholder="Keywords that would disqualify candidates...">
128
  </div>
129
  </div>
130
  </div>
131
+ <!-- Section 3: Set Education & Upload CVs -->
 
132
  <div class="bg-white rounded-lg shadow-sm border border-slate-200 p-6">
133
  <h2 class="text-xl font-semibold text-slate-800 mb-4">3. Set Education & Upload CVs</h2>
134
  <div class="space-y-4">
 
149
  </div>
150
  </div>
151
  </main>
 
152
  <script>
153
+ // Skill extraction function
154
+ function extractSkillsFromDescription(text) {
155
+ const commonSkills = [
156
+ 'JavaScript', 'React', 'Python', 'Java', 'HTML', 'CSS', 'Node.js', 'TypeScript',
157
+ 'SQL', 'MongoDB', 'Git', 'AWS', 'Docker', 'Agile', 'Scrum', 'REST', 'API',
158
+ 'Machine Learning', 'AI', 'Data Analysis', 'Project Management', 'Leadership',
159
+ 'Communication', 'Problem Solving', 'Teamwork', 'Testing', 'Debugging'
160
+ ];
161
+
162
+ const extracted = [];
163
+ const words = text.toLowerCase().split(/\W+/);
164
+
165
+ commonSkills.forEach(skill => {
166
+ if (words.includes(skill.toLowerCase()) || text.toLowerCase().includes(skill.toLowerCase())) {
167
+ extracted.push(skill);
168
+ }
169
+ });
170
+
171
+ // Add some random skills if not enough were found
172
+ if (extracted.length < 3) {
173
+ const additionalSkills = commonSkills.filter(skill => !extracted.includes(skill));
174
+ const randomSkills = additionalSkills.sort(() => 0.5 - Math.random()).slice(0, 3);
175
+ extracted.push(...randomSkills);
176
+ }
177
+
178
+ return extracted.slice(0, 8); // Limit to 8 skills
179
+ }
180
+
181
+ // Function to create skill tag element
182
+ function createSkillTag(skill) {
183
+ const tag = document.createElement('div');
184
+ tag.className = 'inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-indigo-100 text-indigo-800 cursor-pointer hover:bg-indigo-200 transition-colors';
185
+ tag.innerHTML = `
186
+ ${skill}
187
+ <span class="ml-2 text-indigo-600 hover:text-indigo-800">×</span>
188
+ `;
189
+
190
+ tag.addEventListener('click', function(e) {
191
+ if (e.target.tagName === 'SPAN') {
192
+ tag.remove();
193
+ }
194
+ });
195
+
196
+ return tag;
197
+ }
198
+
199
+ // Event listener for extract skills button
200
+ document.getElementById('extract-skills-btn').addEventListener('click', function() {
201
+ const jobDescription = document.getElementById('job-description').value;
202
+ const button = this;
203
+ const originalText = button.textContent;
204
+
205
+ if (!jobDescription.trim()) {
206
+ alert('Please enter a job description first.');
207
+ return;
208
+ }
209
+
210
+ // Show loading state
211
+ button.disabled = true;
212
+ button.textContent = 'Extracting skills...';
213
+ button.classList.add('opacity-50');
214
+
215
+ // Show loading indicator
216
+ const loadingText = document.createElement('div');
217
+ loadingText.className = 'text-sm text-slate-500 mt-2';
218
+ loadingText.textContent = 'Analyzing job description...';
219
+ button.parentNode.appendChild(loadingText);
220
+
221
+ // Simulate API call with timeout
222
+ setTimeout(() => {
223
+ // Hide loading indicator
224
+ loadingText.remove();
225
+
226
+ // Reset button
227
+ button.disabled = false;
228
+ button.textContent = originalText;
229
+ button.classList.remove('opacity-50');
230
+
231
+ // Extract skills
232
+ const skills = extractSkillsFromDescription(jobDescription);
233
+
234
+ // Clear existing skills
235
+ const mustHaveDiv = document.getElementById('must-have-skills');
236
+ const niceToHaveDiv = document.getElementById('nice-to-have-skills');
237
+
238
+ mustHaveDiv.innerHTML = '';
239
+ niceToHaveDiv.innerHTML = '';
240
+
241
+ // Split skills between must-have and nice-to-have
242
+ const mustHaveCount = Math.min(Math.ceil(skills.length * 0.6), 5); // 60% as must-have, max 5
243
+
244
+ skills.forEach((skill, index) => {
245
+ const tag = createSkillTag(skill);
246
+ if (index < mustHaveCount) {
247
+ mustHaveDiv.appendChild(tag);
248
+ } else {
249
+ niceToHaveDiv.appendChild(tag);
250
+ }
251
+ });
252
+
253
+ // Show the screening criteria section
254
+ document.getElementById('screening-criteria').classList.remove('hidden');
255
+ }, 1000);
256
+ });
257
  </script>
258
  </body>
259
  </html>