403 lines
17 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

particlesJS('particles-js', {
particles: {
number: { value: 80, density: { enable: true, value_area: 800 } },
color: { value: "#0071e3" },
shape: { type: "circle" },
opacity: { value: 0.3, random: true },
size: { value: 3, random: true },
line_linked: {
enable: true,
distance: 150,
color: "#0071e3",
opacity: 0.1,
width: 1
},
move: {
enable: true,
speed: 2,
direction: "none",
random: true,
straight: false,
out_mode: "out",
bounce: false
}
},
interactivity: {
detect_on: "canvas",
events: {
onhover: { enable: true, mode: "repulse" },
onclick: { enable: true, mode: "push" },
resize: true
}
}
});
// Управление модальным окном
const modal = document.getElementById('universitiesModal');
const showModalBtn = document.getElementById('showModalBtn');
const closeModalBtn = document.getElementById('closeModalBtn');
// Открытие модального окна
showModalBtn.addEventListener('click', function(e) {
e.preventDefault();
document.body.style.overflow = 'hidden';
modal.style.display = 'block';
// Активируем анимацию после отображения
setTimeout(() => {
modal.classList.add('active');
}, 10);
});
// Закрытие модального окна
function closeModal() {
modal.classList.remove('active');
setTimeout(() => {
modal.style.display = 'none';
document.body.style.overflow = 'auto';
}, 300);
}
closeModalBtn.addEventListener('click', closeModal);
// Закрытие при клике вне модального окна
modal.addEventListener('click', function(e) {
if (e.target === modal) {
closeModal();
}
});
// Закрытие при нажатии Escape
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && modal.style.display === 'block') {
closeModal();
}
});
// Дополнительный JavaScript для интерактивности
document.addEventListener('DOMContentLoaded', function() {
// Эффект параллакса для плавающих элементов
const floatingElements = document.querySelectorAll('.floating-element');
window.addEventListener('mousemove', function(e) {
const mouseX = e.clientX / window.innerWidth;
const mouseY = e.clientY / window.innerHeight;
floatingElements.forEach((el, index) => {
const speed = 0.5 + (index * 0.2);
const x = (mouseX - 0.5) * 50 * speed;
const y = (mouseY - 0.5) * 50 * speed;
el.style.transform = `translate(${x}px, ${y}px)`;
});
});
// Плавный скролл для всех ссылок
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
// Анимация появления элементов при скролле
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.opacity = '1';
entry.target.style.transform = 'translateY(0)';
}
});
}, observerOptions);
// Наблюдаем за карточками
document.querySelectorAll('.btn-container, .info-section, .qa-card, .university-card').forEach(el => {
el.style.opacity = '0';
el.style.transform = 'translateY(20px)';
el.style.transition = 'opacity 0.5s ease, transform 0.5s ease';
observer.observe(el);
});
// Аккордеон для факультетов
const accordionHeaders = document.querySelectorAll('.accordion-header');
accordionHeaders.forEach(header => {
header.addEventListener('click', function() {
const item = this.parentElement;
const content = this.nextElementSibling;
// Закрываем все открытые элементы
document.querySelectorAll('.accordion-content.active').forEach(activeContent => {
if (activeContent !== content) {
activeContent.classList.remove('active');
activeContent.previousElementSibling.classList.remove('active');
}
});
// Переключаем текущий элемент
this.classList.toggle('active');
content.classList.toggle('active');
// Если элемент закрывается, сбрасываем высоту
if (!content.classList.contains('active')) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + 'px';
}
});
});
// Инициализация аккордеона - открываем первый элемент в каждой карточке
document.querySelectorAll('.university-card').forEach(card => {
const firstAccordion = card.querySelector('.accordion-item');
if (firstAccordion) {
const header = firstAccordion.querySelector('.accordion-header');
const content = firstAccordion.querySelector('.accordion-content');
header.classList.add('active');
content.classList.add('active');
content.style.maxHeight = content.scrollHeight + 'px';
}
});
});
document.addEventListener('DOMContentLoaded', function () {
// ====== 2-я модалка (тест) ======
const testModal = document.getElementById('careerTestModal');
const openBtn = document.getElementById('showCareerTestBtn');
const closeBtn = document.getElementById('closeCareerTestBtn');
function openTest(e){
e.preventDefault();
document.body.style.overflow = 'hidden';
testModal.style.display = 'block';
setTimeout(() => testModal.classList.add('active'), 10);
}
function closeTest(){
testModal.classList.remove('active');
setTimeout(() => {
testModal.style.display = 'none';
document.body.style.overflow = 'auto';
}, 300);
}
if (openBtn) openBtn.addEventListener('click', openTest);
if (closeBtn) closeBtn.addEventListener('click', closeTest);
if (testModal) testModal.addEventListener('click', (e) => { if (e.target === testModal) closeTest(); });
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && testModal && testModal.style.display === 'block') closeTest();
});
// ====== Логика теста ======
const form = document.getElementById('careerTestForm');
if (!form) return;
const steps = Array.from(form.querySelectorAll('.career-step'));
const prevBtn = document.getElementById('careerTestPrevBtn');
const nextBtn = document.getElementById('careerTestNextBtn');
const submitBtn = document.getElementById('careerTestSubmitBtn');
const fill = document.getElementById('careerTestProgressFill');
const stepLabel = document.getElementById('careerTestStepLabel');
const resultBox = document.getElementById('careerTestResult');
const resultTitle = document.getElementById('careerTestResultTitle');
const resultBadges = document.getElementById('careerTestResultBadges');
const resultText = document.getElementById('careerTestResultText');
let idx = 0;
const typeTitles = {
R: '🔧 ПРАКТИК', I: '🔬 ИССЛЕДОВАТЕЛЬ', A: '🎨 ТВОРЕЦ',
S: '👥 СОЦИАЛ', E: '💼 ЛИДЕР', C: '📊 ОРГАНИЗАТОР'
};
// Наборы ЕГЭ под 73 балла для каждого профиля
const egeSets = {
R: {
title: 'Техника/производство/агро/транспорт',
ege: [
'📐 <strong>Рус + Профмат + Физика</strong> (технические специальности)',
'🌾 <strong>Рус + Биология + Химия</strong> (агрономия/ветеринария)',
'🚗 <strong>Рус + Профмат + Информатика</strong> (автотранспорт)'
],
desc: 'Инженерия, строительство, транспорт, агрономия, техника.'
},
I: {
title: 'IT/инженерия/наука/анализ',
ege: [
'💻 <strong>Рус + Профмат + Информатика</strong> (IT/программирование)',
'🔬 <strong>Рус + Профмат + Физика</strong> (инженерия/физика)',
'📊 <strong>Рус + Профмат + Химия</strong> (технологии/материаловедение)'
],
desc: 'Программирование, инженерия, физика, математика, исследования.'
},
A: {
title: 'Дизайн/медиа/креатив',
ege: [
'🎨 <strong>Рус + Обществознание + Литература</strong> (журналистика/дизайн)',
'📱 <strong>Рус + Профмат + Информатика</strong> (веб-дизайн/UI/UX)',
'📸 <strong>Рус + История + Иностранный</strong> (медиа/реклама)'
],
desc: 'Дизайн, журналистика, реклама, медиа, творческие индустрии.'
},
S: {
title: 'Помощь людям/педагогика/медицина',
ege: [
'👩‍⚕️ <strong>Рус + Биология + Химия</strong> (медицина/биология)',
'👨‍🏫 <strong>Рус + Обществознание + История</strong> (педагогика/психология)',
'🧠 <strong>Рус + Обществознание + Биология</strong> (социология/социальная работа)'
],
desc: 'Медицина, педагогика, психология, социальная работа.'
},
E: {
title: 'Управление/бизнес/право',
ege: [
'⚖️ <strong>Рус + Обществознание + История</strong> (юриспруденция/госуправление)',
'💼 <strong>Рус + Обществознание + Профмат</strong> (экономика/менеджмент)',
'📈 <strong>Рус + Обществознание + Иностранный</strong> (международные отношения)'
],
desc: 'Юриспруденция, экономика, менеджмент, государственное управление.'
},
C: {
title: 'Учёт/логистика/документы',
ege: [
'📋 <strong>Рус + Обществознание + Профмат</strong> (бухучёт/логистика)',
'📊 <strong>Рус + Профмат + Информатика</strong> (экономика/финансы)',
'🏢 <strong>Рус + Обществознание + История</strong> (администрирование)'
],
desc: 'Бухгалтерия, логистика, документооборот, администрирование.'
}
};
function isAnswered(){
return !!steps[idx].querySelector('input[type="radio"]:checked');
}
function render(){
steps.forEach((s, i) => s.classList.toggle('active', i === idx));
const pct = ((idx + 1) / steps.length) * 100;
fill.style.width = pct + '%';
stepLabel.textContent = `Шаг ${idx + 1} из ${steps.length}`;
prevBtn.disabled = idx === 0;
if (idx === steps.length - 1) {
nextBtn.style.display = 'none';
submitBtn.style.display = 'inline-block';
} else {
nextBtn.style.display = 'inline-block';
submitBtn.style.display = 'none';
}
}
nextBtn.addEventListener('click', () => {
if (!isAnswered()) return alert('Выбери вариант ответа');
idx = Math.min(idx + 1, steps.length - 1);
render();
});
prevBtn.addEventListener('click', () => {
idx = Math.max(idx - 1, 0);
render();
});
form.addEventListener('submit', (e) => {
e.preventDefault();
if (!isAnswered()) return alert('Ответь на последний вопрос');
// Собери все ответы q1-q24
const answers = {};
for (let i = 1; i <= 24; i++) {
const v = form.elements[`q${i}`]?.value;
if (v) answers[`q${i}`] = v;
}
// Получи ClientID из Метрики
let ym_client_id = null;
const COUNTER_ID = 105827527;
if (typeof ym !== 'undefined') {
ym(COUNTER_ID, 'getClientID', (cid) => {
ym_client_id = cid;
submitTest();
});
} else {
submitTest();
}
function submitTest() {
// Отправь на бэкенд
fetch('career-test/submit/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ answers, ym_client_id })
})
.then(r => {
if (!r.ok) throw new Error(`HTTP ${r.status}`);
return r.json();
})
.then(data => {
// Результаты с сервера
const profile = data.profile;
const profileDisplay = data.profile_display;
const top3 = data.top3_profiles;
const ege = data.recommended_ege_sets;
// Показать результат на странице
resultTitle.textContent = `Профиль: ${profileDisplay}`;
resultBadges.innerHTML = top3.map(t => `<span class="pill">${t}</span>`).join('');
resultText.innerHTML = `
<p><strong>${ege.title}</strong></p>
<p>${ege.desc}</p>
<h4>🎯 <strong>Рекомендуемые наборы ЕГЭ (73 балла):</strong></h4>
${ege.ege.map(set => `<div style="margin:8px 0;padding:12px;background:#fff;border-radius:8px;border-left:4px solid #0071e3;">${set}</div>`).join('')}
<p style="color:#515154;margin-top:16px;"><strong>Совет:</strong> Выбирай 1-й набор (основной профиль) + 1 запасной из топ-3.</p>
`;
resultBox.style.display = 'block';
document.querySelector('#careerTestModal .career-test-actions').style.display = 'none';
steps.forEach(s => s.style.display = 'none');
// ✅ ОТПРАВЬ СОБЫТИЕ В МЕТРИКУ
if (typeof ym !== 'undefined') {
ym(105827527, 'reachGoal', 'career_test_completed', {
profile: profile,
profile_name: profileDisplay,
ege_main: ege.ege[0] || null
});
}
console.log('✅ Результат сохранён. ID:', data.id);
})
.catch(err => {
console.error('❌ Ошибка:', err);
alert('Ошибка при отправке результата: ' + err.message);
});
}
});
document.addEventListener('DOMContentLoaded', () => {
const startBtn = document.getElementById('showCareerTestBtn');
if (!startBtn) return;
startBtn.addEventListener('click', () => {
if (typeof ym !== 'undefined') {
ym(COUNTER_ID, 'reachGoal', 'career_test_start');
}
});
});
render();
});