Filter for positions, survey to check compatibility
Tue, Mar 7, 2023
Motivation
Believe it or not, due to the high demand for developers of all kinds in the market by companies, many recruiters and headhunters have become copy paste machines. I don't know the number or the daily amount of messages they send to all the profiles in their network that match the new position they have available, but I would bet they are not few. And it's not that I don't like them sending me messages, but I would like them to send me messages that really interest me and make me think that they have seen my profile, my code or some of my work and that they really want to hire me for my skills.
This is not usually the case, many people use programs to automate the process of searching for profiles such as Hiretual or Jobvite, they send messages to all users "that match" and sometimes this does not work very well. Since your profile clearly says Frontend Developer, your experience says the same... but, they have a Java position with awesome microservices for you.
Other times they screw up and send you a message with the name of your teammate:
The idea
How many times have you had a call with questions like:
- Why are you looking for a change?
- Do you know the SOLID principles?
- How many years would you say you've been working with React ? How about Typescript ?
- Do you know what continuous integration is?
To be offered a lower salary than you have, or to be asked for your CV and never be told anything again.
How many times bro ?
The idea is to screen you before you get screened.
Solution
10 simple questions about points that you consider important, requirements, values... or basically whatever you want and if they are fulfilled, the recruiter will get contact information to be able to go into detail about the whole process.
It's a win win, we both save time, don't we?
Code
With a container or page component, a couple of buttons, radiobuttons and an array of objects you have more than enough, in my case:
I have my page:
import Dialog from '@/components/Dialog';
import styles from '@/styles/survey.module.css';
import ControlButtons from '@/components/ControlButtons';
import Confetti from 'react-confetti';
import SEO from '@/components/SEO';
import useWindowResize from '@/hooks/useWidowResize';
import useSurvey from '@/hooks/useSurvey';
import NavigationArrows from '@/components/NavigationArrows';
const { width, height } = useWindowResize();
<Confetti width={width} height={height} numberOfPieces={100} run={surveySuccess} />
title: 'Find out if I match the position in 1 minute',
description: 'Click to continue',
<div className={styles.header}>
{currentQuestionNum > 0 && currentQuestionNum < 11 && (
{currentQuestionNum} / {totalQuestions - 2}
// TODO: Move to a component
<div className={styles.container}>
(question: any, index: number) =>
currentQuestionNum === index && (
<div key={index} className={styles.question}>
dangerouslySetInnerHTML={{ __html: question.questionHtml }}
className={styles.questionHtml}
{question.answerOptions?.map((answerOption: any) => (
<label htmlFor={answerOption.answerText} key={answerOption.answerText}>
handleAnswerOptionClick({
question: question.questionText,
isCorrect: answerOption.isCorrect,
id={answerOption.answerText}
value={answerOption.answerText}
checked={answers[index]?.answer === answerOption.answerText}
{answerOption.answerText}
<div className={styles.buttons}>
hidden={currentQuestionNum < 1 || currentQuestionNum > 10}
disabledLeft={currentQuestionNum < 2}
disabledRight={questionsDoneNum < currentQuestionNum}
onClickLeft={handlePreviousQuestion}
onClickRight={handleNextQuestion}
My hook with logic
import { useRouter } from 'next/router';
import { useReducer, useEffect, useRef } from 'react';
const reducer = (state: any, action: any) => {
...ya sabes como funciona un switch no?
const useSurvey = () => {
const { query } = useRouter();
const { name = '👋' } = query;
const emailRef = useRef<boolean>(false);
const [state, dispatch] = useReducer(reducer, initialState);
questionText: 'Which came first, the chicken or the egg?
questionHtml: `<h2>Which came first the chicken or the egg?</h2>`,
answerOptions: [{ answerText: 'Egg', isCorrect: true, }, { answerText: 'Chicken', isCorrect: false }],
if (state.currentQuestion === questions.length - 1 && !emailRef.current) {
await fetch('/api/email', {
'Content-Type': 'application/json',
subject: `Job survey from ${name} - ${new Date().toLocaleString()}`,
<code> ${navigator.userAgent} </code>
`<li> ${answer.question} : ${answer.answer} - ${
answer.isCorrect ? '✅' : '🚫'
}, [state, name, questions.length]);
const handlePreviousQuestion = () => {
if (state.currentQuestion > 1) dispatch({ type: 'PREVIOUS_QUESTION' });
const handleNextQuestion = () => {
if (state.currentQuestion != 0 && state.questionsDone >= state.currentQuestion)
dispatch({ type: 'NEXT_QUESTION' });
const handleAnswerOptionClick = (payload: {
}) => dispatch({ type: 'ADD_ANSWER', payload });
surveySuccess: state.success,
currentQuestionNum: state.currentQuestion,
questionsDoneNum: state.questionsDone,
totalQuestions: questions.length,
export default useSurvey;
My endpoint
import type { NextApiRequest, NextApiResponse } from 'next';
import nodemailer from 'nodemailer';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
const transporter = nodemailer.createTransport({
service: process.env.EMAIL_HOST,
pass: process.env.EMAIL_PASSWORD,
const { subject, message } = req.body;
await transporter.sendMail(mailOptions);
res.status(200).json({ success: true });
res.status(500).json({ success: error });
Result
Try it yourself: Link to result