680 lines
29 KiB
Vue
680 lines
29 KiB
Vue
<template>
|
||
<div data-theme="acid" class="min-h-screen">
|
||
<NuxtRouteAnnouncer />
|
||
<aside
|
||
class="glass-card fixed left-4 top-4 z-20 flex h-[calc(100vh-2rem)] w-[320px] flex-col rounded-3xl p-5"
|
||
>
|
||
<div class="mb-4 flex items-center justify-between">
|
||
<div>
|
||
<h2 class="font-display text-lg font-semibold">Навигатор вакансии</h2>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="glass-pane mb-4 rounded-2xl p-4">
|
||
<div class="flex items-center gap-3">
|
||
<div class="avatar">
|
||
<div class="w-12 rounded-full bg-gradient-to-br from-fuchsia-400 via-violet-400 to-cyan-400 p-[2px]">
|
||
<div class="flex h-full w-full items-center justify-center rounded-full bg-base-100">
|
||
<span class="text-lg">🤖</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<p class="text-sm font-semibold">Хантик</p>
|
||
<p class="text-xs text-slate-400">AI-ассистент вакансии</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flex-1 space-y-4 overflow-auto pr-1">
|
||
<div
|
||
v-for="message in chatHistory"
|
||
:key="message.id"
|
||
class="chat"
|
||
:class="message.from === 'ai' ? 'chat-start' : 'chat-end'"
|
||
>
|
||
<div v-if="message.from === 'ai'" class="chat-image avatar">
|
||
<div class="w-8 rounded-full bg-slate-800">
|
||
<span class="flex h-full items-center justify-center text-xs">AI</span>
|
||
</div>
|
||
</div>
|
||
<div
|
||
class="chat-bubble text-sm"
|
||
:class="message.from === 'ai' ? 'glass-pane' : 'bg-sky-500/20'"
|
||
@click="message.step !== undefined && (currentStep = message.step)"
|
||
>
|
||
{{ message.text }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mt-5">
|
||
<label class="input input-bordered glass-pane flex items-center gap-2 rounded-xl">
|
||
<span class="text-xs text-slate-400">Вы:</span>
|
||
<input class="grow text-base" placeholder="Напишите уточнение" />
|
||
<button class="btn btn-primary btn-lg">Отправить</button>
|
||
</label>
|
||
</div>
|
||
</aside>
|
||
|
||
<main
|
||
class="min-h-screen w-full px-4 py-6 md:px-8 lg:pl-[360px]"
|
||
>
|
||
<section class="glass-card flex min-h-[calc(100vh-3rem)] flex-col gap-6 rounded-3xl p-6">
|
||
<div class="flex flex-wrap items-center justify-between gap-4">
|
||
<div>
|
||
<h1 class="section-title">{{ steps[currentStep].title }}</h1>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-if="currentStep === 0" class="grid gap-4">
|
||
<div class="glass-pane rounded-2xl p-5">
|
||
<div class="flex flex-wrap items-center justify-between gap-3">
|
||
<div>
|
||
<h3 class="font-display text-lg font-semibold">Должностная инструкция</h3>
|
||
</div>
|
||
<button class="btn btn-lg btn-ghost">Пройти голосовое интервью</button>
|
||
</div>
|
||
<div class="mt-5 space-y-4">
|
||
<label class="form-control">
|
||
<span class="label-text text-xs uppercase tracking-[0.2em] text-slate-400">Роль</span>
|
||
<input class="input input-bordered glass-pane" value="Head of Growth" />
|
||
</label>
|
||
|
||
<div class="glass-card rounded-2xl p-4">
|
||
<div class="flex flex-wrap items-center justify-between gap-3">
|
||
<div>
|
||
<p class="text-xs uppercase tracking-[0.2em] text-slate-400">Голосовое интервью</p>
|
||
</div>
|
||
</div>
|
||
<div class="mt-4 rounded-2xl border border-sky-300/30 bg-gradient-to-br from-slate-900/70 via-slate-800/40 to-slate-900/80 p-4">
|
||
<div class="flex items-center justify-between">
|
||
<div class="space-y-1">
|
||
<p class="text-sm font-semibold">Сессия интервью</p>
|
||
</div>
|
||
<span class="text-xs text-slate-400">00:00</span>
|
||
</div>
|
||
<div class="mt-4 grid gap-2">
|
||
<div class="h-2 w-full overflow-hidden rounded-full bg-slate-800/80">
|
||
<div class="h-full w-2/5 rounded-full bg-gradient-to-r from-sky-400 to-cyan-300"></div>
|
||
</div>
|
||
</div>
|
||
<div class="mt-4 flex items-center justify-center">
|
||
<button class="btn btn-ghost btn-circle btn-lg">▶</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="glass-pane rounded-2xl p-5">
|
||
<div class="mt-4 space-y-4">
|
||
<div>
|
||
<p class="text-sm font-semibold">Общее описание</p>
|
||
<p class="text-sm text-slate-300">
|
||
Роль отвечает за системный рост продуктовой воронки от активации до удержания. Основной фокус —
|
||
масштабируемые эксперименты, которые увеличивают выручку и улучшают ключевые метрики продукта.
|
||
</p>
|
||
</div>
|
||
<div>
|
||
<p class="text-sm font-semibold">Основные цели</p>
|
||
<ul class="mt-2 list-disc space-y-1 pl-5 text-sm text-slate-300">
|
||
<li>Запускать 3–5 гипотез в месяц и доводить их до измеримых результатов.</li>
|
||
<li>Синхронизировать маркетинг, продукт и продажи вокруг единого North Star.</li>
|
||
<li>Настроить аналитическую систему, которая показывает, где теряем пользователей.</li>
|
||
</ul>
|
||
</div>
|
||
<div>
|
||
<p class="text-sm font-semibold">Пример рабочего дня</p>
|
||
<p class="text-sm text-slate-300">
|
||
Утро — разбор когорт и планирование экспериментов с продактом. Днем — созвоны с командами
|
||
маркетинга и аналитики, согласование приоритетов. Вечером — подготовка отчета по результатам
|
||
спринта и формирование гипотез на следующую неделю.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-else-if="currentStep === 1" class="grid gap-4">
|
||
<div class="glass-pane rounded-2xl p-5">
|
||
<h3 class="font-display text-lg font-semibold">Видео по сценарию</h3>
|
||
<ol class="mt-4 list-decimal space-y-2 pl-5 text-sm text-slate-300">
|
||
<li>Контекст продукта и стадии роста.</li>
|
||
<li>Что значит успех для роли в первые 90 дней.</li>
|
||
<li>Как выглядит идеальное взаимодействие в команде.</li>
|
||
</ol>
|
||
<div class="mt-5 rounded-2xl border border-dashed border-white/20 p-6 text-center">
|
||
<p class="text-sm text-slate-300">Перетащите видео (до 3 минут) или загрузите вручную</p>
|
||
<button class="btn btn-lg btn-ghost mt-3">Загрузить видео</button>
|
||
</div>
|
||
<div class="mt-6">
|
||
<h4 class="text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Видео команды</h4>
|
||
<div class="mt-4 grid gap-3 sm:grid-cols-2 xl:grid-cols-3">
|
||
<div class="glass-card rounded-2xl p-4">
|
||
<div class="flex items-start justify-between">
|
||
<div>
|
||
<p class="text-sm font-semibold">Аня · Product</p>
|
||
<p class="text-xs text-slate-400">1:12 · Вовлеченность</p>
|
||
</div>
|
||
<span class="badge badge-outline">Готово</span>
|
||
</div>
|
||
<div class="mt-3 h-24 rounded-xl bg-gradient-to-br from-slate-800/60 to-slate-900/80"></div>
|
||
</div>
|
||
<div class="glass-card rounded-2xl p-4">
|
||
<div class="flex items-start justify-between">
|
||
<div>
|
||
<p class="text-sm font-semibold">Сергей · Growth</p>
|
||
<p class="text-xs text-slate-400">1:48 · Фокус</p>
|
||
</div>
|
||
<span class="badge badge-outline">Готово</span>
|
||
</div>
|
||
<div class="mt-3 h-24 rounded-xl bg-gradient-to-br from-slate-800/60 to-slate-900/80"></div>
|
||
</div>
|
||
<div class="glass-card rounded-2xl p-4">
|
||
<div class="flex items-start justify-between">
|
||
<div>
|
||
<p class="text-sm font-semibold">Кира · Ops</p>
|
||
<p class="text-xs text-slate-400">0:56 · Структура</p>
|
||
</div>
|
||
<span class="badge badge-outline">Готово</span>
|
||
</div>
|
||
<div class="mt-3 h-24 rounded-xl bg-gradient-to-br from-slate-800/60 to-slate-900/80"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-else-if="currentStep === 2" class="grid gap-4">
|
||
<div class="glass-pane rounded-2xl p-5">
|
||
<div class="flex items-center justify-between">
|
||
<h3 class="font-display text-lg font-semibold">Анализ видео</h3>
|
||
</div>
|
||
<div class="mt-4 flex flex-wrap items-center gap-4">
|
||
<span class="loading loading-spinner loading-lg text-info"></span>
|
||
<progress class="progress progress-info w-48" value="72" max="100"></progress>
|
||
</div>
|
||
</div>
|
||
<div class="glass-pane rounded-2xl p-5">
|
||
<h3 class="font-display text-lg font-semibold">Карточка коллектива</h3>
|
||
<div class="mt-4 grid gap-4 md:grid-cols-[1.1fr_0.9fr]">
|
||
<div class="space-y-3">
|
||
<div class="flex items-center justify-between">
|
||
<span class="text-sm">Тональность</span>
|
||
<div class="badge badge-outline">Дружелюбная + прямолинейная</div>
|
||
</div>
|
||
<div class="flex items-center justify-between">
|
||
<span class="text-sm">Частота синков</span>
|
||
<div class="badge badge-outline">2-3 раза в неделю</div>
|
||
</div>
|
||
<div class="flex items-center justify-between">
|
||
<span class="text-sm">Решения</span>
|
||
<div class="badge badge-outline">Через эксперименты</div>
|
||
</div>
|
||
</div>
|
||
<div class="glass-card rounded-2xl p-4">
|
||
<p class="text-xs uppercase tracking-[0.2em] text-slate-400">Группа</p>
|
||
<p class="mt-2 text-lg font-semibold">Growth Core</p>
|
||
<p class="text-xs text-slate-400">4 участника · Ритм 2-3 синка</p>
|
||
<div class="mt-3 flex flex-wrap gap-2">
|
||
<span class="badge badge-outline">Темп</span>
|
||
<span class="badge badge-outline">Эксперименты</span>
|
||
<span class="badge badge-outline">Прямота</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-else-if="currentStep === 3" class="space-y-4">
|
||
<div class="glass-pane rounded-2xl p-5">
|
||
<div class="flex flex-wrap items-center justify-between gap-3">
|
||
<div>
|
||
<h3 class="font-display text-lg font-semibold">Рекомендации кандидатов</h3>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="glass-pane rounded-2xl p-5">
|
||
<div class="flex flex-wrap items-center justify-between gap-3">
|
||
<div>
|
||
<h3 class="font-display text-lg font-semibold">Методология совпадений</h3>
|
||
</div>
|
||
<div class="tabs tabs-boxed bg-transparent">
|
||
<a
|
||
v-for="method in methodologies"
|
||
:key="method.id"
|
||
class="tab"
|
||
:class="currentMethodology === method.id ? 'tab-active' : ''"
|
||
@click="currentMethodology = method.id"
|
||
>
|
||
{{ method.label }}
|
||
</a>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mt-5 grid gap-4 md:grid-cols-2 xl:grid-cols-3">
|
||
<div
|
||
v-for="candidate in currentCandidates"
|
||
:key="candidate.id"
|
||
class="glass-card rounded-2xl p-4"
|
||
>
|
||
<div class="flex items-start justify-between">
|
||
<div>
|
||
<h4 class="font-display text-lg font-semibold">{{ candidate.name }}</h4>
|
||
<p class="text-sm text-slate-300">{{ candidate.role }}</p>
|
||
<p class="text-xs text-slate-400">{{ candidate.location }}</p>
|
||
</div>
|
||
<div class="radial-progress text-sky-300" :style="`--value:${candidate.match}; --size:3.2rem;`">
|
||
<span class="text-xs text-slate-100">{{ candidate.match }}%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mt-4 grid grid-cols-[90px_1fr] gap-3">
|
||
<svg viewBox="0 0 100 100" class="h-24 w-24">
|
||
<circle cx="50" cy="50" r="38" fill="none" stroke="rgba(148, 163, 184, 0.2)" />
|
||
<circle cx="50" cy="50" r="24" fill="none" stroke="rgba(148, 163, 184, 0.2)" />
|
||
<circle cx="50" cy="50" r="10" fill="none" stroke="rgba(148, 163, 184, 0.2)" />
|
||
<g v-for="(axis, index) in radarAxes" :key="axis">
|
||
<line
|
||
:x1="50"
|
||
:y1="50"
|
||
:x2="axisPoints[index].x"
|
||
:y2="axisPoints[index].y"
|
||
stroke="rgba(148, 163, 184, 0.25)"
|
||
/>
|
||
</g>
|
||
<polygon
|
||
:points="radarPoints(candidate.values)"
|
||
fill="rgba(125, 211, 252, 0.35)"
|
||
stroke="rgba(125, 211, 252, 0.9)"
|
||
stroke-width="1.5"
|
||
/>
|
||
</svg>
|
||
<div class="space-y-2">
|
||
<div class="flex flex-wrap gap-2">
|
||
<span v-for="tag in candidate.tags" :key="tag" class="badge badge-outline">
|
||
{{ tag }}
|
||
</span>
|
||
</div>
|
||
<p class="text-xs text-slate-400">Сильнее всего: {{ candidate.highlight }}</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mt-4 flex items-center justify-between">
|
||
<div class="flex gap-2">
|
||
<button class="btn btn-lg btn-ghost">Профиль</button>
|
||
<button class="btn btn-lg btn-ghost">Сравнить</button>
|
||
</div>
|
||
<button class="btn btn-lg btn-ghost">Запросить интро</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div v-else class="space-y-4">
|
||
<div class="glass-pane rounded-2xl p-5">
|
||
<div class="flex flex-wrap items-center justify-between gap-3">
|
||
<div>
|
||
<h3 class="font-display text-lg font-semibold">Мэтчи и диалоги</h3>
|
||
</div>
|
||
<button class="btn btn-lg btn-ghost">Сгенерировать ссылку для встреч</button>
|
||
</div>
|
||
<div class="mt-5 space-y-3">
|
||
<div class="glass-card rounded-2xl p-4">
|
||
<div class="flex items-center justify-between gap-4">
|
||
<div class="flex items-center gap-3">
|
||
<div class="avatar">
|
||
<div class="w-10 rounded-full bg-slate-800">
|
||
<span class="flex h-full items-center justify-center text-xs">ИС</span>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<p class="text-sm font-semibold">Ирина Соколова · Head of Growth</p>
|
||
<p class="text-xs text-slate-400">Последнее: «Готова к короткому созвону» · 2ч назад</p>
|
||
</div>
|
||
</div>
|
||
<span class="badge badge-success badge-outline">Match 91%</span>
|
||
</div>
|
||
<div class="mt-3 flex flex-wrap gap-2">
|
||
<button class="btn btn-lg btn-ghost">Открыть диалог</button>
|
||
<button class="btn btn-lg btn-ghost">Назначить встречу</button>
|
||
<button class="btn btn-lg btn-ghost">Предложить слоты</button>
|
||
</div>
|
||
</div>
|
||
<div class="glass-card rounded-2xl p-4">
|
||
<div class="flex items-center justify-between gap-4">
|
||
<div class="flex items-center gap-3">
|
||
<div class="avatar">
|
||
<div class="w-10 rounded-full bg-slate-800">
|
||
<span class="flex h-full items-center justify-center text-xs">КД</span>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<p class="text-sm font-semibold">Кира Дуброва · Product Growth</p>
|
||
<p class="text-xs text-slate-400">Последнее: «Вижу слоты на четверг» · 5ч назад</p>
|
||
</div>
|
||
</div>
|
||
<span class="badge badge-success badge-outline">Match 92%</span>
|
||
</div>
|
||
<div class="mt-3 flex flex-wrap gap-2">
|
||
<button class="btn btn-lg btn-ghost">Открыть диалог</button>
|
||
<button class="btn btn-lg btn-ghost">Назначить встречу</button>
|
||
<button class="btn btn-lg btn-ghost">Предложить слоты</button>
|
||
</div>
|
||
</div>
|
||
<div class="glass-card rounded-2xl p-4">
|
||
<div class="flex items-center justify-between gap-4">
|
||
<div class="flex items-center gap-3">
|
||
<div class="avatar">
|
||
<div class="w-10 rounded-full bg-slate-800">
|
||
<span class="flex h-full items-center justify-center text-xs">АМ</span>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<p class="text-sm font-semibold">Алексей Марков · Growth Manager</p>
|
||
<p class="text-xs text-slate-400">Последнее: «Можно быстро согласовать календарь» · 1д назад</p>
|
||
</div>
|
||
</div>
|
||
<span class="badge badge-success badge-outline">Match 88%</span>
|
||
</div>
|
||
<div class="mt-3 flex flex-wrap gap-2">
|
||
<button class="btn btn-lg btn-ghost">Открыть диалог</button>
|
||
<button class="btn btn-lg btn-ghost">Назначить встречу</button>
|
||
<button class="btn btn-lg btn-ghost">Предложить слоты</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="mt-auto flex justify-end">
|
||
<button class="btn btn-primary btn-lg" @click="nextStep">
|
||
Далее
|
||
</button>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { computed, ref } from 'vue'
|
||
|
||
const steps = [
|
||
{
|
||
id: 'requirements',
|
||
title: 'Функциональные требования к вакансии',
|
||
},
|
||
{
|
||
id: 'video',
|
||
title: 'Видео по сценарию',
|
||
},
|
||
{
|
||
id: 'fingerprint',
|
||
title: 'AI-отпечаток коллектива',
|
||
},
|
||
{
|
||
id: 'recommendations',
|
||
title: 'Рекомендации кандидатов',
|
||
},
|
||
{
|
||
id: 'matches',
|
||
title: 'Мэтчи и чат',
|
||
}
|
||
]
|
||
|
||
const currentStep = ref(0)
|
||
const chatHistory = computed(() => chatByStep.slice(0, currentStep.value + 1).flat())
|
||
const nextStep = () => {
|
||
currentStep.value = Math.min(currentStep.value + 1, steps.length - 1)
|
||
}
|
||
|
||
const methodologies = [
|
||
{ id: 'coaching', label: 'Бизнес-коучинг' },
|
||
{ id: 'therapy', label: 'Психотерапия' },
|
||
{ id: 'product', label: 'Продуктовый мэтч' }
|
||
]
|
||
|
||
const candidatesByMethodology = {
|
||
coaching: [
|
||
{
|
||
id: 1,
|
||
name: 'Ирина Соколова',
|
||
role: 'Growth Lead · B2B SaaS',
|
||
location: 'Берлин / Remote',
|
||
match: 91,
|
||
values: [88, 62, 79, 71, 66],
|
||
tags: ['Experimentation', 'B2B', 'Lifecycle'],
|
||
highlight: 'темп запуска'
|
||
},
|
||
{
|
||
id: 2,
|
||
name: 'Максим Орлов',
|
||
role: 'Head of Growth',
|
||
location: 'Лондон / Remote',
|
||
match: 87,
|
||
values: [76, 58, 82, 68, 73],
|
||
tags: ['SQL', 'Funnels', 'Team Lead'],
|
||
highlight: 'структура'
|
||
},
|
||
{
|
||
id: 3,
|
||
name: 'Лия Вернер',
|
||
role: 'Revenue Strategist',
|
||
location: 'Амстердам',
|
||
match: 85,
|
||
values: [72, 74, 65, 70, 81],
|
||
tags: ['PLG', 'Retention', 'Ops'],
|
||
highlight: 'удержание'
|
||
},
|
||
{
|
||
id: 4,
|
||
name: 'Алексей Нестеров',
|
||
role: 'Growth Manager',
|
||
location: 'Барселона',
|
||
match: 83,
|
||
values: [70, 60, 78, 64, 69],
|
||
tags: ['Paid', 'Analytics', 'B2B'],
|
||
highlight: 'скорость экспериментов'
|
||
},
|
||
{
|
||
id: 5,
|
||
name: 'Анна Прайс',
|
||
role: 'Lifecycle Director',
|
||
location: 'Прага',
|
||
match: 81,
|
||
values: [68, 72, 59, 66, 84],
|
||
tags: ['CRM', 'Email', 'Segmentation'],
|
||
highlight: 'процессы'
|
||
},
|
||
{
|
||
id: 6,
|
||
name: 'Давид Клайн',
|
||
role: 'Growth Partner',
|
||
location: 'Цюрих',
|
||
match: 79,
|
||
values: [66, 64, 73, 62, 70],
|
||
tags: ['Strategy', 'OKR', 'B2B'],
|
||
highlight: 'стратегия'
|
||
}
|
||
],
|
||
therapy: [
|
||
{
|
||
id: 1,
|
||
name: 'Юлия Ланская',
|
||
role: 'Growth Coach',
|
||
location: 'Варшава',
|
||
match: 89,
|
||
values: [70, 86, 60, 75, 78],
|
||
tags: ['Care', 'Leadership', 'Empathy'],
|
||
highlight: 'эмпатия'
|
||
},
|
||
{
|
||
id: 2,
|
||
name: 'Николай Протасов',
|
||
role: 'Team Therapist',
|
||
location: 'Мюнхен',
|
||
match: 86,
|
||
values: [64, 82, 58, 72, 83],
|
||
tags: ['Feedback', 'Culture', 'People'],
|
||
highlight: 'культура'
|
||
},
|
||
{
|
||
id: 3,
|
||
name: 'Леа Хольм',
|
||
role: 'Org Development',
|
||
location: 'Копенгаген',
|
||
match: 84,
|
||
values: [62, 80, 61, 69, 79],
|
||
tags: ['Mentoring', 'Soft Skills', 'Sync'],
|
||
highlight: 'синхронизация'
|
||
},
|
||
{
|
||
id: 4,
|
||
name: 'Роман Игнатьев',
|
||
role: 'Leadership Coach',
|
||
location: 'Рига',
|
||
match: 82,
|
||
values: [66, 78, 63, 67, 74],
|
||
tags: ['Coaching', 'Trust', 'Care'],
|
||
highlight: 'поддержка'
|
||
},
|
||
{
|
||
id: 5,
|
||
name: 'София Брукс',
|
||
role: 'Culture Partner',
|
||
location: 'Лиссабон',
|
||
match: 80,
|
||
values: [60, 76, 57, 70, 77],
|
||
tags: ['Culture', 'Energy', 'Rhythm'],
|
||
highlight: 'тональность'
|
||
},
|
||
{
|
||
id: 6,
|
||
name: 'Тимур Аббасов',
|
||
role: 'People Growth',
|
||
location: 'Стамбул',
|
||
match: 78,
|
||
values: [62, 74, 56, 68, 72],
|
||
tags: ['Well-being', 'Coaching', 'Values'],
|
||
highlight: 'ценности'
|
||
}
|
||
],
|
||
product: [
|
||
{
|
||
id: 1,
|
||
name: 'Кира Дуброва',
|
||
role: 'Product Growth',
|
||
location: 'Стокгольм',
|
||
match: 92,
|
||
values: [84, 64, 78, 76, 71],
|
||
tags: ['PLG', 'Activation', 'Metrics'],
|
||
highlight: 'продуктовый мэтч'
|
||
},
|
||
{
|
||
id: 2,
|
||
name: 'Сергей Пак',
|
||
role: 'Growth PM',
|
||
location: 'Хельсинки',
|
||
match: 88,
|
||
values: [80, 62, 74, 72, 69],
|
||
tags: ['Experiment', 'North Star', 'Team'],
|
||
highlight: 'структура роста'
|
||
},
|
||
{
|
||
id: 3,
|
||
name: 'Мария Йенс',
|
||
role: 'Product Strategy',
|
||
location: 'Вена',
|
||
match: 86,
|
||
values: [78, 66, 69, 74, 70],
|
||
tags: ['Insight', 'Journey', 'B2B'],
|
||
highlight: 'customer insight'
|
||
},
|
||
{
|
||
id: 4,
|
||
name: 'Эмиль Громов',
|
||
role: 'Lifecycle PM',
|
||
location: 'Таллин',
|
||
match: 84,
|
||
values: [74, 60, 71, 68, 73],
|
||
tags: ['Retention', 'PLG', 'SQL'],
|
||
highlight: 'ретеншн'
|
||
},
|
||
{
|
||
id: 5,
|
||
name: 'Дарья Нор',
|
||
role: 'Growth Analyst',
|
||
location: 'Краков',
|
||
match: 82,
|
||
values: [70, 58, 75, 66, 68],
|
||
tags: ['Analytics', 'BI', 'Funnels'],
|
||
highlight: 'данные'
|
||
},
|
||
{
|
||
id: 6,
|
||
name: 'Феликс Штайн',
|
||
role: 'Growth Ops',
|
||
location: 'Женева',
|
||
match: 80,
|
||
values: [68, 56, 73, 64, 66],
|
||
tags: ['Process', 'Automation', 'B2B'],
|
||
highlight: 'операционка'
|
||
}
|
||
]
|
||
} as const
|
||
|
||
const currentMethodology = ref<keyof typeof candidatesByMethodology>('coaching')
|
||
const currentCandidates = computed(() => candidatesByMethodology[currentMethodology.value])
|
||
|
||
const radarAxes = ['Стратегия', 'Эмпатия', 'Темп', 'Креатив', 'Стабильность']
|
||
|
||
const axisPoints = radarAxes.map((_, index) => {
|
||
const angle = (-90 + (360 / radarAxes.length) * index) * (Math.PI / 180)
|
||
const radius = 38
|
||
return {
|
||
x: 50 + radius * Math.cos(angle),
|
||
y: 50 + radius * Math.sin(angle)
|
||
}
|
||
})
|
||
|
||
const radarPoints = (values: number[]) => {
|
||
const radius = 38
|
||
return values
|
||
.map((value, index) => {
|
||
const angle = (-90 + (360 / values.length) * index) * (Math.PI / 180)
|
||
const r = (value / 100) * radius
|
||
const x = 50 + r * Math.cos(angle)
|
||
const y = 50 + r * Math.sin(angle)
|
||
return `${x.toFixed(1)},${y.toFixed(1)}`
|
||
})
|
||
.join(' ')
|
||
}
|
||
|
||
const chatByStep = [
|
||
[
|
||
{ id: 'r1', from: 'ai', text: 'Опиши требования к вакансии. Заполни форму.', step: 0 },
|
||
{ id: 'r2', from: 'user', text: 'Ок, заполняю.' }
|
||
],
|
||
[
|
||
{ id: 'v1', from: 'ai', text: 'Запиши видео по сценарию и загрузи.', step: 1 },
|
||
{ id: 'v2', from: 'user', text: 'Ок, записываю.' }
|
||
],
|
||
[
|
||
{ id: 'f1', from: 'ai', text: 'AI сформировал отпечаток коллектива по видео.', step: 2 },
|
||
{ id: 'f2', from: 'user', text: 'Смотрю профиль.' }
|
||
],
|
||
[
|
||
{ id: 'p1', from: 'ai', text: 'Рекомендации готовы. Откликов нет.', step: 3 },
|
||
{ id: 'p2', from: 'user', text: 'Покажи топ.' }
|
||
],
|
||
[
|
||
{ id: 'm1', from: 'ai', text: 'Созданы мэтчи. Можно открыть чат или интро.', step: 4 },
|
||
{ id: 'm2', from: 'user', text: 'Открываю чат.' }
|
||
]
|
||
]
|
||
</script>
|