(function () { // ====== НАСТРОЙКИ / КЛАССЫ ====== const CORE_OFFERS = ['offer1', 'offer2', 'offer3']; // участвуют в -1/-2 const GATE_OFFERS = ['offer7', 'offer8']; // тарифы (взаимоисключающие) const BLOCK_OVERLAY_SELECTOR = 'div.offer_block'; // блокирующий слой const BLOCK_STYLE_CLASS = 'offer_block_style'; // стиль "заблокирован" // ====== УТИЛИТЫ ====== const $$ = (sel, root=document) => Array.from(root.querySelectorAll(sel)); const $ = (sel, root=document) => root.querySelector(sel); function hasAnyClass(el, classes) { return classes.some(c => el.classList.contains(c)); } function closestOfferEl(el) { // ищем ближайший элемент, который несет offerX класс return el.closest('.offer1, .offer2, .offer3, .offer7, .offer8'); } function setSelectedOnParent(offerEl) { // "родитель" — как ты написал. Берём непосредственного parentElement. // Если нужно выше — поменяй на offerEl.closest('.что-то') const parent = offerEl.parentElement; if (!parent) return; // снимаем selected у соседей в рамках общего контейнера const scope = parent.parentElement || document; $$('.selected', scope).forEach(p => { if (p !== parent) p.classList.remove('selected'); }); parent.classList.add('selected'); } function isBlockedCoreOffers() { // заблокировано, если НЕ выбран ни offer7 ни offer8 return !GATE_OFFERS.some(cls => $(`.${cls}.is-chosen`)); } function getChosenCoreOffers() { return CORE_OFFERS.filter(cls => $(`.${cls}.is-chosen`)); } function getChosenGateOffer() { const a = $(`.${GATE_OFFERS[0]}.is-chosen`); const b = $(`.${GATE_OFFERS[1]}.is-chosen`); return a ? GATE_OFFERS[0] : (b ? GATE_OFFERS[1] : null); } function updateOverlayAndBlockStyles() { const overlay = $(BLOCK_OVERLAY_SELECTOR); const blocked = isBlockedCoreOffers(); // overlay показываем/прячем if (overlay) { overlay.style.display = blocked ? 'block' : 'none'; overlay.style.pointerEvents = blocked ? 'auto' : 'none'; } // offer_block_style на core offers CORE_OFFERS.forEach(cls => { $$('.' + cls).forEach(el => { if (blocked) el.classList.add(BLOCK_STYLE_CLASS); else el.classList.remove(BLOCK_STYLE_CLASS); }); }); } function updateGcOfferVisibility() { // Если выбран 1 из offer1/2/3 => активируем *-1 // Если выбран 2 или 3 => активируем *-2 const chosen = getChosenCoreOffers(); const tier = (chosen.length <= 1) ? 1 : 2; // Скрываем все вариации offer1-1/offer1-2/... и показываем только нужные для выбранных core offers CORE_OFFERS.forEach(core => { const showClass = `${core}-${tier}`; const hideClass = `${core}-${tier === 1 ? 2 : 1}`; // Показываем элементы с нужным классом $$('.' + showClass).forEach(el => { el.style.display = ''; }); // Скрываем противоположные $$('.' + hideClass).forEach(el => { el.style.display = 'none'; }); }); // Если core offer НЕ выбран — скрываем обе его вариации (чтобы в GC не “передавать” лишнее) CORE_OFFERS.forEach(core => { if (!chosen.includes(core)) { $$('.' + core + '-1').forEach(el => { el.style.display = 'none'; }); $$('.' + core + '-2').forEach(el => { el.style.display = 'none'; }); } }); } function buildGcOfferListToSend() { // Возвращает список классов GC, которые "должны пройти" (логика передачи) const chosen = getChosenCoreOffers(); const tier = (chosen.length <= 1) ? 1 : 2; return chosen.map(core => `${core}-${tier}`); } // ====== ОСНОВНОЙ ОБРАБОТЧИК КЛИКОВ ====== function toggleChosen(el, on) { if (on) el.classList.add('is-chosen'); else el.classList.remove('is-chosen'); } function clearChosenFor(classes) { classes.forEach(cls => $$('.' + cls).forEach(el => el.classList.remove('is-chosen'))); } function onOfferClick(e) { const offerEl = closestOfferEl(e.target); if (!offerEl) return; // 1) selected на родителя при нажатии setSelectedOnParent(offerEl); // Какие офферы? const isCore = hasAnyClass(offerEl, CORE_OFFERS); const isGate = hasAnyClass(offerEl, GATE_OFFERS); // Если core-офферы заблокированы — не даём нажать if (isCore && isBlockedCoreOffers()) { // можно подсветить/сообщение return; } // 3) offer7/offer8: взаимоисключающие if (isGate) { const clickedGate = GATE_OFFERS.find(c => offerEl.classList.contains(c)); // снимаем другой gate GATE_OFFERS.forEach(c => { $$('.' + c).forEach(el => toggleChosen(el, c === clickedGate)); }); // Разблокируем core offers updateOverlayAndBlockStyles(); // После выбора gate — core offer'ы остаются как были (или можешь обнулять выбор) // Если нужно обнулять core при смене gate — раскомментируй: // clearChosenFor(CORE_OFFERS); updateGcOfferVisibility(); // Debug/вывод куда “передаем” const list = buildGcOfferListToSend(); console.log('[GC offers]', list, 'gate=', getChosenGateOffer()); return; } // 2) offer1/2/3: можно выбрать несколько (toggle) if (isCore) { // toggle const isNowChosen = !offerEl.classList.contains('is-chosen'); toggleChosen(offerEl, isNowChosen); // если у тебя несколько кнопок одного offerX (например дубли) — синхронизируем все элементы с этим классом: const coreCls = CORE_OFFERS.find(c => offerEl.classList.contains(c)); if (coreCls) { $$('.' + coreCls).forEach(el => toggleChosen(el, isNowChosen)); } updateGcOfferVisibility(); const list = buildGcOfferListToSend(); console.log('[GC offers]', list, 'gate=', getChosenGateOffer()); return; } } // ====== ИНИЦИАЛИЗАЦИЯ ====== function init() { // Начальное состояние: core заблокированы, пока нет gate выбора updateOverlayAndBlockStyles(); // Спрячем все GC-вариации на старте (потом покажем выбранное) ['offer1-1','offer1-2','offer2-1','offer2-2','offer3-1','offer3-2'].forEach(cls => { $$('.' + cls).forEach(el => { el.style.display = 'none'; }); }); document.addEventListener('click', onOfferClick, true); } init(); // Если нужно получить массив “куда передать” извне: window.__getSelectedGcOffers = buildGcOfferListToSend; })();