SIte_Shag/obr_site/modals.js

371 lines
15 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.

document.addEventListener('DOMContentLoaded', function () {
// Модалка с вузами
const universitiesModal = document.getElementById('universitiesModal');
const openUniversitiesBtn = document.getElementById('showModalBtn');
const closeUniversitiesBtn = document.getElementById('closeModalBtn');
function openUniversitiesModal(e){
e.preventDefault();
document.body.style.overflow = 'hidden';
universitiesModal.style.display = 'block';
setTimeout(() => universitiesModal.classList.add('active'), 10);
}
function closeUniversitiesModal(){
universitiesModal.classList.remove('active');
setTimeout(() => {
universitiesModal.style.display = 'none';
document.body.style.overflow = 'auto';
}, 300);
}
if (openUniversitiesBtn) openUniversitiesBtn.addEventListener('click', openUniversitiesModal);
if (closeUniversitiesBtn) closeUniversitiesBtn.addEventListener('click', closeUniversitiesModal);
if (universitiesModal) {
universitiesModal.addEventListener('click', (e) => {
if (e.target === universitiesModal) closeUniversitiesModal();
});
}
// Модалка с тестом
const testModal = document.getElementById('careerTestModal');
const openTestBtn = document.getElementById('showCareerTestBtn');
const closeTestBtn = document.getElementById('closeCareerTestBtn');
function openTestModal(e){
e.preventDefault();
document.body.style.overflow = 'hidden';
testModal.style.display = 'block';
setTimeout(() => testModal.classList.add('active'), 10);
}
function closeTestModal(){
testModal.classList.remove('active');
setTimeout(() => {
testModal.style.display = 'none';
document.body.style.overflow = 'auto';
}, 300);
}
if (openTestBtn) openTestBtn.addEventListener('click', openTestModal);
if (closeTestBtn) closeTestBtn.addEventListener('click', closeTestModal);
if (testModal) {
testModal.addEventListener('click', (e) => {
if (e.target === testModal) closeTestModal();
});
}
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
if (testModal && testModal.style.display === 'block') closeTestModal();
if (universitiesModal && universitiesModal.style.display === 'block') closeUniversitiesModal();
}
});
// Аккордион для вузов
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.style.maxHeight = null;
activeContent.previousElementSibling.classList.remove('active');
}
});
this.classList.toggle('active');
if (content.classList.contains('active')) {
content.classList.remove('active');
content.style.maxHeight = null;
} else {
content.classList.add('active');
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 () {
// ---------- OPEN/CLOSE ----------
const modal = document.getElementById('ratingModal');
const openBtn = document.getElementById('showRatingBtn');
const closeBtn = document.getElementById('closeRatingBtn');
function openModal(e){
e.preventDefault();
document.body.style.overflow = 'hidden';
modal.style.display = 'block';
setTimeout(() => modal.classList.add('active'), 10);
if (typeof ym !== 'undefined') {
ym(105827527, 'reachGoal', 'rating_opened');
}
}
function closeModal(){
modal.classList.remove('active');
setTimeout(() => {
modal.style.display = 'none';
document.body.style.overflow = 'auto';
}, 300);
}
if (openBtn) openBtn.addEventListener('click', openModal);
if (closeBtn) closeBtn.addEventListener('click', closeModal);
if (modal) modal.addEventListener('click', (e) => { if (e.target === modal) closeModal(); });
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal && modal.style.display === 'block') closeModal();
});
// ---------- DATA (пока на фронте, потом можно заменить на API) ----------
// Оценки 0..100 (примерные заглушки). Замени на свои данные.
const universities = [
{ id:'ulgu', name:'УлГУ — Ульяновский государственный университет', type:'classic', acc:90, emp:75, rank:70, rev:78, url:'https://ulsu.ru' },
{ id:'ulstu', name:'УлГТУ — Ульяновский государственный технический университет', type:'technical', acc:88, emp:82, rank:72, rev:74, url:'https://ulstu.ru' },
{ id:'ulspu', name:'УлГПУ — Ульяновский государственный педагогический университет', type:'pedagogical', acc:86, emp:70, rank:60, rev:76, url:'https://ulspu.ru' },
{ id:'ulsau', name:'УлГАУ — Ульяновский государственный аграрный университет', type:'agro', acc:84, emp:68, rank:58, rev:72, url:'https://ulsau.ru' },
{ id:'uiga', name:'УИ ГА — Ульяновский институт гражданской авиации', type:'aviation', acc:85, emp:80, rank:65, rev:70, url:'https://uvauga.ru' },
{ id:'ranepa', name:'РАНХиГС (Ульяновский филиал)', type:'management', acc:83, emp:73, rank:62, rev:69, url:'https://ulyanovsk.ranepa.ru' },
];
// ---------- UI refs ----------
const listEl = document.getElementById('ratingList');
const countEl = document.getElementById('ratingCount');
const searchEl = document.getElementById('ratingSearch');
const sortEl = document.getElementById('ratingSort');
const minTotalEl = document.getElementById('ratingMinTotal');
const minTotalLabel = document.getElementById('ratingMinTotalLabel');
const typeEls = Array.from(document.querySelectorAll('.ratingType'));
const wAcc = document.getElementById('wAcc');
const wEmp = document.getElementById('wEmp');
const wRank = document.getElementById('wRank');
const wRev = document.getElementById('wRev');
const wAccL = document.getElementById('wAccL');
const wEmpL = document.getElementById('wEmpL');
const wRankL = document.getElementById('wRankL');
const wRevL = document.getElementById('wRevL');
const resetBtn = document.getElementById('ratingResetBtn');
function weights() {
return {
acc: Number(wAcc.value),
emp: Number(wEmp.value),
rank: Number(wRank.value),
rev: Number(wRev.value),
};
}
function calcTotal(u, w) {
const sumW = (w.acc + w.emp + w.rank + w.rev) || 1;
return Math.round(
(u.acc * w.acc + u.emp * w.emp + u.rank * w.rank + u.rev * w.rev) / sumW
);
}
function getSelectedTypes() {
return new Set(typeEls.filter(x => x.checked).map(x => x.value));
}
function render() {
const q = (searchEl.value || '').trim().toLowerCase();
const minTotal = Number(minTotalEl.value);
const selectedTypes = getSelectedTypes();
const w = weights();
// обновление лейблов
minTotalLabel.textContent = String(minTotal);
wAccL.textContent = w.acc; wEmpL.textContent = w.emp; wRankL.textContent = w.rank; wRevL.textContent = w.rev;
// фильтрация
let items = universities
.map(u => ({ ...u, total: calcTotal(u, w) }))
.filter(u => !q || u.name.toLowerCase().includes(q))
.filter(u => selectedTypes.has(u.type))
.filter(u => u.total >= minTotal);
// сортировка
const sort = sortEl.value;
const cmpNum = (k) => (a,b) => b[k] - a[k];
if (sort === 'total_desc') items.sort(cmpNum('total'));
if (sort === 'employment_desc') items.sort(cmpNum('emp'));
if (sort === 'reviews_desc') items.sort(cmpNum('rev'));
if (sort === 'accreditation_desc') items.sort(cmpNum('acc'));
if (sort === 'name_asc') items.sort((a,b) => a.name.localeCompare(b.name, 'ru'));
countEl.textContent = String(items.length);
// рендер
listEl.innerHTML = items.map((u, i) => `
<div class="university-card">
<div class="university-header">
<h3>${i+1}) ${u.name}</h3>
<div class="university-meta">
<div class="meta-item"><i class="fas fa-star"></i> Итог: <b>${u.total}</b>/100</div>
<div class="meta-item"><i class="fas fa-check-circle"></i> Аккредитация: ${u.acc}/100</div>
<div class="meta-item"><i class="fas fa-briefcase"></i> Трудоустройство: ${u.emp}/100</div>
<div class="meta-item"><i class="fas fa-trophy"></i> Рейтинги: ${u.rank}/100</div>
<div class="meta-item"><i class="fas fa-comment"></i> Отзывы: ${u.rev}/100</div>
</div>
</div>
<div class="university-body">
<div class="directions-list" style="margin-top:0;">
<div class="direction-item">Тип: ${u.type}</div>
<div class="direction-item">Весовая модель: A${w.acc}/E${w.emp}/R${w.rank}/O${w.rev}</div>
</div>
</div>
<div class="university-footer">
<a href="${u.url}" target="_blank" class="official-site">
Официальный сайт <i class="fas fa-external-link-alt"></i>
</a>
<a href="#" class="official-site ratingMoreBtn" data-id="${u.id}">
Подробнее <i class="fas fa-chevron-right"></i>
</a>
</div>
</div>
`).join('');
// метрика по фильтрам (без спама: отправляем на изменение, но с лёгкой защитой)
if (typeof ym !== 'undefined') {
ym(105827527, 'reachGoal', 'rating_filtered', {
q: q ? '1' : '0',
min_total: String(minTotal),
types: Array.from(selectedTypes).join(','),
sort: sort
});
}
}
// события
[searchEl, sortEl, minTotalEl, wAcc, wEmp, wRank, wRev, ...typeEls].forEach(el => {
el.addEventListener('input', render);
el.addEventListener('change', render);
});
if (resetBtn) {
resetBtn.addEventListener('click', () => {
searchEl.value = '';
sortEl.value = 'total_desc';
minTotalEl.value = 0;
typeEls.forEach(x => x.checked = true);
wAcc.value = 20; wEmp.value = 35; wRank.value = 25; wRev.value = 20;
render();
});
}
// initial render
render();
});
document.addEventListener('DOMContentLoaded', function() {
// --- Логика фильтрации рейтинга вузов ---
const filterDirection = document.getElementById('filterDirection');
const filterDorm = document.getElementById('filterDorm');
const filterMil = document.getElementById('filterMil');
const universitiesList = document.getElementById('universitiesList');
const noResultsMsg = document.getElementById('noResultsMsg');
const ratingModal = document.getElementById('ratingModal');
const openRatingBtn = document.getElementById('showRatingModalBtn');
const closeRatingBtn = document.getElementById('closeRatingModalBtn');
// Функция фильтрации
function filterUniversities() {
if(!universitiesList) return;
const typeVal = filterDirection.value;
const needDorm = filterDorm.checked;
const needMil = filterMil.checked;
const cards = universitiesList.querySelectorAll('.university-card');
let visibleCount = 0;
cards.forEach(card => {
const types = (card.dataset.type || '').split(' ');
const hasDorm = card.dataset.dorm === 'true';
const hasMil = card.dataset.mil === 'true';
let match = true;
if (typeVal !== 'all' && !types.includes(typeVal)) {
match = false;
}
if (needDorm && !hasDorm) {
match = false;
}
if (needMil && !hasMil) {
match = false;
}
card.style.display = match ? 'block' : 'none';
if (match) visibleCount++;
});
noResultsMsg.style.display = visibleCount === 0 ? 'block' : 'none';
}
// Слушатели для фильтров
if (filterDirection) filterDirection.addEventListener('change', filterUniversities);
if (filterDorm) filterDorm.addEventListener('change', filterUniversities);
if (filterMil) filterMil.addEventListener('change', filterUniversities);
// Открытие модалки рейтинга
if (openRatingBtn) {
openRatingBtn.addEventListener('click', function(e) {
e.preventDefault();
if (typeof ym !== 'undefined') {
ym(105827527, 'reachGoal', 'rating_opened');
}
document.body.style.overflow = 'hidden';
ratingModal.style.display = 'block';
setTimeout(() => ratingModal.classList.add('active'), 10);
});
}
// Закрытие модалки
function closeRating() {
if (ratingModal) {
ratingModal.classList.remove('active');
setTimeout(() => {
ratingModal.style.display = 'none';
document.body.style.overflow = 'auto';
}, 300);
}
}
if (closeRatingBtn) closeRatingBtn.addEventListener('click', closeRating);
// Закрытие по клику на фон
if (ratingModal) {
ratingModal.addEventListener('click', (e) => {
if (e.target === ratingModal) closeRating();
});
}
// Закрытие по Escape
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && ratingModal && ratingModal.style.display === 'block') {
closeRating();
}
});
});