git-subtree-dir: template-parts/la-components git-subtree-mainline:main7c5a7f373a
git-subtree-split:54eb8e266f
commit
d2bec21994
@ -0,0 +1,68 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Блок с клубными картами |
||||||
|
*/ |
||||||
|
|
||||||
|
// Получение полей ACF |
||||||
|
$block_id = 'club-cards-' . $block['id']; |
||||||
|
$class_name = 'club-cards-block'; |
||||||
|
if (!empty($block['className'])) { |
||||||
|
$class_name .= ' ' . $block['className']; |
||||||
|
} |
||||||
|
if (!empty($block['align'])) { |
||||||
|
$class_name .= ' align' . $block['align']; |
||||||
|
} |
||||||
|
|
||||||
|
// Получение карт для текущего языка |
||||||
|
function get_club_cards_for_current_language() { |
||||||
|
$current_lang = pll_current_language(); |
||||||
|
|
||||||
|
$args = array( |
||||||
|
'post_type' => 'club-card', |
||||||
|
'posts_per_page' => -1, |
||||||
|
'lang' => $current_lang, |
||||||
|
'post_status' => 'publish' |
||||||
|
); |
||||||
|
|
||||||
|
return get_posts($args); |
||||||
|
} |
||||||
|
|
||||||
|
$cards = get_club_cards_for_current_language(); |
||||||
|
?> |
||||||
|
|
||||||
|
<div id="<?php echo esc_attr($block_id); ?>" class="container mx-auto <?php echo esc_attr($class_name); ?>">
|
||||||
|
<?php if ($cards): ?> |
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-[24px]"> |
||||||
|
<?php foreach ($cards as $card): ?> |
||||||
|
<div class="club-card rounded-[8px] overflow-hidden hover:shadow-xl transition-shadow duration-[300ms]"> |
||||||
|
<?php if (has_post_thumbnail($card->ID)): ?> |
||||||
|
<div class="aspect-video overflow-hidden"> |
||||||
|
<?php echo get_the_post_thumbnail($card->ID, 'medium', ['class' => 'w-full h-full object-cover']); ?> |
||||||
|
</div> |
||||||
|
<?php endif; ?> |
||||||
|
|
||||||
|
<div class="p-[24px]"> |
||||||
|
<h3 class="text-[20px] font-semibold mb-[12px]"> |
||||||
|
<?php echo get_the_title($card->ID); ?> |
||||||
|
</h3> |
||||||
|
|
||||||
|
<?php if (get_the_excerpt($card->ID)): ?> |
||||||
|
<div class="text-gray-600 mb-[16px]"> |
||||||
|
<?php echo get_the_excerpt($card->ID); ?> |
||||||
|
</div> |
||||||
|
<?php endif; ?> |
||||||
|
|
||||||
|
|
||||||
|
<div class="text-center"> |
||||||
|
<button data-modal="club-card" |
||||||
|
data-card-id="<?php echo $card->ID; ?>"
|
||||||
|
class="inline-block px-[24px] py-[12px] bg-blue-500 text-white rounded-[6px] hover:bg-blue-600 transition-colors duration-[300ms]"> |
||||||
|
Подробнее |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<?php endforeach; ?> |
||||||
|
</div> |
||||||
|
<?php endif; ?> |
||||||
|
</div> |
@ -0,0 +1,110 @@ |
|||||||
|
ymaps.ready(function () { |
||||||
|
|
||||||
|
var buildingCoordinates = [55.832659, 37.576118]; |
||||||
|
|
||||||
|
//Смещение карты, чтобы иконка была визуально по центру
|
||||||
|
var offsetCoefficient = 0.001; |
||||||
|
|
||||||
|
var mapCenter = [ |
||||||
|
buildingCoordinates[0], |
||||||
|
buildingCoordinates[1] - offsetCoefficient |
||||||
|
]; |
||||||
|
|
||||||
|
var myMap = new ymaps.Map('map', { |
||||||
|
center: mapCenter, |
||||||
|
zoom: 17, |
||||||
|
controls: [] |
||||||
|
}); |
||||||
|
|
||||||
|
// Отключаем все взаимодействия с картой
|
||||||
|
myMap.behaviors.disable(['scrollZoom', 'drag', 'multiTouch', 'dblClickZoom']); |
||||||
|
|
||||||
|
var svgIcon = '<svg width="146" height="175" viewBox="0 0 146 175" fill="none" xmlns="http://www.w3.org/2000/svg">' + |
||||||
|
'<path d="M73 174.328L48.4669 131.836H97.5331L73 174.328Z" fill="#FA4241" />' + |
||||||
|
'<circle cx="71.9104" cy="73" r="73" fill="url(#paint0_linear_150_2453)" />' + |
||||||
|
'<path d="M58.0581 42.549C50.1523 47.1076 43.6824 50.8665 43.6985 50.9305C43.7469 51.0424 52.3304 56.0169 52.4756 56.0169C52.524 56.0169 57.0094 53.4577 62.4628 50.3386C67.9162 47.2196 72.4339 44.6444 72.5145 44.6284C72.5952 44.5964 77.1612 47.1556 82.6631 50.3067L92.6825 56.0429L96.942 53.6117C99.2656 52.2841 101.266 51.1004 101.379 51.0044C101.525 50.8765 98.0553 48.8131 87.2614 42.639C79.3878 38.1444 72.8372 34.4175 72.7081 34.3855C72.5791 34.3375 65.9801 38.0164 58.0581 42.549Z" fill="white" />' + |
||||||
|
'<path d="M38.5032 73.2768V92.7908L42.0043 90.7755C43.9405 89.6718 45.9734 88.5201 46.5381 88.2002L47.5384 87.6244V78.2993C47.5384 73.1648 47.5707 68.9741 47.603 68.9741C47.6352 68.9741 53.2661 72.1891 60.1232 76.1079C66.9642 80.0267 72.6597 83.1938 72.7565 83.1458C72.8694 83.0978 78.5003 79.8828 85.2929 75.98L97.6357 68.8941L97.7164 78.3153L97.7971 87.7204L102.234 90.2636L106.67 92.8068L106.719 73.2408C106.735 62.54 106.719 53.7587 106.687 53.7267C106.655 53.6947 98.9746 58.0614 89.6008 63.4358L72.5629 73.2088L55.896 63.6757C46.7317 58.4133 39.0679 54.0306 38.8743 53.9027L38.5032 53.6787V73.2768Z" fill="white" />' + |
||||||
|
'<path d="M47.9893 93.0937C45.6014 94.4692 43.6653 95.6209 43.6653 95.6849C43.6653 95.8288 72.449 112.24 72.6588 112.224C72.9008 112.192 101.587 95.7968 101.587 95.6849C101.587 95.6369 99.5867 94.4692 97.1508 93.0777L92.6977 90.5344L82.6782 96.2767C77.1603 99.4277 72.5781 101.987 72.5136 101.955C72.4329 101.939 67.8991 99.3637 62.4618 96.2447C57.0084 93.1256 52.4908 90.5664 52.4262 90.5824C52.3456 90.5984 50.361 91.7181 47.9893 93.0937Z" fill="white" />' + |
||||||
|
'<defs>' + |
||||||
|
'<linearGradient id="paint0_linear_150_2453" x1="2.4683" y1="6.137" x2="115.196" y2="71.48" gradientUnits="userSpaceOnUse">' + |
||||||
|
'<stop stop-color="#F41C1B" />' + |
||||||
|
'<stop offset="0.435" stop-color="#F72D2C" />' + |
||||||
|
'<stop offset="1" stop-color="#FA4242" />' + |
||||||
|
'</linearGradient>' + |
||||||
|
'</defs>' + |
||||||
|
'</svg>'; |
||||||
|
|
||||||
|
|
||||||
|
var iconSize; |
||||||
|
var iconOffset; |
||||||
|
|
||||||
|
if (window.innerWidth <= 768) { |
||||||
|
|
||||||
|
iconSize = [73, 88]; |
||||||
|
iconOffset = [-36, -87]; |
||||||
|
} else { |
||||||
|
|
||||||
|
iconSize = [146, 175]; |
||||||
|
iconOffset = [-73, -174]; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
var myPlacemark = new ymaps.Placemark( |
||||||
|
buildingCoordinates, |
||||||
|
{hintContent: '', balloonContent: ''}, |
||||||
|
{ |
||||||
|
|
||||||
|
iconLayout: 'default#imageWithContent', |
||||||
|
iconImageHref: 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svgIcon), |
||||||
|
iconImageSize: iconSize, |
||||||
|
iconImageOffset: iconOffset, |
||||||
|
hideIconOnBalloonOpen: false |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
|
||||||
|
myMap.panes.get('ground').getElement().style.filter = 'grayscale(100%)'; |
||||||
|
|
||||||
|
|
||||||
|
myMap.geoObjects.add(myPlacemark); |
||||||
|
|
||||||
|
|
||||||
|
var isMapInteractive = false; |
||||||
|
var mapElement = document.getElementById('map'); |
||||||
|
|
||||||
|
function activateMap(e) { |
||||||
|
if (!isMapInteractive) { |
||||||
|
myMap.behaviors.enable(['scrollZoom', 'drag', 'multiTouch', 'dblClickZoom']); |
||||||
|
isMapInteractive = true; |
||||||
|
|
||||||
|
setTimeout(function () { |
||||||
|
document.addEventListener('click', deactivateMap); |
||||||
|
document.addEventListener('touchend', deactivateMap); |
||||||
|
}, 100); |
||||||
|
|
||||||
|
e.stopPropagation(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function deactivateMap(e) { |
||||||
|
var target = e.target; |
||||||
|
|
||||||
|
if (e.type === 'touchend' || e.changedTouches || e.changedTouches[0]) { |
||||||
|
var touch = e.changedTouches[0]; |
||||||
|
target = document.elementFromPoint(touch.clientX, touch.clientY); |
||||||
|
} |
||||||
|
|
||||||
|
if (!mapElement.contains(target)) { |
||||||
|
|
||||||
|
myMap.behaviors.disable(['scrollZoom', 'drag', 'multiTouch', 'dblClickZoom']); |
||||||
|
isMapInteractive = false; |
||||||
|
|
||||||
|
|
||||||
|
document.removeEventListener('click', deactivateMap); |
||||||
|
document.removeEventListener('touchend', deactivateMap); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
mapElement.addEventListener('click', activateMap); |
||||||
|
mapElement.addEventListener('touchstart', activateMap); |
||||||
|
}); |
@ -0,0 +1,131 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Шаблон для блока преимуществ |
||||||
|
*/ |
||||||
|
|
||||||
|
$blocks = parse_blocks(get_the_content()); |
||||||
|
$is_first_block = false; |
||||||
|
|
||||||
|
if (!empty($blocks) && isset($blocks[0]['blockName']) && $blocks[0]['blockName'] === 'acf/contacts-block') { |
||||||
|
$is_first_block = true; |
||||||
|
} |
||||||
|
|
||||||
|
$section_padding = $is_first_block ? "pt-[65px] max-[768px]:pt-[35px]" : "pt-[120px] max-[768px]:pt-[70px]"; |
||||||
|
|
||||||
|
?> |
||||||
|
|
||||||
|
<style> |
||||||
|
/* Скрываем, но лучше не нужно по копирайту */ |
||||||
|
.ymaps-2-1-79-copyright, .ymaps-2-1-79-gototech, .ymaps-2-1-79-gototaxi, .ymaps-2-1-79-gotoymaps, |
||||||
|
.ymaps-2-1-79-map-copyrights-promo, .ymaps-2-1-79-copyright__wrap, .ymaps-2-1-79-copyright__content-cell, |
||||||
|
[class*="ymaps-2"][class*="copyright"], [class*="ymaps-2"][class*="gototech"], |
||||||
|
[class*="ymaps-2"][class*="gototaxi"], [class*="ymaps-2"][class*="gotoymaps"] { |
||||||
|
display: none !important; |
||||||
|
opacity: 0 !important; |
||||||
|
visibility: hidden !important; |
||||||
|
} |
||||||
|
</style> |
||||||
|
|
||||||
|
<section class="<?php echo $section_padding ?> full-layout">
|
||||||
|
<div class="max-[1200px]:max-w-[640px] max-[768px]:max-w-[340px] hidden max-[1200px]:block mx-auto mb-[-120px] bg-white w-full max-w-[378px] simple-shadow rounded-[25px] relative z-10"> |
||||||
|
<div class="max-[768px]:pl-[30px] max-[768px]:pt-[30px] max-[768px]:rounded-[20px] pl-[45px] pt-[40px] pb-[40px] relative rounded-[25px] overflow-hidden"> |
||||||
|
<svg class="absolute bottom-[-55px] right-[-65px]" width="126" height="129" viewBox="0 0 126 129" |
||||||
|
fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||||
|
<rect x="60.8145" width="82.2698" height="98.6297" transform="rotate(38.0681 60.8145 0)" |
||||||
|
fill="url(#paint0_linear_2001_4983)"/> |
||||||
|
<defs> |
||||||
|
<linearGradient id="paint0_linear_2001_4983" x1="62.7686" y1="4.14594" x2="131.553" y2="37.4035" |
||||||
|
gradientUnits="userSpaceOnUse"> |
||||||
|
<stop stop-color="#F41C1B"/> |
||||||
|
<stop offset="0.435" stop-color="#F72D2C"/> |
||||||
|
<stop offset="1" stop-color="#FA4242"/> |
||||||
|
</linearGradient> |
||||||
|
</defs> |
||||||
|
</svg> |
||||||
|
<div class="py-[10px] px-[25px] w-full max-w-fit gap-[19px] border border-[#dedede] rounded-[1111px] flex items-center justify-center"> |
||||||
|
<?php |
||||||
|
display_icon('dot'); |
||||||
|
?> |
||||||
|
<span class="font-light text-[14px] leading-[140%] text-[#565656]">Связь с нами</span> |
||||||
|
</div> |
||||||
|
<div class="max-[768px]:max-w-[240px] flex flex-col gap-[20px]"> |
||||||
|
<h2 class="max-[768px]:text-[28px] font-bold mt-[25px] text-[45px] leading-[130%] text-[#3f3f3f]"> |
||||||
|
Контакты</h2> |
||||||
|
<div class="max-[768px]:text-[24px] flex flex-col font-semibold text-[28px] leading-[165%] text-[#3f3f3f]"> |
||||||
|
<p class="max-[768px]:text-[15px] font-light text-[18px] text-[#828282]">Номер телефона:</p> |
||||||
|
<a target="_blank" href="tel:<?php echo get_field('phones', 'options')['main_phone'] ?>"
|
||||||
|
class="hover:text-[#f62322] !decoration-transparent skip-ink transition-colors" |
||||||
|
href="tel:+7(800)302-11-85"><?php echo get_field('phones', 'options')['main_phone'] ?></a>
|
||||||
|
<a target="_blank" href="tel:<?php echo get_field('phones', 'options')['phone'] ?>"
|
||||||
|
class="hover:text-[#f62322] !decoration-transparent skip-ink transition-colors" |
||||||
|
href="tel:+7(911)098-59-77"><?php echo get_field('phones', 'options')['phone'] ?></a>
|
||||||
|
</div> |
||||||
|
<div class="flex flex-col gap-[10px]"> |
||||||
|
<p class="max-[768px]:text-[15px] font-light text-[18px] text-[#828282]">Головной офис:</p> |
||||||
|
<div class="max-[768px]:text-[19px] font-normal text-[23px] leading-[137%] text-[#3f3f3f]"> |
||||||
|
<?php echo get_field('address', 'options') ?> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="flex flex-col gap-[10px]"> |
||||||
|
<p class="max-[768px]:text-[15px] font-light text-[18px] text-[#828282]">E-mail:</p> |
||||||
|
<a class="max-[768px]:text-[19px] hover:text-[#f62322] !decoration-transparent skip-ink transition-colors font-normal text-[23px] leading-[137%] text-[#3f3f3f]" |
||||||
|
href="mailto:info@mylogistika2010.ru"><?php echo get_field('email', 'options') ?></a>
|
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div id="map-container" |
||||||
|
class="max-[1200px]:p-0 max-[1200px]:h-[600px] pt-[90px] pl-[62px] pb-[89px] rounded-[35px] relative"> |
||||||
|
<div id="map" class="absolute top-0 left-0 w-full h-full rounded-[35px] overflow-hidden z-0"></div> |
||||||
|
<div class="max-[1200px]:hidden bg-white w-full max-w-[378px] simple-shadow rounded-[25px] relative z-10"> |
||||||
|
<div class=" pl-[45px] pt-[40px] pb-[40px] relative rounded-[25px] overflow-hidden"> |
||||||
|
<svg class="absolute bottom-[-55px] right-[-65px]" width="126" height="129" viewBox="0 0 126 129" |
||||||
|
fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||||
|
<rect x="60.8145" width="82.2698" height="98.6297" transform="rotate(38.0681 60.8145 0)" |
||||||
|
fill="url(#paint0_linear_2001_4983)"/> |
||||||
|
<defs> |
||||||
|
<linearGradient id="paint0_linear_2001_4983" x1="62.7686" y1="4.14594" x2="131.553" y2="37.4035" |
||||||
|
gradientUnits="userSpaceOnUse"> |
||||||
|
<stop stop-color="#F41C1B"/> |
||||||
|
<stop offset="0.435" stop-color="#F72D2C"/> |
||||||
|
<stop offset="1" stop-color="#FA4242"/> |
||||||
|
</linearGradient> |
||||||
|
</defs> |
||||||
|
</svg> |
||||||
|
<div class="py-[10px] px-[25px] w-full max-w-fit gap-[19px] border border-[#dedede] rounded-[1111px] flex items-center justify-center"> |
||||||
|
<?php |
||||||
|
display_icon('dot'); |
||||||
|
?> |
||||||
|
<span class="font-light text-[14px] leading-[140%] text-[#565656]">Свяжитесь с нами</span> |
||||||
|
</div> |
||||||
|
<div class="flex flex-col gap-[20px]"> |
||||||
|
<h2 class="max-[768px]:text-[28px] max-[1200px]:mb-[20px] font-bold mt-[25px] text-[45px] leading-[130%] text-[#3f3f3f]"> |
||||||
|
Контакты</h2> |
||||||
|
<div class="flex flex-col font-semibold text-[28px] leading-[165%] text-[#3f3f3f]"> |
||||||
|
<p class=" font-light text-[18px] text-[#828282]">Номер телефона:</p> |
||||||
|
<a target="_blank" href="tel:<?php echo get_field('phones', 'options')['main_phone'] ?>"
|
||||||
|
class="hover:text-[#f62322] !decoration-transparent skip-ink transition-colors" |
||||||
|
href="tel:+7(800)302-11-85"><?php echo get_field('phones', 'options')['main_phone'] ?></a>
|
||||||
|
<a target="_blank" href="tel:<?php echo get_field('phones', 'options')['phone'] ?>"
|
||||||
|
class="hover:text-[#f62322] !decoration-transparent skip-ink transition-colors" |
||||||
|
href="tel:+7(911)098-59-77"><?php echo get_field('phones', 'options')['phone'] ?></a>
|
||||||
|
</div> |
||||||
|
<div class="flex flex-col gap-[10px]"> |
||||||
|
<p class="font-light text-[18px] text-[#828282]">Головной офис:</p> |
||||||
|
<div class="font-normal text-[23px] leading-[137%] text-[#3f3f3f]"> |
||||||
|
<?php echo get_field('address', 'options') ?> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="flex flex-col gap-[10px]"> |
||||||
|
<p class="font-light text-[18px] text-[#828282]">E-mail:</p> |
||||||
|
<a class="hover:text-[#f62322] !decoration-transparent skip-ink transition-colors font-normal text-[23px] leading-[137%] text-[#3f3f3f]" |
||||||
|
href="mailto:info@mylogistika2010.ru"><?php echo get_field('email', 'options') ?></a>
|
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&apikey=03df01cd-1a4b-4cb2-9ae5-d32d62590767" |
||||||
|
type="text/javascript"></script> |
||||||
|
</section> |
@ -0,0 +1,110 @@ |
|||||||
|
document.addEventListener('DOMContentLoaded', function() { |
||||||
|
document.querySelectorAll('.gallery-block').forEach(function(block) { |
||||||
|
const blockId = block.getAttribute('data-gallery-id'); |
||||||
|
initGalleryBlock(blockId); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
function initGalleryBlock(blockId) { |
||||||
|
const container = document.getElementById(blockId); |
||||||
|
if (!container) return; |
||||||
|
|
||||||
|
const swipers = {}; |
||||||
|
let lightbox; |
||||||
|
|
||||||
|
function initSwiper(tabId) { |
||||||
|
if (swipers[tabId]) { |
||||||
|
swipers[tabId].destroy(true, true); |
||||||
|
} |
||||||
|
|
||||||
|
swipers[tabId] = new Swiper(`#${blockId} #swiper-${tabId}`, { |
||||||
|
slidesPerView: 1.5, |
||||||
|
spaceBetween: 20, |
||||||
|
loop: true, |
||||||
|
centeredSlides: true, |
||||||
|
navigation: { |
||||||
|
nextEl: `#${blockId} #swiper-${tabId} .swiper-button-next`, |
||||||
|
prevEl: `#${blockId} #swiper-${tabId} .swiper-button-prev`, |
||||||
|
}, |
||||||
|
on: { |
||||||
|
slideChange: function() { |
||||||
|
updateThumbnails(tabId, this.realIndex); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function initLightbox(tabId) { |
||||||
|
if (lightbox) { |
||||||
|
lightbox.destroy(); |
||||||
|
} |
||||||
|
|
||||||
|
lightbox = GLightbox({ |
||||||
|
selector: `#${blockId} #tab-${tabId} .glightbox` |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function updateThumbnails(tabId, activeIndex) { |
||||||
|
const thumbnails = container.querySelectorAll(`#tab-${tabId} .thumbnail`); |
||||||
|
thumbnails.forEach((thumb, index) => { |
||||||
|
if (index === activeIndex) { |
||||||
|
thumb.classList.add('active', '!border-blue-500'); |
||||||
|
thumb.classList.remove('border-transparent'); |
||||||
|
} else { |
||||||
|
thumb.classList.remove('active', '!border-blue-500'); |
||||||
|
thumb.classList.add('border-transparent'); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
// Табы
|
||||||
|
container.querySelectorAll('.tab-button').forEach(button => { |
||||||
|
button.addEventListener('click', () => { |
||||||
|
const tabId = button.getAttribute('data-tab'); |
||||||
|
|
||||||
|
container.querySelectorAll('.tab-button').forEach(btn => { |
||||||
|
btn.classList.remove('active', 'underline'); |
||||||
|
btn.classList.add('bg-gray-100'); |
||||||
|
}); |
||||||
|
button.classList.add('active', 'underline'); |
||||||
|
button.classList.remove('bg-gray-100'); |
||||||
|
|
||||||
|
container.querySelectorAll('.tab-content').forEach(content => { |
||||||
|
content.classList.remove('block'); |
||||||
|
content.classList.add('hidden'); |
||||||
|
}); |
||||||
|
container.querySelector(`#tab-${tabId}`).classList.remove('hidden'); |
||||||
|
container.querySelector(`#tab-${tabId}`).classList.add('block'); |
||||||
|
|
||||||
|
setTimeout(() => { |
||||||
|
initSwiper(tabId); |
||||||
|
initLightbox(tabId); |
||||||
|
}, 100); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
// Thumbnails
|
||||||
|
container.addEventListener('click', (e) => { |
||||||
|
if (e.target.closest('.thumbnail')) { |
||||||
|
const thumbnail = e.target.closest('.thumbnail'); |
||||||
|
const index = parseInt(thumbnail.getAttribute('data-index')); |
||||||
|
const activeTab = container.querySelector('.tab-content.block'); |
||||||
|
const tabId = activeTab.id.replace('tab-', ''); |
||||||
|
|
||||||
|
if (swipers[tabId]) { |
||||||
|
swipers[tabId].slideToLoop(index); |
||||||
|
} |
||||||
|
|
||||||
|
updateThumbnails(tabId, index); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
const firstTab = container.querySelector('.tab-button.active'); |
||||||
|
if (firstTab) { |
||||||
|
const tabId = firstTab.getAttribute('data-tab'); |
||||||
|
setTimeout(() => { |
||||||
|
initSwiper(tabId); |
||||||
|
initLightbox(tabId); |
||||||
|
}, 100); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,136 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
// Моковые данные (потом заменить на ACF поля) |
||||||
|
$galleryData = [ |
||||||
|
'reception' => [ |
||||||
|
'title' => 'Зона ресепшен', |
||||||
|
'images' => [ |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/4a5568/ffffff?text=Ресепшен+1', |
||||||
|
'thumb' => 'https://placehold.co/150x100/4a5568/ffffff?text=Р1', |
||||||
|
'alt' => 'Ресепшен 1' |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/2d3748/ffffff?text=Ресепшен+2', |
||||||
|
'thumb' => 'https://placehold.co/150x100/2d3748/ffffff?text=Р2', |
||||||
|
'alt' => 'Ресепшен 2' |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/1a202c/ffffff?text=Ресепшен+3', |
||||||
|
'thumb' => 'https://placehold.co/150x100/1a202c/ffffff?text=Р3', |
||||||
|
'alt' => 'Ресепшен 3' |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/718096/ffffff?text=Ресепшен+4', |
||||||
|
'thumb' => 'https://placehold.co/150x100/718096/ffffff?text=Р4', |
||||||
|
'alt' => 'Ресепшен 4' |
||||||
|
] |
||||||
|
] |
||||||
|
], |
||||||
|
'gym' => [ |
||||||
|
'title' => 'Зона тренажерного зала', |
||||||
|
'images' => [ |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/dc2626/ffffff?text=Тренажёрный+1', |
||||||
|
'thumb' => 'https://placehold.co/150x100/dc2626/ffffff?text=Т1', |
||||||
|
'alt' => 'Тренажерный зал 1' |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/b91c1c/ffffff?text=Тренажёрный+2', |
||||||
|
'thumb' => 'https://placehold.co/150x100/b91c1c/ffffff?text=Т2', |
||||||
|
'alt' => 'Тренажерный зал 2' |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/991b1b/ffffff?text=Тренажёрный+3', |
||||||
|
'thumb' => 'https://placehold.co/150x100/991b1b/ffffff?text=Т3', |
||||||
|
'alt' => 'Тренажерный зал 3' |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/7f1d1d/ffffff?text=Тренажёрный+4', |
||||||
|
'thumb' => 'https://placehold.co/150x100/7f1d1d/ffffff?text=Т4', |
||||||
|
'alt' => 'Тренажерный зал 4' |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/ef4444/ffffff?text=Тренажёрный+5', |
||||||
|
'thumb' => 'https://placehold.co/150x100/ef4444/ffffff?text=Т5', |
||||||
|
'alt' => 'Тренажерный зал 5' |
||||||
|
] |
||||||
|
] |
||||||
|
], |
||||||
|
'group' => [ |
||||||
|
'title' => 'Залы для групповых тренировок', |
||||||
|
'images' => [ |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/059669/ffffff?text=Групповые+1', |
||||||
|
'thumb' => 'https://placehold.co/150x100/059669/ffffff?text=Г1', |
||||||
|
'alt' => 'Групповые тренировки 1' |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/047857/ffffff?text=Групповые+2', |
||||||
|
'thumb' => 'https://placehold.co/150x100/047857/ffffff?text=Г2', |
||||||
|
'alt' => 'Групповые тренировки 2' |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/065f46/ffffff?text=Групповые+3', |
||||||
|
'thumb' => 'https://placehold.co/150x100/065f46/ffffff?text=Г3', |
||||||
|
'alt' => 'Групповые тренировки 3' |
||||||
|
] |
||||||
|
] |
||||||
|
] |
||||||
|
]; |
||||||
|
|
||||||
|
$block_id = 'gallery-' . $block['id']; |
||||||
|
?> |
||||||
|
|
||||||
|
<div class="gallery-block" |
||||||
|
id="<?php echo $block_id; ?>"
|
||||||
|
data-gallery-id="<?php echo $block_id; ?>">
|
||||||
|
<div class="container mx-auto"> |
||||||
|
<h2 class="text-[32px] font-bold mb-[30px]">Галерея</h2> |
||||||
|
|
||||||
|
<div class="flex gap-[10px] mb-[30px]"> |
||||||
|
<?php foreach ($galleryData as $index => $tab): ?> |
||||||
|
<button class="tab-button px-[24px] py-[12px] border-0 rounded-[25px] cursor-pointer transition-all <?php echo $index === 'reception' ? 'active underline' : ''; ?>"
|
||||||
|
data-tab="<?php echo $index; ?>">
|
||||||
|
<?php echo esc_html($tab['title']); ?> |
||||||
|
</button> |
||||||
|
<?php endforeach; ?> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<?php foreach ($galleryData as $tab_id => $tab_data): ?> |
||||||
|
<div class="tab-content <?php echo $tab_id === 'reception' ? 'block' : 'hidden'; ?>"
|
||||||
|
id="tab-<?php echo $tab_id; ?>">
|
||||||
|
|
||||||
|
<div class="swiper gallery-swiper mb-[20px] h-[440px]" id="swiper-<?php echo $tab_id; ?>">
|
||||||
|
<div class="swiper-wrapper"> |
||||||
|
<?php foreach ($tab_data['images'] as $image): ?> |
||||||
|
<div class="swiper-slide cursor-pointer min-h-[440px]"> |
||||||
|
<a href="<?php echo esc_url($image['src']); ?>"
|
||||||
|
class="glightbox block w-full h-full" |
||||||
|
data-gallery="gallery-<?php echo $tab_id; ?>">
|
||||||
|
<img src="<?php echo esc_url($image['src']); ?>"
|
||||||
|
alt="<?php echo esc_attr($image['alt']); ?>"
|
||||||
|
class="w-full h-full object-cover"> |
||||||
|
</a> |
||||||
|
</div> |
||||||
|
<?php endforeach; ?> |
||||||
|
</div> |
||||||
|
<div class="swiper-button-next"></div> |
||||||
|
<div class="swiper-button-prev"></div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="flex gap-[8px] overflow-x-auto"> |
||||||
|
<?php foreach ($tab_data['images'] as $thumb_index => $image): ?> |
||||||
|
<div class="thumbnail flex-shrink-0 w-[80px] h-[60px] rounded-[5px] overflow-hidden cursor-pointer border-2 border-transparent <?php echo $thumb_index === 0 ? 'active !border-blue-500' : ''; ?>"
|
||||||
|
data-index="<?php echo $thumb_index; ?>">
|
||||||
|
<img src="<?php echo esc_url($image['thumb']); ?>"
|
||||||
|
alt="<?php echo esc_attr($image['alt']); ?>"
|
||||||
|
class="w-full h-full object-cover"> |
||||||
|
</div> |
||||||
|
<?php endforeach; ?> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<?php endforeach; ?> |
||||||
|
</div> |
||||||
|
|
@ -0,0 +1,26 @@ |
|||||||
|
.inverted-radius-wrapper:before { |
||||||
|
content: ''; |
||||||
|
display: block; |
||||||
|
width: 40px; |
||||||
|
height: 25px; |
||||||
|
background-color: transparent; |
||||||
|
border-radius: 0 0 0 25px; |
||||||
|
box-shadow: calc(15px * -0.5) calc(15px * 0.5) 0 0 #f9f9f9; |
||||||
|
position: absolute; |
||||||
|
z-index: -1; |
||||||
|
left: -1px; |
||||||
|
bottom: 100%; |
||||||
|
} |
||||||
|
.inverted-radius-wrapper:after { |
||||||
|
content: ''; |
||||||
|
display: block; |
||||||
|
width: 40px; |
||||||
|
height: 25px; |
||||||
|
background-color: transparent; |
||||||
|
border-radius: 0 0 0 25px; |
||||||
|
box-shadow: calc(15px * -0.5) calc(15px * 0.5) 0 0 #f9f9f9; |
||||||
|
position: absolute; |
||||||
|
z-index: -1; |
||||||
|
left: calc(100% - 1px); |
||||||
|
bottom: 0; |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
document.addEventListener('DOMContentLoaded', function() { |
||||||
|
const heroBlocks = document.querySelectorAll('.hero-block'); |
||||||
|
|
||||||
|
heroBlocks.forEach(function(block) { |
||||||
|
const swiperContainer = block.querySelector('.swiper'); |
||||||
|
|
||||||
|
if (!swiperContainer) return; |
||||||
|
|
||||||
|
const swiper = new Swiper(swiperContainer, { |
||||||
|
slidesPerView: 1, |
||||||
|
loop: true, |
||||||
|
grabCursor: true, |
||||||
|
on: { |
||||||
|
slideChange: function () { |
||||||
|
const realIndex = this.realIndex; |
||||||
|
const paginationItems = block.querySelectorAll('.pagination-item'); |
||||||
|
|
||||||
|
paginationItems.forEach((item, index) => { |
||||||
|
const line = item.querySelector('.pagination-line'); |
||||||
|
const text = item.querySelector('.slide-text'); |
||||||
|
|
||||||
|
if (index === realIndex) { |
||||||
|
item.className = 'pagination-item flex-[2] cursor-pointer transition-all '; |
||||||
|
line.className = 'pagination-line bg-[#222] h-[2px] rounded-[30px] transition-colors '; |
||||||
|
text.className = 'slide-text mt-[10px] text-[14px] text-[#222] font-[600] opacity-100 transition-opacity '; |
||||||
|
} else { |
||||||
|
item.className = 'pagination-item flex-1 cursor-pointer transition-all '; |
||||||
|
line.className = 'pagination-line bg-[#e0e0e0] h-[2px] rounded-[30px] transition-colors '; |
||||||
|
text.className = 'slide-text mt-[10px] text-[14px] text-[#222] font-[600] opacity-0 transition-opacity '; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// Навигация
|
||||||
|
block.querySelector('.custom-prev')?.addEventListener('click', () => swiper.slidePrev()); |
||||||
|
block.querySelector('.custom-next')?.addEventListener('click', () => swiper.slideNext()); |
||||||
|
|
||||||
|
// Пагинация
|
||||||
|
block.querySelectorAll('.pagination-item').forEach((item, index) => { |
||||||
|
item.addEventListener('click', () => swiper.slideToLoop(index)); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,170 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Заглавный блок с ACF полями |
||||||
|
*/ |
||||||
|
|
||||||
|
$id = 'hero-' . $block['id']; |
||||||
|
if (!empty($block['anchor'])) { |
||||||
|
$id = $block['anchor']; |
||||||
|
} |
||||||
|
|
||||||
|
$className = 'hero-block'; |
||||||
|
if (!empty($block['className'])) { |
||||||
|
$className .= ' ' . $block['className']; |
||||||
|
} |
||||||
|
if (!empty($block['align'])) { |
||||||
|
$className .= ' align' . $block['align']; |
||||||
|
} |
||||||
|
|
||||||
|
// Получаем данные из ACF полей |
||||||
|
$slider_data = get_field('slider') ?: []; |
||||||
|
$text_data = get_field('text') ?: []; |
||||||
|
|
||||||
|
|
||||||
|
$heading = $text_data['heading'] ?? ''; |
||||||
|
$heading_text = $text_data['heading_text'] ?? ''; |
||||||
|
$address = $text_data['adress'] ?? ''; |
||||||
|
$address_extra = $text_data['adress_extra'] ?? ''; |
||||||
|
|
||||||
|
$slides = []; |
||||||
|
if (!empty($slider_data) && is_array($slider_data)) { |
||||||
|
foreach ($slider_data as $index => $slide) { |
||||||
|
$image_url = ''; |
||||||
|
if (!empty($slide['image']) && is_array($slide['image'])) { |
||||||
|
$image_url = $slide['image']['url'] ?? ''; |
||||||
|
} |
||||||
|
|
||||||
|
$slides[] = [ |
||||||
|
'number' => sprintf('%02d', $index + 1), |
||||||
|
'title' => $slide['text'] ?? '', |
||||||
|
'img' => $image_url |
||||||
|
]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
?> |
||||||
|
|
||||||
|
<section class="container mx-auto hero-block"> |
||||||
|
<div class="flex justify-between gap-[24px]"> |
||||||
|
<div class="flex flex-col w-full mt-[26px]"> |
||||||
|
<?php display_icon('logo_fitness') ?> |
||||||
|
|
||||||
|
<h1 class="font-[500] leading-[110%] text-[48px] mt-[20px]"> |
||||||
|
<?php if (!empty($heading)): ?> |
||||||
|
<?php echo wp_kses_post($heading); ?> |
||||||
|
<?php endif; ?> |
||||||
|
</h1> |
||||||
|
|
||||||
|
<p class="text-[24px] font-[500] mt-[20px]"> |
||||||
|
<?php echo !empty($heading_text) ? esc_html($heading_text) : 'Зал для тех, кто ценит комфорт и сервис'; ?> |
||||||
|
</p> |
||||||
|
|
||||||
|
<div class="flex gap-[12px] mt-[40px]"> |
||||||
|
<a class="!no-underline text-[#f8f8f8] text-[18px] font-[600] justify-center h-[75px] w-full max-w-[281px] rounded-[90px] flex items-center gap-[12px] red-gradient-hover" |
||||||
|
href="#"> |
||||||
|
Пробная тренировка |
||||||
|
<?php display_icon('button_arrow_up') ?> |
||||||
|
</a> |
||||||
|
<a class="!no-underline text-[#f8f8f8] text-[18px] font-[600] justify-center h-[75px] w-full max-w-[210px] rounded-[90px] flex items-center gap-[12px] grey-gradient-hover" |
||||||
|
href="/цены">Смотреть цены</a> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="flex items-center gap-[12px] mt-[50px]"> |
||||||
|
<?php display_icon('location') ?> |
||||||
|
<div> |
||||||
|
<p> |
||||||
|
<b><?php echo !empty($address) ? esc_html($address) : 'Красноармейская, 120 — 2ой этаж'; ?></b>
|
||||||
|
</p> |
||||||
|
<p> |
||||||
|
<?php echo !empty($address_extra) ? esc_html($address_extra) : 'Главный вход со стороны ул. Косарева'; ?> |
||||||
|
</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="w-full max-w-[648px] h-[575px] relative"> |
||||||
|
<div class="swiper rounded-[25px] w-full h-full"> |
||||||
|
<div class="swiper-wrapper"> |
||||||
|
<?php foreach ($slides as $index => $slide): ?> |
||||||
|
<div class="swiper-slide [&>_img]:max-w-none"> |
||||||
|
<?php if (!empty($slide['img'])): ?> |
||||||
|
<img src="<?php echo esc_url($slide['img']); ?>" alt="<?php echo esc_attr($slide['title']); ?>">
|
||||||
|
<?php endif; ?> |
||||||
|
</div> |
||||||
|
<?php endforeach; ?> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="inverted-radius-wrapper absolute z-[1] pt-[15px] pr-[15px] rounded-[25px] rounded-bl-none rounded-br-none rounded-tl-none flex items-center gap-[4px] bg-[#f9f9f9] left-0 bottom-0"> |
||||||
|
<button class="group custom-prev cursor-pointer"> |
||||||
|
<?php display_icon('slider-prev') ?> |
||||||
|
</button> |
||||||
|
<button class="group custom-next cursor-pointer"> |
||||||
|
<?php display_icon('slider-next') ?> |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="flex gap-[24px] mt-[44px]"> |
||||||
|
<?php foreach ($slides as $index => $slide): ?> |
||||||
|
<div class="pagination-item <?php echo $index === 0 ? 'flex-[2]' : 'flex-1' ?> cursor-pointer transition-all"
|
||||||
|
data-slide="<?php echo $index ?>">
|
||||||
|
<div class="pagination-line <?php echo $index === 0 ? 'bg-[#222]' : 'bg-gray-[#e0e0e0]' ?> h-[2px] rounded-[30px] transition-colors"></div>
|
||||||
|
<div class="slide-text <?php echo $index === 0 ? 'opacity-100' : 'opacity-0' ?> transition-opacity">
|
||||||
|
<span class="slide-number"><?php echo esc_html($slide['number']); ?>.</span>
|
||||||
|
<span class="slide-title"><?php echo esc_html($slide['title']); ?></span>
|
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<?php endforeach; ?> |
||||||
|
</div> |
||||||
|
</section> |
||||||
|
|
||||||
|
<?php if (is_admin()): ?> |
||||||
|
<script> |
||||||
|
|
||||||
|
|
||||||
|
function initAdminSwiper() { |
||||||
|
const selectors = [ |
||||||
|
'#hero-<?php echo $block['id']; ?> .swiper',
|
||||||
|
'[data-block="<?php echo $block['id']; ?>"] .swiper',
|
||||||
|
'.hero-block[data-slides] .swiper', |
||||||
|
'.swiper' |
||||||
|
]; |
||||||
|
|
||||||
|
let swiperContainer = null; |
||||||
|
|
||||||
|
for (let selector of selectors) { |
||||||
|
swiperContainer = document.querySelector(selector); |
||||||
|
console.log(`🔍 Checking selector "${selector}":`, swiperContainer); |
||||||
|
if (swiperContainer) break; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
try { |
||||||
|
const swiper = new Swiper(swiperContainer, { |
||||||
|
slidesPerView: 1, |
||||||
|
loop: true, |
||||||
|
autoplay: { |
||||||
|
delay: 4000, |
||||||
|
disableOnInteraction: false, |
||||||
|
}, |
||||||
|
navigation: { |
||||||
|
nextEl: '.custom-next', |
||||||
|
prevEl: '.custom-prev', |
||||||
|
} |
||||||
|
}); |
||||||
|
} catch (error) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
if (typeof wp !== 'undefined' && wp.domReady) { |
||||||
|
wp.domReady(function() { |
||||||
|
setTimeout(initAdminSwiper, 300); |
||||||
|
}); |
||||||
|
} |
||||||
|
</script> |
||||||
|
<?php endif; ?> |
@ -0,0 +1,104 @@ |
|||||||
|
document.addEventListener('DOMContentLoaded', function() { |
||||||
|
document.querySelectorAll('.reviews-block').forEach(function(block) { |
||||||
|
const blockId = block.getAttribute('data-reviews-id'); |
||||||
|
initReviewsBlock(blockId); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
function initReviewsBlock(blockId) { |
||||||
|
const container = document.getElementById(blockId); |
||||||
|
if (!container) return; |
||||||
|
|
||||||
|
const swipers = {}; |
||||||
|
let lightbox; |
||||||
|
|
||||||
|
function initSwiper(tabId) { |
||||||
|
if (swipers[tabId]) { |
||||||
|
swipers[tabId].destroy(true, true); |
||||||
|
} |
||||||
|
|
||||||
|
swipers[tabId] = new Swiper(`#${blockId} #swiper-${tabId}`, { |
||||||
|
slidesPerView: 3, |
||||||
|
spaceBetween: 20, |
||||||
|
loop: true, |
||||||
|
centeredSlides: true, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function initLightbox(tabId) { |
||||||
|
if (lightbox) { |
||||||
|
lightbox.destroy(); |
||||||
|
} |
||||||
|
|
||||||
|
lightbox = GLightbox({ |
||||||
|
selector: `#${blockId} #tab-${tabId} .glightbox`, |
||||||
|
touchNavigation: true, |
||||||
|
loop: true, |
||||||
|
autoplayVideos: false, |
||||||
|
videosWidth: '90vw', |
||||||
|
videosHeight: '80vh', |
||||||
|
plyr: { |
||||||
|
css: 'https://cdn.plyr.io/3.7.8/plyr.css', |
||||||
|
js: 'https://cdn.plyr.io/3.7.8/plyr.js', |
||||||
|
config: { |
||||||
|
ratio: '16:9', |
||||||
|
fullscreen: { enabled: true, fallback: true, iosNative: true }, |
||||||
|
controls: [ |
||||||
|
'play-large', |
||||||
|
'play', |
||||||
|
'progress', |
||||||
|
'current-time', |
||||||
|
'duration', |
||||||
|
'mute', |
||||||
|
'volume', |
||||||
|
'fullscreen' |
||||||
|
] |
||||||
|
} |
||||||
|
}, |
||||||
|
onOpen: () => { |
||||||
|
console.log('видео открыли'); |
||||||
|
}, |
||||||
|
onClose: () => { |
||||||
|
console.log('видео закрыли'); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// Табы
|
||||||
|
container.querySelectorAll('.tab-button').forEach(button => { |
||||||
|
button.addEventListener('click', () => { |
||||||
|
const tabId = button.getAttribute('data-tab'); |
||||||
|
|
||||||
|
container.querySelectorAll('.tab-button').forEach(btn => { |
||||||
|
btn.classList.remove('active', 'underline'); |
||||||
|
btn.classList.add('bg-gray-100'); |
||||||
|
}); |
||||||
|
button.classList.add('active', 'underline'); |
||||||
|
button.classList.remove('bg-gray-100'); |
||||||
|
|
||||||
|
container.querySelectorAll('.tab-content').forEach(content => { |
||||||
|
content.classList.remove('block'); |
||||||
|
content.classList.add('hidden'); |
||||||
|
}); |
||||||
|
container.querySelector(`#tab-${tabId}`).classList.remove('hidden'); |
||||||
|
container.querySelector(`#tab-${tabId}`).classList.add('block'); |
||||||
|
|
||||||
|
setTimeout(() => { |
||||||
|
initSwiper(tabId); |
||||||
|
initLightbox(tabId); |
||||||
|
}, 100); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const firstTab = container.querySelector('.tab-button.active'); |
||||||
|
if (firstTab) { |
||||||
|
const tabId = firstTab.getAttribute('data-tab'); |
||||||
|
setTimeout(() => { |
||||||
|
initSwiper(tabId); |
||||||
|
initLightbox(tabId); |
||||||
|
}, 100); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,136 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
// Моковые данные отзывов (потом заменить на ACF поля) |
||||||
|
$reviewsData = [ |
||||||
|
'google' => [ |
||||||
|
'title' => 'Отзывы Google', |
||||||
|
'reviews' => [ |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/4f46e5/ffffff?text=Отзыв+Google+1', |
||||||
|
'thumb' => 'https://placehold.co/300x200/4f46e5/ffffff?text=G1', |
||||||
|
'alt' => 'Отзыв Google 1' |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/7c3aed/ffffff?text=Отзыв+Google+2', |
||||||
|
'thumb' => 'https://placehold.co/300x200/7c3aed/ffffff?text=G2', |
||||||
|
'alt' => 'Отзыв Google 2' |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/8b5cf6/ffffff?text=Отзыв+Google+3', |
||||||
|
'thumb' => 'https://placehold.co/300x200/8b5cf6/ffffff?text=G3', |
||||||
|
'alt' => 'Отзыв Google 3' |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/a855f7/ffffff?text=Отзыв+Google+4', |
||||||
|
'thumb' => 'https://placehold.co/300x200/a855f7/ffffff?text=G4', |
||||||
|
'alt' => 'Отзыв Google 4' |
||||||
|
] |
||||||
|
] |
||||||
|
], |
||||||
|
'yandex' => [ |
||||||
|
'title' => 'Отзывы Яндекс', |
||||||
|
'reviews' => [ |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/f59e0b/ffffff?text=Отзыв+Яндекс+1', |
||||||
|
'thumb' => 'https://placehold.co/300x200/f59e0b/ffffff?text=Я1', |
||||||
|
'alt' => 'Отзыв Яндекс 1' |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/d97706/ffffff?text=Отзыв+Яндекс+2', |
||||||
|
'thumb' => 'https://placehold.co/300x200/d97706/ffffff?text=Я2', |
||||||
|
'alt' => 'Отзыв Яндекс 2' |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => 'https://placehold.co/800x600/b45309/ffffff?text=Отзыв+Яндекс+3', |
||||||
|
'thumb' => 'https://placehold.co/300x200/b45309/ffffff?text=Я3', |
||||||
|
'alt' => 'Отзыв Яндекс 3' |
||||||
|
] |
||||||
|
] |
||||||
|
], |
||||||
|
'video' => [ |
||||||
|
'title' => 'Видеоотзывы', |
||||||
|
'reviews' => [ |
||||||
|
[ |
||||||
|
'src' => '/path/to/video1.mp4', // Путь к видеофайлу |
||||||
|
'thumb' => 'https://placehold.co/300x200/b45309/ffffff?text=В1', |
||||||
|
'alt' => 'Видеоотзыв 1', |
||||||
|
'type' => 'video', |
||||||
|
'video_type' => 'mp4' // Тип видео |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => '/path/to/video2.webm', |
||||||
|
'thumb' => 'https://placehold.co/300x200/b45309/ffffff?text=В2', |
||||||
|
'alt' => 'Видеоотзыв 2', |
||||||
|
'type' => 'video', |
||||||
|
'video_type' => 'webm' |
||||||
|
], |
||||||
|
[ |
||||||
|
'src' => '/path/to/video3.mov', |
||||||
|
'thumb' => 'https://placehold.co/300x200/b45309/ffffff?text=В3', |
||||||
|
'alt' => 'Видеоотзыв 3', |
||||||
|
'type' => 'video', |
||||||
|
'video_type' => 'mov' |
||||||
|
] |
||||||
|
] |
||||||
|
] |
||||||
|
]; |
||||||
|
|
||||||
|
$block_id = 'reviews-' . $block['id']; |
||||||
|
?> |
||||||
|
|
||||||
|
<div class="reviews-block container mx-auto" |
||||||
|
id="<?php echo $block_id; ?>"
|
||||||
|
data-reviews-id="<?php echo $block_id; ?>">
|
||||||
|
<div> |
||||||
|
<h2 class="text-[32px] font-bold mb-[30px]">Отзывы клиентов</h2> |
||||||
|
|
||||||
|
<!-- Табы --> |
||||||
|
<div class="flex gap-[10px] mb-[30px]"> |
||||||
|
<?php foreach ($reviewsData as $index => $tab): ?> |
||||||
|
<button class="tab-button px-[24px] py-[12px] border-0 rounded-[25px] cursor-pointer transition-all <?php echo $index === 'google' ? 'active underline' : ''; ?>"
|
||||||
|
data-tab="<?php echo $index; ?>">
|
||||||
|
<?php echo esc_html($tab['title']); ?> |
||||||
|
</button> |
||||||
|
<?php endforeach; ?> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- Контент табов --> |
||||||
|
<?php foreach ($reviewsData as $tab_id => $tab_data): ?> |
||||||
|
<div class="tab-content <?php echo $tab_id === 'google' ? 'block' : 'hidden'; ?>"
|
||||||
|
id="tab-<?php echo $tab_id; ?>">
|
||||||
|
|
||||||
|
<!-- Swiper для отзывов --> |
||||||
|
<div class="swiper reviews-swiper mb-[20px] h-[440px]" id="swiper-<?php echo $tab_id; ?>">
|
||||||
|
<div class="swiper-wrapper"> |
||||||
|
<?php foreach ($tab_data['reviews'] as $review): ?> |
||||||
|
<div class="swiper-slide cursor-pointer min-h-[440px]"> |
||||||
|
<a href="<?php echo esc_url($review['src']); ?>"
|
||||||
|
class="glightbox block w-full h-full relative" |
||||||
|
data-gallery="reviews-<?php echo $tab_id; ?>"
|
||||||
|
<?php if (isset($review['type']) && $review['type'] === 'video'): ?> |
||||||
|
data-type="video" |
||||||
|
data-description="<?php echo esc_attr($review['alt']); ?>"
|
||||||
|
<?php endif; ?>>
|
||||||
|
<img src="<?php echo esc_url($review['thumb']); ?>"
|
||||||
|
alt="<?php echo esc_attr($review['alt']); ?>"
|
||||||
|
class="w-full h-full object-cover rounded-lg"> |
||||||
|
<?php if (isset($review['type']) && $review['type'] === 'video'): ?> |
||||||
|
<!-- Иконка воспроизведения для видео --> |
||||||
|
<div class="absolute inset-0 flex items-center justify-center bg-[rgba(0,0,0,0.5)] hover:bg-[rgba(0,0,0,0.1)] transition-all"> |
||||||
|
<div class="w-[60px] h-[60px] bg-white bg-opacity-90 rounded-full flex items-center justify-center shadow-lg"> |
||||||
|
<svg class="w-[24px] h-[24px]" fill="currentColor" viewBox="0 0 20 20"> |
||||||
|
<path d="M8 5v10l8-5-8-5z"/> |
||||||
|
</svg> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<?php endif; ?> |
||||||
|
</a> |
||||||
|
</div> |
||||||
|
<?php endforeach; ?> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
</div> |
||||||
|
<?php endforeach; ?> |
||||||
|
</div> |
@ -0,0 +1,25 @@ |
|||||||
|
<?php |
||||||
|
?> |
||||||
|
<div class="bg-black text-white"> |
||||||
|
<div class="mx-auto container"> |
||||||
|
<div> |
||||||
|
Время работы: |
||||||
|
<?php |
||||||
|
|
||||||
|
$work_time = get_field('work_time', 'option'); |
||||||
|
echo $work_time[get_current_room()]; |
||||||
|
?> |
||||||
|
</div> |
||||||
|
<div class="flex w-full justify-between"> |
||||||
|
<div>© 2025 fakelgym.ru. Все права защищены.</div> |
||||||
|
<div><a href="#">Политика Конфиденциальности</a></div> |
||||||
|
<div> |
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="13" viewBox="0 0 22 13" fill="none"> |
||||||
|
<path |
||||||
|
d="M20.504 12.3814H18.222C17.359 12.3814 17.099 11.6824 15.552 10.1344C14.2 8.83144 13.629 8.66943 13.287 8.66943C12.814 8.66943 12.685 8.79943 12.685 9.45043V11.5024C12.685 12.0574 12.505 12.3824 11.055 12.3824C9.64829 12.2879 8.28416 11.8606 7.07497 11.1356C5.86578 10.4106 4.84612 9.4087 4.1 8.21243C2.32901 6.00706 1.09641 3.41928 0.5 0.654435C0.5 0.312435 0.63 0.00243485 1.282 0.00243485H3.562C4.148 0.00243485 4.359 0.263435 4.589 0.866435C5.696 4.12443 7.585 6.95844 8.352 6.95844C8.646 6.95844 8.774 6.82843 8.774 6.09544V2.73944C8.677 1.20844 7.864 1.07944 7.864 0.525435C7.87428 0.379276 7.94114 0.242883 8.05037 0.145228C8.15961 0.0475726 8.30261 -0.00365196 8.449 0.00243485H12.033C12.523 0.00243485 12.685 0.246435 12.685 0.832435V5.36244C12.685 5.85144 12.895 6.01343 13.043 6.01343C13.337 6.01343 13.563 5.85143 14.102 5.31343C15.2569 3.90409 16.2008 2.33435 16.904 0.653435C16.9756 0.451399 17.1116 0.278427 17.2909 0.161024C17.4703 0.0436209 17.6832 -0.0117363 17.897 0.00343477H20.178C20.862 0.00343477 21.007 0.345435 20.862 0.833435C20.0321 2.69173 19.0056 4.45579 17.8 6.09544C17.554 6.47044 17.456 6.66543 17.8 7.10543C18.026 7.44743 18.826 8.11543 19.363 8.75043C20.145 9.53043 20.794 10.4324 21.285 11.4204C21.481 12.0564 21.155 12.3814 20.504 12.3814Z" |
||||||
|
fill="white"/> |
||||||
|
</svg> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,158 @@ |
|||||||
|
<?php |
||||||
|
function register_acf_blocks() { |
||||||
|
if (function_exists('acf_register_block_type')) { |
||||||
|
|
||||||
|
acf_register_block_type(array( |
||||||
|
'name' => 'hero-block', |
||||||
|
'title' => __('Hero Block'), |
||||||
|
'description' => __('Заглавный блок со слайдером'), |
||||||
|
'render_template' => 'template-parts/la-components/blocks/hero-block/hero-block.php', |
||||||
|
'category' => 'theme-blocks', |
||||||
|
'icon' => 'cover-image', |
||||||
|
'keywords' => array('hero', 'banner', 'заголовок', 'слайдер'), |
||||||
|
'supports' => array( |
||||||
|
'align' => array('wide', 'full'), |
||||||
|
'anchor' => true, |
||||||
|
'customClassName' => true, |
||||||
|
), |
||||||
|
'enqueue_assets' => function() { |
||||||
|
wp_enqueue_script( |
||||||
|
'hero-block-js', |
||||||
|
get_template_directory_uri() . '/template-parts/la-components/blocks/hero-block/hero-block.js', |
||||||
|
['jquery'], |
||||||
|
'1.0.0', |
||||||
|
true |
||||||
|
); |
||||||
|
|
||||||
|
wp_enqueue_style( |
||||||
|
'hero-block-css', |
||||||
|
get_template_directory_uri() . '/template-parts/la-components/blocks/hero-block/hero-block.css', |
||||||
|
[], |
||||||
|
'1.0.0' |
||||||
|
); |
||||||
|
} |
||||||
|
)); |
||||||
|
|
||||||
|
acf_register_block_type(array( |
||||||
|
'name' => 'contacts-block', |
||||||
|
'title' => __('Блок с контактами'), |
||||||
|
'description' => __('Блок с контактами>'), |
||||||
|
'render_template' => 'template-parts/la-components/blocks/contacts-block/contacts-block.php', |
||||||
|
'category' => 'theme-blocks', |
||||||
|
'icon' => 'cover-image', |
||||||
|
'keywords' => array('контакты', 'contacts', 'адрес'), |
||||||
|
'supports' => array( |
||||||
|
'align' => array('wide', 'full'), |
||||||
|
'anchor' => true, |
||||||
|
'customClassName' => true, |
||||||
|
), |
||||||
|
'enqueue_assets' => function() { |
||||||
|
wp_enqueue_script( |
||||||
|
'contacts-block-js', |
||||||
|
get_template_directory_uri() . '/template-parts/la-components/blocks/contacts-block/contacts-block.js', |
||||||
|
['jquery'], |
||||||
|
'1.0.0', |
||||||
|
true |
||||||
|
); |
||||||
|
} |
||||||
|
)); |
||||||
|
|
||||||
|
|
||||||
|
acf_register_block_type(array( |
||||||
|
'name' => 'club-cards-block', |
||||||
|
'title' => __('Блок с клубными картами'), |
||||||
|
'description' => __('Блок с клубными картами для текущего языка'), |
||||||
|
'render_template' => 'template-parts/la-components/blocks/club-cards-block/club-cards-block.php', |
||||||
|
'category' => 'theme-blocks', |
||||||
|
'icon' => 'id-alt', |
||||||
|
'keywords' => array('карты', 'клуб', 'cards', 'club'), |
||||||
|
'supports' => array( |
||||||
|
'align' => array('wide', 'full'), |
||||||
|
'anchor' => true, |
||||||
|
'customClassName' => true, |
||||||
|
), |
||||||
|
)); |
||||||
|
|
||||||
|
acf_register_block_type(array( |
||||||
|
'name' => 'reviews-block', |
||||||
|
'title' => __('Блок с отзывами'), |
||||||
|
'description' => __('Блок с отзывами'), |
||||||
|
'render_template' => 'template-parts/la-components/blocks/reviews-block/reviews-block.php', |
||||||
|
'category' => 'theme-blocks', |
||||||
|
'icon' => 'cover-image', |
||||||
|
'keywords' => array('отзывы', 'видеоотзывы', 'reviews'), |
||||||
|
'supports' => array( |
||||||
|
'align' => array('wide', 'full'), |
||||||
|
'anchor' => true, |
||||||
|
'customClassName' => true, |
||||||
|
), |
||||||
|
'enqueue_assets' => function() { |
||||||
|
wp_enqueue_script( |
||||||
|
'reviews-block-js', |
||||||
|
get_template_directory_uri() . '/template-parts/la-components/blocks/reviews-block/reviews-block.js', |
||||||
|
['jquery'], |
||||||
|
'1.0.0', |
||||||
|
true |
||||||
|
); |
||||||
|
} |
||||||
|
)); |
||||||
|
|
||||||
|
|
||||||
|
acf_register_block_type(array( |
||||||
|
'name' => 'gallery-tabs', |
||||||
|
'title' => __('Галерея с табами'), |
||||||
|
'description' => __('Галерея с табами, слайдером и лайтбоксом'), |
||||||
|
'render_template' => 'template-parts/la-components/blocks/gallery-tabs/gallery-tabs.php', |
||||||
|
'category' => 'theme-blocks', |
||||||
|
'icon' => 'images-alt2', |
||||||
|
'keywords' => array('gallery', 'tabs', 'slider', 'галерея', 'слайдер'), |
||||||
|
'supports' => array( |
||||||
|
'align' => array('wide', 'full'), |
||||||
|
'anchor' => true, |
||||||
|
'customClassName' => true, |
||||||
|
), |
||||||
|
'enqueue_assets' => function() { |
||||||
|
|
||||||
|
wp_enqueue_style( |
||||||
|
'glightbox-css', |
||||||
|
'https://cdnjs.cloudflare.com/ajax/libs/glightbox/3.2.0/css/glightbox.min.css', |
||||||
|
[], |
||||||
|
'3.2.0' |
||||||
|
); |
||||||
|
|
||||||
|
wp_enqueue_script( |
||||||
|
'glightbox-js', |
||||||
|
'https://cdnjs.cloudflare.com/ajax/libs/glightbox/3.2.0/js/glightbox.min.js', |
||||||
|
[], |
||||||
|
'3.2.0', |
||||||
|
true |
||||||
|
); |
||||||
|
|
||||||
|
|
||||||
|
wp_enqueue_script( |
||||||
|
'gallery-tabs-js', |
||||||
|
get_template_directory_uri() . '/template-parts/la-components/blocks/gallery-tabs/gallery-tabs.js', |
||||||
|
['swiper-js', 'glightbox-js'], |
||||||
|
'1.0.0', |
||||||
|
true |
||||||
|
); |
||||||
|
} |
||||||
|
)); |
||||||
|
} |
||||||
|
} |
||||||
|
add_action('acf/init', 'register_acf_blocks'); |
||||||
|
|
||||||
|
|
||||||
|
function register_custom_block_category($categories, $post) { |
||||||
|
return array_merge( |
||||||
|
$categories, |
||||||
|
array( |
||||||
|
array( |
||||||
|
'slug' => 'theme-blocks', |
||||||
|
'title' => __('Блоки темы'), |
||||||
|
'icon' => 'admin-customizer', |
||||||
|
), |
||||||
|
) |
||||||
|
); |
||||||
|
} |
||||||
|
add_filter('block_categories_all', 'register_custom_block_category', 10, 2); |
@ -0,0 +1,58 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
function enqueue_theme_scripts() { |
||||||
|
wp_enqueue_script( |
||||||
|
'modals-js', |
||||||
|
get_template_directory_uri() . '/template-parts/la-components/js/modals.js', |
||||||
|
array('jquery'), |
||||||
|
'1.0.0', |
||||||
|
true |
||||||
|
); |
||||||
|
} |
||||||
|
add_action('wp_enqueue_scripts', 'enqueue_theme_scripts'); |
||||||
|
|
||||||
|
// Вывод всех модалок в футере |
||||||
|
function modal_system_container() { |
||||||
|
// Получаем список всех модалок |
||||||
|
$modals_dir = get_template_directory() . '/template-parts/la-components/modals/'; |
||||||
|
$modals = array(); |
||||||
|
|
||||||
|
if (is_dir($modals_dir)) { |
||||||
|
$files = scandir($modals_dir); |
||||||
|
foreach ($files as $file) { |
||||||
|
if (preg_match('/^modal-(.+)\.php$/', $file, $matches)) { |
||||||
|
$modals[] = $matches[1]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// общий контейнер |
||||||
|
?> |
||||||
|
<div id="modal-overlay" class="fixed inset-0 bg-[rgba(0,0,0,0.5)] backdrop-blur-sm z-50 flex items-center justify-center p-4 opacity-0 invisible transition-all duration-300"> |
||||||
|
<div class="bg-white rounded-lg shadow-2xl max-w-2xl w-full max-h-[90vh] relative transform scale-90 transition-transform duration-300 overflow-hidden"> |
||||||
|
|
||||||
|
<button id="modal-close" class="absolute top-4 right-4 z-10 w-8 h-8 flex items-center justify-center rounded-full hover:bg-gray-100 transition-colors text-gray-500 hover:text-gray-700"> |
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path> |
||||||
|
</svg> |
||||||
|
</button> |
||||||
|
|
||||||
|
<!-- Контейнер для контента модалок --> |
||||||
|
<div id="modal-content" class="overflow-y-auto max-h-[90vh]"> |
||||||
|
|
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
|
||||||
|
<div id="modal-templates" class="hidden"> |
||||||
|
<?php foreach ($modals as $modal_name): ?> |
||||||
|
<div id="modal-template-<?php echo esc_attr($modal_name); ?>" class="modal-template">
|
||||||
|
<?php get_template_part('template-parts/la-components/modals/modal', $modal_name); ?> |
||||||
|
</div> |
||||||
|
<?php endforeach; ?> |
||||||
|
</div> |
||||||
|
<?php |
||||||
|
} |
||||||
|
add_action('wp_footer', 'modal_system_container'); |
||||||
|
?> |
@ -0,0 +1,201 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* Переключает язык (регионы) необходим плагин Polylang |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
|
||||||
|
// Проверяем существование функций Polylang |
||||||
|
if (!function_exists('pll_languages_list') || !function_exists('pll_current_language')) { |
||||||
|
return; |
||||||
|
} |
||||||
|
?> |
||||||
|
|
||||||
|
<style> |
||||||
|
.pl-lang-switcher-container { |
||||||
|
position: relative; |
||||||
|
display: inline-flex; |
||||||
|
border: 1px solid #e0e0e0; |
||||||
|
border-radius: 90px; |
||||||
|
padding: 6px; |
||||||
|
--pl-slider-width: 0px; |
||||||
|
--pl-slider-x: 0px; |
||||||
|
gap: 4px; |
||||||
|
} |
||||||
|
|
||||||
|
.pl-lang-switcher-button, |
||||||
|
.pl-lang-switcher-container a { |
||||||
|
position: relative; |
||||||
|
z-index: 2; |
||||||
|
border: none; |
||||||
|
background: transparent; |
||||||
|
color: #636363; |
||||||
|
font-weight: 600; |
||||||
|
font-size: 15px; |
||||||
|
line-height: 110%; |
||||||
|
text-align: center; |
||||||
|
border-radius: 90px; |
||||||
|
cursor: pointer; |
||||||
|
transition: all 180ms ease; |
||||||
|
white-space: nowrap; |
||||||
|
text-decoration: none; |
||||||
|
display: inline-flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
height: 29px; |
||||||
|
padding-left: 12px; |
||||||
|
padding-right: 12px; |
||||||
|
} |
||||||
|
|
||||||
|
.pl-lang-switcher-button:hover, |
||||||
|
.pl-lang-switcher-container a:hover { |
||||||
|
color: #222; |
||||||
|
} |
||||||
|
|
||||||
|
.pl-lang-switcher-button.pl-lang-switcher-active, |
||||||
|
.pl-lang-switcher-container a.pl-lang-switcher-active, |
||||||
|
.pl-lang-switcher-container a.pl-lang-switcher-current { |
||||||
|
color: #f8f8f8; |
||||||
|
} |
||||||
|
|
||||||
|
.pl-lang-switcher-slider { |
||||||
|
position: absolute; |
||||||
|
height: 29px; |
||||||
|
background: linear-gradient(90deg, #2b2c35 67.31%, #4f5870 92.9%); |
||||||
|
border-radius: 90px; |
||||||
|
z-index: 1; |
||||||
|
width: var(--pl-slider-width); |
||||||
|
transform: translateX(var(--pl-slider-x)); |
||||||
|
transition: all 180ms cubic-bezier(0.4, 0.0, 0.2, 1); |
||||||
|
} |
||||||
|
</style> |
||||||
|
|
||||||
|
<div class="pl-lang-switcher-container" id="plLangSwitcherContainer"> |
||||||
|
<div class="pl-lang-switcher-slider" id="plLangSwitcherSlider"></div> |
||||||
|
<?php |
||||||
|
$languages = pll_languages_list(); |
||||||
|
$current_lang = pll_current_language('slug'); |
||||||
|
|
||||||
|
if ($languages) { |
||||||
|
foreach ($languages as $lang_slug) { |
||||||
|
$is_current = ($lang_slug === $current_lang); |
||||||
|
$class = $is_current ? 'pl-lang-switcher-current' : ''; |
||||||
|
|
||||||
|
$lang_url = ''; |
||||||
|
if (function_exists('pll_home_url')) { |
||||||
|
if (is_singular() && function_exists('pll_get_post')) { |
||||||
|
$translated_post_id = pll_get_post(get_the_ID(), $lang_slug); |
||||||
|
if ($translated_post_id) { |
||||||
|
$lang_url = get_permalink($translated_post_id); |
||||||
|
} else { |
||||||
|
$lang_url = pll_home_url($lang_slug); |
||||||
|
} |
||||||
|
} else { |
||||||
|
$lang_url = pll_home_url($lang_slug); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$lang_name = ''; |
||||||
|
if (function_exists('pll_languages_list')) { |
||||||
|
$lang_names = pll_languages_list(array('fields' => 'name')); |
||||||
|
$lang_slugs = pll_languages_list(array('fields' => 'slug')); |
||||||
|
$lang_index = array_search($lang_slug, $lang_slugs); |
||||||
|
if ($lang_index !== false && isset($lang_names[$lang_index])) { |
||||||
|
$lang_name = $lang_names[$lang_index]; |
||||||
|
} else { |
||||||
|
$lang_name = strtoupper($lang_slug); |
||||||
|
} |
||||||
|
} else { |
||||||
|
$lang_name = strtoupper($lang_slug); |
||||||
|
} |
||||||
|
|
||||||
|
echo sprintf( |
||||||
|
'<a href="%s" class="%s" data-lang="%s">%s</a>', |
||||||
|
esc_url($lang_url), |
||||||
|
esc_attr($class), |
||||||
|
esc_attr($lang_slug), |
||||||
|
esc_html($lang_name) |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
?> |
||||||
|
</div> |
||||||
|
|
||||||
|
<script> |
||||||
|
document.addEventListener('DOMContentLoaded', function() { |
||||||
|
const container = document.getElementById('plLangSwitcherContainer'); |
||||||
|
if (!container) return; |
||||||
|
|
||||||
|
let isInitialized = false; |
||||||
|
|
||||||
|
function updateSliderPosition(target = null, animate = false) { |
||||||
|
if (!target) { |
||||||
|
target = container.querySelector('.pl-lang-switcher-current'); |
||||||
|
} |
||||||
|
if (!target) return; |
||||||
|
|
||||||
|
const slider = container.querySelector('#plLangSwitcherSlider'); |
||||||
|
const width = target.offsetWidth; |
||||||
|
const x = target.offsetLeft - 6; |
||||||
|
|
||||||
|
if (animate) { |
||||||
|
slider.style.transition = 'all 180ms cubic-bezier(0.4, 0.0, 0.2, 1)'; |
||||||
|
} else { |
||||||
|
slider.style.transition = 'none'; |
||||||
|
} |
||||||
|
|
||||||
|
container.style.setProperty('--pl-slider-width', width + 'px'); |
||||||
|
container.style.setProperty('--pl-slider-x', x + 'px'); |
||||||
|
} |
||||||
|
|
||||||
|
function initialize() { |
||||||
|
if (isInitialized) return; |
||||||
|
|
||||||
|
const activeLink = container.querySelector('.pl-lang-switcher-current'); |
||||||
|
if (!activeLink || activeLink.offsetWidth === 0) { |
||||||
|
requestAnimationFrame(initialize); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
updateSliderPosition(activeLink, false); |
||||||
|
isInitialized = true; |
||||||
|
|
||||||
|
setupClickHandlers(); |
||||||
|
|
||||||
|
if (window.ResizeObserver) { |
||||||
|
const resizeObserver = new ResizeObserver(() => { |
||||||
|
if (isInitialized) { |
||||||
|
updateSliderPosition(null, false); |
||||||
|
} |
||||||
|
}); |
||||||
|
resizeObserver.observe(container); |
||||||
|
} else { |
||||||
|
window.addEventListener('resize', () => { |
||||||
|
if (isInitialized) { |
||||||
|
updateSliderPosition(null, false); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function setupClickHandlers() { |
||||||
|
container.addEventListener('click', function(e) { |
||||||
|
const link = e.target.closest('a'); |
||||||
|
if (!link) return; |
||||||
|
|
||||||
|
e.preventDefault(); |
||||||
|
|
||||||
|
container.querySelectorAll('a').forEach(a => a.classList.remove('pl-lang-switcher-current')); |
||||||
|
|
||||||
|
link.classList.add('pl-lang-switcher-current'); |
||||||
|
|
||||||
|
updateSliderPosition(link, true); |
||||||
|
|
||||||
|
setTimeout(() => location.href = link.href, 20); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
initialize(); |
||||||
|
}); |
||||||
|
</script> |
@ -0,0 +1,90 @@ |
|||||||
|
|
||||||
|
<div class="bg-white max-w-lg w-full rounded-[8px]"> |
||||||
|
<div class="p-[24px]"> |
||||||
|
<h2 class="text-[24px] font-bold text-gray-900 mb-[16px]"> |
||||||
|
Заказать клубную карту |
||||||
|
</h2> |
||||||
|
|
||||||
|
<form class="space-y-[16px]"> |
||||||
|
<div> |
||||||
|
<label for="name" class="block text-[14px] font-medium text-gray-700 mb-[8px]"> |
||||||
|
Имя * |
||||||
|
</label> |
||||||
|
<input type="text" |
||||||
|
id="name" |
||||||
|
name="name" |
||||||
|
required |
||||||
|
class="w-full px-[12px] py-[8px] border border-gray-300 rounded-[6px] focus:outline-none focus:ring-2 focus:ring-blue-500"> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div> |
||||||
|
<label for="email" class="block text-[14px] font-medium text-gray-700 mb-[8px]"> |
||||||
|
Email * |
||||||
|
</label> |
||||||
|
<input type="email" |
||||||
|
id="email" |
||||||
|
name="email" |
||||||
|
required |
||||||
|
class="w-full px-[12px] py-[8px] border border-gray-300 rounded-[6px] focus:outline-none focus:ring-2 focus:ring-blue-500"> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div> |
||||||
|
<label for="phone" class="block text-[14px] font-medium text-gray-700 mb-[8px]"> |
||||||
|
Телефон * |
||||||
|
</label> |
||||||
|
<input type="tel" |
||||||
|
id="phone" |
||||||
|
name="phone" |
||||||
|
required |
||||||
|
class="w-full px-[12px] py-[8px] border border-gray-300 rounded-[6px] focus:outline-none focus:ring-2 focus:ring-blue-500"> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div> |
||||||
|
<label for="card-type" class="block text-[14px] font-medium text-gray-700 mb-[8px]"> |
||||||
|
Тип карты |
||||||
|
</label> |
||||||
|
<select id="card-type" |
||||||
|
name="card-type" |
||||||
|
class="w-full px-[12px] py-[8px] border border-gray-300 rounded-[6px] focus:outline-none focus:ring-2 focus:ring-blue-500"> |
||||||
|
<option value="">Выберите тип карты</option> |
||||||
|
<option value="basic">Базовая</option> |
||||||
|
<option value="premium">Премиум</option> |
||||||
|
<option value="vip">VIP</option> |
||||||
|
</select> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div> |
||||||
|
<label for="message" class="block text-[14px] font-medium text-gray-700 mb-[8px]"> |
||||||
|
Комментарий |
||||||
|
</label> |
||||||
|
<textarea id="message" |
||||||
|
name="message" |
||||||
|
rows="3" |
||||||
|
class="w-full px-[12px] py-[8px] border border-gray-300 rounded-[6px] focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none"></textarea> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="flex items-center"> |
||||||
|
<input type="checkbox" |
||||||
|
id="agreement" |
||||||
|
name="agreement" |
||||||
|
required |
||||||
|
class="mr-[8px] w-[16px] h-[16px] text-blue-600 border-gray-300 rounded focus:ring-blue-500"> |
||||||
|
<label for="agreement" class="text-[14px] text-gray-700"> |
||||||
|
Я согласен с обработкой персональных данных * |
||||||
|
</label> |
||||||
|
</div> |
||||||
|
</form> |
||||||
|
|
||||||
|
<div class="flex justify-end gap-[12px] mt-[24px]"> |
||||||
|
<button data-modal-close |
||||||
|
type="button" |
||||||
|
class="px-[24px] py-[12px] bg-gray-500 text-white rounded-[6px] hover:bg-gray-600 transition-colors duration-[300ms]"> |
||||||
|
Отмена |
||||||
|
</button> |
||||||
|
<button type="submit" |
||||||
|
class="px-[24px] py-[12px] bg-blue-500 text-white rounded-[6px] hover:bg-blue-600 transition-colors duration-[300ms]"> |
||||||
|
Отправить заявку |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,33 @@ |
|||||||
|
<?php |
||||||
|
?> |
||||||
|
<div class="bg-white max-w-lg w-full"> |
||||||
|
<div class="p-6"> |
||||||
|
<h2 class="text-xl font-bold text-gray-900 mb-4">О нашей компании 2</h2> |
||||||
|
|
||||||
|
<div class="text-gray-600 space-y-4"> |
||||||
|
<p> |
||||||
|
Мы работаем на рынке более 10 лет и знаем, как решать самые сложные задачи наших клиентов. |
||||||
|
</p> |
||||||
|
|
||||||
|
<p> |
||||||
|
Наша команда состоит из опытных специалистов, которые постоянно совершенствуют свои навыки. |
||||||
|
</p> |
||||||
|
|
||||||
|
<div class="bg-blue-50 p-4 rounded-lg"> |
||||||
|
<h3 class="font-semibold text-blue-900 mb-2">Наши преимущества:</h3> |
||||||
|
<ul class="text-blue-800 space-y-1"> |
||||||
|
<li>• Высокое качество работ</li> |
||||||
|
<li>• Соблюдение сроков</li> |
||||||
|
<li>• Индивидуальный подход</li> |
||||||
|
<li>• Конкурентные цены</li> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="flex justify-end mt-6"> |
||||||
|
<button data-modal-close class="px-6 py-2 rounded-md"> |
||||||
|
Понятно |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,3 @@ |
|||||||
|
<?php |
||||||
|
echo do_shortcode('[fluentform id="2"]') |
||||||
|
?> |
@ -0,0 +1,261 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* Выбор языка (направления) в виде карточек |
||||||
|
* Необходим плагин Polylang |
||||||
|
*/ |
||||||
|
|
||||||
|
// Проверяем существование функций Polylang |
||||||
|
if (!function_exists('pll_languages_list') || !function_exists('pll_current_language')) { |
||||||
|
return; |
||||||
|
} |
||||||
|
?> |
||||||
|
|
||||||
|
<style> |
||||||
|
.language-selector { |
||||||
|
max-width: 800px; |
||||||
|
margin: 0 auto; |
||||||
|
background: #f5f5f5; |
||||||
|
border-radius: 20px; |
||||||
|
padding: 40px 30px; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.language-selector__title { |
||||||
|
font-size: 42px; |
||||||
|
font-weight: 700; |
||||||
|
color: #333; |
||||||
|
margin: 0 0 15px 0; |
||||||
|
} |
||||||
|
|
||||||
|
.language-selector__subtitle { |
||||||
|
font-size: 24px; |
||||||
|
font-weight: 400; |
||||||
|
color: #666; |
||||||
|
margin: 0 0 40px 0; |
||||||
|
line-height: 1.3; |
||||||
|
} |
||||||
|
|
||||||
|
.language-cards { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: 1fr 1fr; |
||||||
|
gap: 0; |
||||||
|
border-radius: 16px; |
||||||
|
overflow: hidden; |
||||||
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12); |
||||||
|
} |
||||||
|
|
||||||
|
.language-card { |
||||||
|
padding: 50px 30px; |
||||||
|
text-decoration: none; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: space-between; |
||||||
|
min-height: 320px; |
||||||
|
transition: transform 0.3s ease, box-shadow 0.3s ease; |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
.language-card:hover { |
||||||
|
transform: translateY(-4px); |
||||||
|
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.2); |
||||||
|
z-index: 2; |
||||||
|
} |
||||||
|
|
||||||
|
.language-card--dark { |
||||||
|
background: linear-gradient(135deg, #4a4a4a 0%, #2d2d2d 100%); |
||||||
|
color: white; |
||||||
|
} |
||||||
|
|
||||||
|
.language-card--light { |
||||||
|
background: linear-gradient(135deg, #ffffff 0%, #f8f8f8 100%); |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
|
||||||
|
.language-card__header { |
||||||
|
margin-bottom: 30px; |
||||||
|
} |
||||||
|
|
||||||
|
.language-card__title { |
||||||
|
font-size: 32px; |
||||||
|
font-weight: 700; |
||||||
|
margin: 0 0 8px 0; |
||||||
|
} |
||||||
|
|
||||||
|
.language-card__subtitle { |
||||||
|
font-size: 16px; |
||||||
|
opacity: 0.8; |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.language-card__content { |
||||||
|
flex-grow: 1; |
||||||
|
margin-bottom: 30px; |
||||||
|
} |
||||||
|
|
||||||
|
.language-card__description { |
||||||
|
font-size: 15px; |
||||||
|
line-height: 1.6; |
||||||
|
opacity: 0.9; |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.language-card__footer { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.language-card__button { |
||||||
|
background: rgba(255, 255, 255, 0.15); |
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2); |
||||||
|
color: inherit; |
||||||
|
padding: 12px 32px; |
||||||
|
border-radius: 50px; |
||||||
|
font-size: 16px; |
||||||
|
font-weight: 600; |
||||||
|
transition: all 0.3s ease; |
||||||
|
display: inline-block; |
||||||
|
text-decoration: none; |
||||||
|
backdrop-filter: blur(10px); |
||||||
|
} |
||||||
|
|
||||||
|
.language-card--dark .language-card__button { |
||||||
|
background: rgba(255, 255, 255, 0.15); |
||||||
|
border-color: rgba(255, 255, 255, 0.3); |
||||||
|
} |
||||||
|
|
||||||
|
.language-card--light .language-card__button { |
||||||
|
background: rgba(0, 0, 0, 0.08); |
||||||
|
border-color: rgba(0, 0, 0, 0.15); |
||||||
|
} |
||||||
|
|
||||||
|
.language-card__button:hover { |
||||||
|
transform: translateY(-2px); |
||||||
|
background: rgba(255, 255, 255, 0.25); |
||||||
|
border-color: rgba(255, 255, 255, 0.4); |
||||||
|
} |
||||||
|
|
||||||
|
.language-card--light .language-card__button:hover { |
||||||
|
background: rgba(0, 0, 0, 0.12); |
||||||
|
border-color: rgba(0, 0, 0, 0.25); |
||||||
|
} |
||||||
|
|
||||||
|
/* Мобильная адаптация */ |
||||||
|
@media (max-width: 768px) { |
||||||
|
.language-cards { |
||||||
|
grid-template-columns: 1fr; |
||||||
|
} |
||||||
|
|
||||||
|
.language-selector { |
||||||
|
padding: 30px 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.language-selector__title { |
||||||
|
font-size: 32px; |
||||||
|
} |
||||||
|
|
||||||
|
.language-selector__subtitle { |
||||||
|
font-size: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.language-card { |
||||||
|
padding: 40px 25px; |
||||||
|
min-height: 280px; |
||||||
|
} |
||||||
|
|
||||||
|
.language-card__title { |
||||||
|
font-size: 28px; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
|
|
||||||
|
<div class="language-selector"> |
||||||
|
<h2 class="language-selector__title">Fakel</h2> |
||||||
|
<p class="language-selector__subtitle">Какое направление<br>вас интересует?</p> |
||||||
|
|
||||||
|
<div class="language-cards"> |
||||||
|
<?php |
||||||
|
$languages = pll_languages_list(); |
||||||
|
$current_lang = pll_current_language('slug'); |
||||||
|
|
||||||
|
// Определяем конфигурацию языков |
||||||
|
$lang_config = array( |
||||||
|
'fitness' => array( |
||||||
|
'title' => 'Fakel Fitness', |
||||||
|
'subtitle' => 'Фитнес-центр', |
||||||
|
'description' => 'Фитнес-центр мировых стандартов 2500 м². Оборудование из США, большая кардио-зона, более 45 направлений групповых программ, сауна, кафе, зона релакса и мн. др.', |
||||||
|
'button_text' => 'Фитнес-центр', |
||||||
|
'style' => 'light' |
||||||
|
), |
||||||
|
'gym' => array( |
||||||
|
'title' => 'Fakel Gym', |
||||||
|
'subtitle' => 'Тренажерный зал', |
||||||
|
'description' => 'Пространство для работы с весами, головными тренажерами и ничего лишнего. Идеальное соотношение цены и комфорта, если Вам необходим лишь тренажерный зал.', |
||||||
|
'button_text' => 'Тренажерный зал', |
||||||
|
'style' => 'dark' |
||||||
|
) |
||||||
|
); |
||||||
|
|
||||||
|
if ($languages) { |
||||||
|
foreach ($languages as $lang_slug) { |
||||||
|
// Получаем URL для языка |
||||||
|
$lang_url = ''; |
||||||
|
if (function_exists('pll_home_url')) { |
||||||
|
if (is_singular() && function_exists('pll_get_post')) { |
||||||
|
$translated_post_id = pll_get_post(get_the_ID(), $lang_slug); |
||||||
|
if ($translated_post_id) { |
||||||
|
$lang_url = get_permalink($translated_post_id); |
||||||
|
} else { |
||||||
|
$lang_url = pll_home_url($lang_slug); |
||||||
|
} |
||||||
|
} else { |
||||||
|
$lang_url = pll_home_url($lang_slug); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Используем конфигурацию если есть, иначе дефолтные значения |
||||||
|
if (isset($lang_config[$lang_slug])) { |
||||||
|
$config = $lang_config[$lang_slug]; |
||||||
|
} else { |
||||||
|
// Получаем название языка |
||||||
|
$lang_names = pll_languages_list(array('fields' => 'name')); |
||||||
|
$lang_slugs = pll_languages_list(array('fields' => 'slug')); |
||||||
|
$lang_index = array_search($lang_slug, $lang_slugs); |
||||||
|
$lang_name = ($lang_index !== false && isset($lang_names[$lang_index])) |
||||||
|
? $lang_names[$lang_index] |
||||||
|
: strtoupper($lang_slug); |
||||||
|
|
||||||
|
$config = array( |
||||||
|
'title' => $lang_name, |
||||||
|
'subtitle' => 'Версия сайта', |
||||||
|
'description' => 'Перейти на ' . $lang_name . ' версию сайта', |
||||||
|
'button_text' => 'Перейти', |
||||||
|
'style' => ($lang_slug === 'gym') ? 'dark' : 'light' |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
echo sprintf( |
||||||
|
'<a href="%s" class="language-card language-card--%s" data-lang="%s"> |
||||||
|
<div class="language-card__header"> |
||||||
|
<h3 class="language-card__title">%s</h3> |
||||||
|
<p class="language-card__subtitle">%s</p> |
||||||
|
</div> |
||||||
|
<div class="language-card__content"> |
||||||
|
<p class="language-card__description">%s</p> |
||||||
|
</div> |
||||||
|
<div class="language-card__footer"> |
||||||
|
<span class="language-card__button">%s</span> |
||||||
|
</div> |
||||||
|
</a>', |
||||||
|
esc_url($lang_url), |
||||||
|
esc_attr($config['style']), |
||||||
|
esc_attr($lang_slug), |
||||||
|
esc_html($config['title']), |
||||||
|
esc_html($config['subtitle']), |
||||||
|
esc_html($config['description']), |
||||||
|
esc_html($config['button_text']) |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
?> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,13 @@ |
|||||||
|
<?php |
||||||
|
?> |
||||||
|
<div class="bg-white max-w-lg w-full"> |
||||||
|
<div class="p-6"> |
||||||
|
<h2 class="text-xl font-bold text-gray-900 mb-4">Расписание</h2> |
||||||
|
|
||||||
|
<div class="flex justify-end mt-6"> |
||||||
|
<button data-modal-close class="border w-full"> |
||||||
|
Понятно |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,180 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Навигационное меню с сео |
||||||
|
* По умолчанию названию меню Шапка сайта |
||||||
|
*/ |
||||||
|
|
||||||
|
$menu = wp_get_nav_menu_object('Шапка сайта'); |
||||||
|
|
||||||
|
if ($menu) { |
||||||
|
$menu_items = wp_get_nav_menu_items($menu->term_id); |
||||||
|
$current_lang = function_exists('pll_current_language') ? pll_current_language() : null; |
||||||
|
|
||||||
|
if ($menu_items) { |
||||||
|
// Чистим заголовок от (переводов) |
||||||
|
$clean_title = function($title) { |
||||||
|
return trim(preg_replace('/\s*\([^)]*\)/', '', $title)); |
||||||
|
}; |
||||||
|
|
||||||
|
$current_region = 'RU'; |
||||||
|
|
||||||
|
// Навигационная схема для Яндекса |
||||||
|
$navigation_schema = array( |
||||||
|
"@context" => "https://schema.org", |
||||||
|
"@type" => "SiteNavigationElement", |
||||||
|
"name" => "Главная навигация сайта", |
||||||
|
"description" => "Основное меню навигации по сайту", |
||||||
|
"inLanguage" => $current_lang ?: 'ru', |
||||||
|
"areaServed" => $current_region, |
||||||
|
"url" => array() |
||||||
|
); |
||||||
|
|
||||||
|
// Хлебные крошки для Яндекса |
||||||
|
$breadcrumb_schema = array( |
||||||
|
"@context" => "https://schema.org", |
||||||
|
"@type" => "BreadcrumbList", |
||||||
|
"itemListElement" => array() |
||||||
|
); |
||||||
|
?> |
||||||
|
|
||||||
|
<nav class="main-navigation primary-navigation h-full" |
||||||
|
role="navigation" |
||||||
|
aria-label="Основное меню сайта" |
||||||
|
itemscope |
||||||
|
itemtype="https://schema.org/SiteNavigationElement" |
||||||
|
data-region="<?php echo esc_attr($current_region); ?>"
|
||||||
|
data-lang="<?php echo esc_attr($current_lang ?: 'ru'); ?>">
|
||||||
|
|
||||||
|
<p class="screen-reader-text">Главное меню</p> |
||||||
|
|
||||||
|
<ul class="flex items-center h-full gap-[30px] justify-between nav-menu main-menu" role="menubar" aria-label="Главная навигация"> |
||||||
|
<?php |
||||||
|
$position = 1; |
||||||
|
|
||||||
|
foreach ($menu_items as $index => $item) { |
||||||
|
$url = $item->url; |
||||||
|
$title = $clean_title($item->title); |
||||||
|
|
||||||
|
// Polylang |
||||||
|
if ($current_lang && $item->object == 'page' && function_exists('pll_get_post')) { |
||||||
|
$translated_page_id = pll_get_post($item->object_id, $current_lang); |
||||||
|
if ($translated_page_id) { |
||||||
|
$url = get_permalink($translated_page_id); |
||||||
|
$translated_title = get_the_title($translated_page_id); |
||||||
|
if ($translated_title) { |
||||||
|
$title = $clean_title($translated_title); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Дата изменения для Яндекса |
||||||
|
$last_modified = ''; |
||||||
|
if ($item->object == 'page') { |
||||||
|
$last_modified = get_the_modified_time('c', $item->object_id); |
||||||
|
} |
||||||
|
|
||||||
|
// Активный пункт меню |
||||||
|
$is_current = false; |
||||||
|
$current_classes = ''; |
||||||
|
$aria_current = ''; |
||||||
|
|
||||||
|
if (is_page()) { |
||||||
|
global $post; |
||||||
|
if ($item->object == 'page') { |
||||||
|
if (($current_lang && function_exists('pll_get_post') && pll_get_post($item->object_id, $current_lang) == $post->ID) || |
||||||
|
$item->object_id == $post->ID) { |
||||||
|
$is_current = true; |
||||||
|
$current_classes = ' current-menu-item active current_page_item'; |
||||||
|
$aria_current = ' aria-current="page"'; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// CSS классы |
||||||
|
$css_classes = array( |
||||||
|
'menu-item', |
||||||
|
'menu-item-' . $item->ID, |
||||||
|
'menu-item-type-' . $item->type, |
||||||
|
'menu-item-object-' . $item->object, |
||||||
|
'menu-order-' . $item->menu_order |
||||||
|
); |
||||||
|
|
||||||
|
if ($is_current) { |
||||||
|
$css_classes[] = 'current-menu-item'; |
||||||
|
$css_classes[] = 'current_page_item'; |
||||||
|
$css_classes[] = 'active'; |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($item->classes)) { |
||||||
|
$css_classes = array_merge($css_classes, array_filter($item->classes)); |
||||||
|
} |
||||||
|
|
||||||
|
// Схема для Яндекса |
||||||
|
$page_data = array( |
||||||
|
"@type" => "WebPage", |
||||||
|
"name" => $title, |
||||||
|
"url" => $url, |
||||||
|
"position" => $position |
||||||
|
); |
||||||
|
|
||||||
|
if ($last_modified) { |
||||||
|
$page_data['dateModified'] = $last_modified; |
||||||
|
} |
||||||
|
|
||||||
|
$navigation_schema['url'][] = $page_data; |
||||||
|
|
||||||
|
$breadcrumb_schema['itemListElement'][] = array( |
||||||
|
"@type" => "ListItem", |
||||||
|
"position" => $position, |
||||||
|
"name" => $title, |
||||||
|
"item" => $url |
||||||
|
); |
||||||
|
?> |
||||||
|
|
||||||
|
<li class="hover:translate-y-[-1px] transition h-full <?php echo esc_attr(implode(' ', $css_classes)); ?>" role="none">
|
||||||
|
<a href="<?php echo esc_url($url); ?>"
|
||||||
|
class="menu-link !no-underline h-full flex items-center" |
||||||
|
role="menuitem" |
||||||
|
itemprop="url" |
||||||
|
tabindex="0"<?php echo $aria_current; ?> |
||||||
|
title="<?php echo esc_attr('Перейти на страницу: ' . $title); ?>"
|
||||||
|
data-menu-item="<?php echo esc_attr($title); ?>"
|
||||||
|
data-menu-position="<?php echo $position; ?>"
|
||||||
|
onclick="if(typeof yaCounter !== 'undefined') { yaCounter.reachGoal('menu_click', {item: '<?php echo esc_js($title); ?>'}); }"
|
||||||
|
<?php if ($item->target): ?>target="<?php echo esc_attr($item->target); ?>"<?php endif; ?> |
||||||
|
<?php if ($item->attr_title): ?>title="<?php echo esc_attr($item->attr_title); ?>"<?php endif; ?>>
|
||||||
|
<span itemprop="name"><?php echo esc_html($title); ?></span>
|
||||||
|
</a> |
||||||
|
</li> |
||||||
|
|
||||||
|
<?php |
||||||
|
// Сепаратор |
||||||
|
if ($index < count($menu_items) - 1): ?> |
||||||
|
<li class="menu-separator" role="none" aria-hidden="true"> |
||||||
|
<span class="separator"><svg width="7" height="15" viewBox="0 0 7 15" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||||
|
<path d="M0.574219 14.4345L5.55022 0.5625H6.92622L1.93422 14.4345H0.574219Z" fill="#E0E0E0"/> |
||||||
|
</svg> |
||||||
|
</span> |
||||||
|
</li> |
||||||
|
<?php endif; |
||||||
|
|
||||||
|
$position++; |
||||||
|
} ?> |
||||||
|
</ul> |
||||||
|
</nav> |
||||||
|
|
||||||
|
<?php |
||||||
|
// Cео |
||||||
|
?> |
||||||
|
<script type="application/ld+json"> |
||||||
|
<?php echo json_encode($navigation_schema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?> |
||||||
|
</script> |
||||||
|
|
||||||
|
<script type="application/ld+json"> |
||||||
|
<?php echo json_encode($breadcrumb_schema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?> |
||||||
|
</script> |
||||||
|
|
||||||
|
<?php |
||||||
|
} |
||||||
|
} |
||||||
|
?> |
Loading…
Reference in new issue