|
import { useContext, useState } from 'react'; |
|
import styles from './hrTool.module.css'; |
|
import HrContext from '../../context/hrToolContext/HrContext'; |
|
|
|
function HrTool({ skills, personName }) { |
|
const [matchedSkills, setMatchedSkills] = useState([]); |
|
const [requirements, setRequirements] = useState(""); |
|
const { saveRequirements, requirementsFilter } = useContext(HrContext); |
|
|
|
// Function to calculate Levenshtein distance between two strings |
|
const levenshteinDistance = (skill, word) => { |
|
const skillChars = skill.length; |
|
const wordChars = word.length; |
|
const dp = new Array(skillChars + 1).fill(null).map(() => new Array(wordChars + 1).fill(0)); |
|
|
|
for (let i = 0; i <= skillChars; i++) dp[i][0] = i; |
|
for (let j = 0; j <= wordChars; j++) dp[0][j] = j; |
|
|
|
for (let i = 1; i <= skillChars; i++) { |
|
for (let j = 1; j <= wordChars; j++) { |
|
const cost = skill[i - 1] === word[j - 1] ? 0 : 1; |
|
dp[i][j] = Math.min( |
|
dp[i - 1][j] + 1, |
|
dp[i][j - 1] + 1, |
|
dp[i - 1][j - 1] + cost |
|
); |
|
} |
|
} |
|
|
|
return dp[skillChars][wordChars]; |
|
} |
|
|
|
// Function to check if a skill is similar to a keyword |
|
const isSimilar = (skill, keyword, maxDistance) => { |
|
return levenshteinDistance(skill, keyword) <= maxDistance; |
|
} |
|
|
|
// Function to search for skills in a given input string |
|
const findSkills = (input, skills, maxDistance) => { |
|
const inputWords = input.split(/\s+/); |
|
const matchingSkills = []; |
|
|
|
for (const skill of skills) { |
|
for (const inputWord of inputWords) { |
|
if (isSimilar(inputWord.toLowerCase(), skill.toLowerCase(), maxDistance)) { |
|
matchingSkills.push(skill); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
return matchingSkills; |
|
} |
|
|
|
const handleChange = (event) => { |
|
setRequirements(event.target.value); |
|
setMatchedSkills(findSkills(event.target.value, skills, 2)); |
|
} |
|
|
|
return ( |
|
<section className={styles.section}> |
|
<h3>Tem alguma descrição de projeto ou vaga?<br />Coloque-a abaixo e veja o quanto meu perfil bate com os requisitos!</h3> |
|
<section className={styles.analysis_section}> |
|
<section className={styles.input_area}> |
|
<textarea |
|
placeholder={`Exemplo:\n\nEstamos em busca de um desenvolvedor front-end habilidoso e criativo, com experiência em HTML, CSS, JavaScript, React, e responsividade.\n\nVocê será responsável por traduzir designs em interfaces interativas e otimizar o desempenho do usuário.\n\nTrabalhe conosco para criar experiências web inovadoras e cativantes. Se você é um entusiasta de tecnologia e está pronto para se destacar no desenvolvimento front-end, inscreva-se agora!`} |
|
value={requirements} |
|
onChange={(event) => handleChange(event)} |
|
className={styles.blink} |
|
/> |
|
<label id="checkbox" className={styles.notification}> |
|
<input id="checkbox" type="checkbox" /> |
|
{`Notificar ${personName} dos requisitos`} |
|
</label> |
|
</section> |
|
<section className={styles.results}> |
|
<h3>Habilidades identificadas que possuo</h3> |
|
{ |
|
matchedSkills.length > 0 && ( |
|
<> |
|
<ul> |
|
{ matchedSkills.map((skill) => <li key={ skill }>{ skill }</li>) } |
|
</ul> |
|
<button onClick={() => saveRequirements(matchedSkills)}> |
|
Destacar no portfólio habilidades identificadas |
|
</button> |
|
{ |
|
requirementsFilter.length > 0 && ( |
|
<p className={`animate__animated animate__fadeInDown ${styles.requirements_saved_message}`}> |
|
As próximas seções do portfólio (Projetos e Tecnologias) foram destacadas de acordo com os requisitos! |
|
</p> |
|
) |
|
} |
|
</> |
|
) |
|
} |
|
</section> |
|
</section> |
|
</section> |
|
); |
|
} |
|
|
|
export default HrTool; |