PageSourceSearch

https://rabotavsushisell.ru/quiz.js?v=49

js rabotavsushisell.ru collected 2026-10-07 18:09:26 UTC 6,864 bytes, 115 lines download raw bytes

1/* Квиз «Какая работа тебе подходит»: 3 вопроса → вакансия из data.js.
2   Вопросы и баллы правятся здесь. Баллы — какой вакансии сколько добавляет ответ (id как в SITE.vacancies) */
3(function () {
4  const QUESTIONS = [
5    {
6      q: 'Что тебе ближе?',
7      a: [
8        { t: 'Готовить руками', img: 'assets/img/cook.webp', s: { cook: 3, kitchen: 1 } },
9        { t: 'Быть в движении', img: 'assets/img/courier.svg', s: { courier: 3 } },
10        { t: 'Общаться с людьми', img: 'assets/img/cashier.webp', s: { cashier: 2, admin: 2 } },
11        { t: 'Порядок и внимательность', img: 'assets/img/picker.webp', s: { picker: 3, kitchen: 2 } }
12      ]
13    },
14    {
15      q: 'Как хочешь работать?',
16      a: [
17        { t: 'Полные смены, чтобы больше заработать', s: { cook: 1, courier: 2, admin: 1 } },
18        { t: 'Вечером или вместе с учёбой', s: { cashier: 2, courier: 1, picker: 1 } },
19        { t: 'Спокойно, без суеты', s: { kitchen: 2, picker: 1 } },
20        { t: 'Держать всю смену под контролем', s: { admin: 3 } }
21      ]
22    },
23    {
24      q: 'Что для тебя главное?',
25      a: [
26        { t: 'Деньги сразу', s: { courier: 2, cook: 1 } },
27        { t: 'Научиться с нуля', s: { cook: 2, picker: 1, kitchen: 1 } },
28        { t: 'Вырасти до управляющего', s: { admin: 2, cook: 1 } },
29        { t: 'Команда и атмосфера', s: { cashier: 1, kitchen: 1, picker: 1, admin: 1 } }
30      ]
31    }
32  ];
33
34  // Почему подходит + история роста для примера (slug из stories.js)
35  const WHY = {
36    cook: ['Ты любишь делать руками и видеть результат. Научим с нуля, а через полгода можно вырасти до шефа', 'ivan-rakov'],
37    courier: ['Тебе важны движение и свобода. Сам выбираешь смены и маршрут, чаевые каждый день', 'aleksandr-lavrinovich'],
38    admin: ['Ты умеешь держать всё под контролем и ладить с людьми. Отсюда прямой путь в управляющие', 'aleksandr-danilin'],
39    cashier: ['Ты легко общаешься с людьми. Вечерние смены удобно совмещать с учёбой', ''],
40    picker: ['Ты внимательный и любишь порядок. Спокойная работа, график выбираешь сам', ''],
41    kitchen: ['Тебе нравится, когда всё чисто и по местам. Можно без опыта и с быстрым выходом на смену', '']
42  };
43  const ORDER = ['cook', 'courier', 'admin', 'cashier', 'picker', 'kitchen']; // при равных баллах
44
45  const root = document.querySelector('[data-quiz]');
46  if (!root || !window.SITE) return;
47  const esc = (s) => String(s).replace(/[&<>"]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]));
48  let step = 0, score = {};
49
50  function progress() {
51    return `<div class="quiz__progress" aria-hidden="true">${QUESTIONS.map((_, i) => `<i class="${i <= step ? 'is-on' : ''}"></i>`).join('')}</div>`;
52  }
53
54  function drawQuestion(dir) {
55    const Q = QUESTIONS[step];
56    const withImg = Q.a.some((x) => x.img);
57    root.innerHTML = `<div class="quiz__step ${dir ? 'is-in' : ''}">
58      <div class="quiz__top">${progress()}<span class="quiz__count">${step + 1} из ${QUESTIONS.length}</span></div>
59      <h3 class="h3 quiz__q">${esc(Q.q)}</h3>
60      <div class="quiz__opts ${withImg ? 'quiz__opts--img' : ''}">
61        ${Q.a.map((a, i) => `<button type="button" class="quiz__opt quiz__opt--${i}" data-i="${i}">
62          ${a.img ? `<span class="quiz__img"><img src="${esc(a.img)}" alt="" loading="lazy"></span>` : ''}
63          <span class="quiz__t">${esc(a.t)}</span></button>`).join('')}
64      </div>
65      ${step ? '<button type="button" class="quiz__back">← Назад</button>' : ''}
66    </div>`;
67  }
68
69  function drawResult() {
70    if (window.trackGoal) trackGoal('quiz_done');
71    const best = ORDER.slice().sort((a, b) => (score[b] || 0) - (score[a] || 0) || ORDER.indexOf(a) - ORDER.indexOf(b));
72    const v = SITE.vacancies.find((x) => x.id === best[0]);
73    const alt = SITE.vacancies.find((x) => x.id === best[1]);
74    const [why, storySlug] = WHY[v.id];
75    const story = storySlug && (window.STORIES || []).find((s) => s.slug === storySlug);
76    root.innerHTML = `<div class="quiz__step is-in quiz__result quiz__result--${esc(v.color)}">
77      <div class="quiz__res-img"><img src="${esc(v.img)}" alt="${esc(v.title)}"></div>
78      <div class="quiz__res-body">
79        <span class="quiz__count">Тебе подойдёт</span>
80        <h3 class="h2 quiz__res-title">${esc(v.title)}</h3>
81        <p class="quiz__why">${esc(why)}</p>
82        <p class="quiz__salary">${esc(v.salary)}${v.noNote ? '' : '<sup>*</sup>'}</p>
83        <ul class="perks">${v.perks.slice(0, 3).map((p) => `<li>${esc(p)}</li>`).join('')}</ul>
84        <div class="quiz__actions">
85          <a href="#apply" class="btn btn--dark" data-apply="${esc(v.title)}">Откликнуться</a>
86          <button type="button" class="btn quiz__again">Пройти ещё раз</button>
87        </div>
88        ${story ? `<a class="quiz__story" href="stories.html#${esc(story.slug)}"><img src="${esc(story.face)}" alt=""><span>${esc(story.name.split(' ')[0])} тоже начинал так: <b>${esc(story.from)} → ${esc(story.to)}</b></span></a>` : ''}
89        ${v.noNote ? '' : `<p class="quiz__note">* ${esc(SITE.salaryNote)}</p>`}
90        ${alt ? `<p class="quiz__alt">Ещё присмотрись: <a href="#vacancies">${esc(alt.title)}</a></p>` : ''}
91      </div>
92    </div>`;
93  }
94
95  root.addEventListener('click', (e) => {
96    const opt = e.target.closest('.quiz__opt');
97    if (opt) {
98      const a = QUESTIONS[step].a[+opt.dataset.i];
99      opt.classList.add('is-picked');
100      Object.entries(a.s).forEach(([k, n]) => { score[k] = (score[k] || 0) + n; });
101      (root._hist = root._hist || []).push(a.s);
102      setTimeout(() => { step++; step < QUESTIONS.length ? drawQuestion(1) : drawResult(); }, 220);
103      return;
104    }
105    if (e.target.closest('.quiz__back')) {
106      const s = root._hist.pop();
107      Object.entries(s).forEach(([k, n]) => { score[k] -= n; });
108      step--; drawQuestion(1);
109      return;
110    }
111    if (e.target.closest('.quiz__again')) { step = 0; score = {}; root._hist = []; drawQuestion(1); }
112  });
113
114  drawQuestion(0);
115})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.