блоки в админку и фиксы стилей

This commit is contained in:
GP_DEV
2025-06-03 21:52:23 +03:00
parent 32ef49087a
commit decc7c470a
9 changed files with 549 additions and 427 deletions

View File

@@ -13,7 +13,7 @@ if (!empty($block['align'])) {
$class_name .= ' align' . $block['align']; $class_name .= ' align' . $block['align'];
} }
// Получение карт для текущего языка if (!function_exists('get_club_cards_for_current_language')) {
function get_club_cards_for_current_language() { function get_club_cards_for_current_language() {
$current_lang = pll_current_language(); $current_lang = pll_current_language();
@@ -26,15 +26,16 @@ function get_club_cards_for_current_language() {
return get_posts($args); return get_posts($args);
} }
}
$cards = get_club_cards_for_current_language(); $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); ?>"> <div id="<?php echo esc_attr($block_id); ?>" class="container mx-auto mt-[24px] <?php echo esc_attr($class_name); ?>">
<?php if ($cards): ?> <?php if ($cards): ?>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-[24px]"> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-[24px]">
<?php foreach ($cards as $card): ?> <?php foreach ($cards as $card): ?>
<div class="club-card rounded-[8px] overflow-hidden hover:shadow-xl transition-shadow duration-[300ms]"> <div class="club-card rounded-[8px] overflow-hidden border transition-shadow ">
<?php if (has_post_thumbnail($card->ID)): ?> <?php if (has_post_thumbnail($card->ID)): ?>
<div class="aspect-video overflow-hidden"> <div class="aspect-video overflow-hidden">
<?php echo get_the_post_thumbnail($card->ID, 'medium', ['class' => 'w-full h-full object-cover']); ?> <?php echo get_the_post_thumbnail($card->ID, 'medium', ['class' => 'w-full h-full object-cover']); ?>
@@ -56,7 +57,7 @@ $cards = get_club_cards_for_current_language();
<div class="text-center"> <div class="text-center">
<button data-modal="club-card" <button data-modal="club-card"
data-card-id="<?php echo $card->ID; ?>" 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]"> class="inline-block px-[24px] py-[12px] bg-blue-500 text-white rounded-[6px] hover:bg-blue-600 transition-colors ">
Подробнее Подробнее
</button> </button>
</div> </div>

View File

@@ -1,7 +1,22 @@
<?php <?php
/**
* Шаблон для блока преимуществ $id = 'contacts-block-' . $block['id'];
*/ if ( ! empty($block['anchor'] ) ) {
$id = $block['anchor'];
}
$classes = 'block-contacts-block';
if ( ! empty( $block['className'] ) ) {
$classes .= ' ' . $block['className'];
}
if ( ! empty( $block['align'] ) ) {
$classes .= ' align' . $block['align'];
}
$heading = get_field('heading');
$work_time = get_field('work_time');
$address = get_field('address');
$contacts = get_field('contacts');
$blocks = parse_blocks(get_the_content()); $blocks = parse_blocks(get_the_content());
$is_first_block = false; $is_first_block = false;
@@ -10,116 +25,122 @@ if (!empty($blocks) && isset($blocks[0]['blockName']) && $blocks[0]['blockName']
$is_first_block = true; $is_first_block = true;
} }
$section_padding = $is_first_block ? "pt-[65px] max-[768px]:pt-[35px]" : "pt-[120px] max-[768px]:pt-[70px]"; $section_padding = $is_first_block ? "pt-[64px] max-[768px]:pt-[40px]" : "pt-[80px] max-[768px]:pt-[64px]";
?> ?>
<style> <style type="text/css">
/* Скрываем, но лучше не нужно по копирайту */ <?php echo '#' . $id; ?> {
.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, .ymaps-2-1-79-copyright,
[class*="ymaps-2"][class*="copyright"], [class*="ymaps-2"][class*="gototech"], .ymaps-2-1-79-gototech,
[class*="ymaps-2"][class*="gototaxi"], [class*="ymaps-2"][class*="gotoymaps"] { .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; display: none !important;
opacity: 0 !important;
visibility: hidden !important;
} }
</style> </style>
<section class="<?php echo $section_padding ?> full-layout"> <section id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $classes ); ?> <?php echo $section_padding ?>">
<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="w-full relative">
<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"> <div id="map" class="w-full h-[500px] min-[1024px]:h-[700px] bg-[#f3f4f6]"></div>
<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"> <div class="absolute inset-0 pointer-events-none">
<rect x="60.8145" width="82.2698" height="98.6297" transform="rotate(38.0681 60.8145 0)" <div class="container mx-auto px-[16px] h-full flex items-start pt-[40px]">
fill="url(#paint0_linear_2001_4983)"/> <div class="bg-[#ffffff] border-[1px] border-[#e5e7eb] rounded-[12px] p-[30px] w-full max-w-[380px] shadow-lg pointer-events-auto">
<defs>
<linearGradient id="paint0_linear_2001_4983" x1="62.7686" y1="4.14594" x2="131.553" y2="37.4035" <?php if ($heading) : ?>
gradientUnits="userSpaceOnUse"> <h2 class="text-[36px] max-[768px]:text-[28px] font-bold mb-[30px] text-[#1f2937]">
<stop stop-color="#F41C1B"/> <?php echo esc_html($heading); ?>
<stop offset="0.435" stop-color="#F72D2C"/> </h2>
<stop offset="1" stop-color="#FA4242"/> <?php else : ?>
</linearGradient> <h2 class="text-[36px] max-[768px]:text-[28px] font-bold mb-[30px] text-[#1f2937]">Контакты</h2>
</defs> <?php endif; ?>
</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]"> <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> <?php if ($work_time) : ?>
<div class="flex flex-col font-semibold text-[28px] leading-[165%] text-[#3f3f3f]"> <div>
<p class=" font-light text-[18px] text-[#828282]">Номер телефона:</p> <?php if (!empty($work_time['heading'])) : ?>
<a target="_blank" href="tel:<?php echo get_field('phones', 'options')['main_phone'] ?>" <p class="text-[14px] text-[#6b7280] mb-[8px]"><?php echo esc_html($work_time['heading']); ?></p>
class="hover:text-[#f62322] !decoration-transparent skip-ink transition-colors" <?php endif; ?>
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'] ?>" <?php if (!empty($work_time['work_time_repeater'])) : ?>
class="hover:text-[#f62322] !decoration-transparent skip-ink transition-colors" <div class="flex flex-col gap-[4px] mb-[12px]">
href="tel:+7(911)098-59-77"><?php echo get_field('phones', 'options')['phone'] ?></a> <?php foreach ($work_time['work_time_repeater'] as $time_item) : ?>
<div class="flex text-[16px] text-[#1f2937]">
<span><?php echo esc_html($time_item['title']); ?></span>
 
<span><?php echo esc_html($time_item['time']); ?></span>
</div> </div>
<div class="flex flex-col gap-[10px]"> <?php endforeach; ?>
<p class="font-light text-[18px] text-[#828282]">Головной офис:</p> </div>
<div class="font-normal text-[23px] leading-[137%] text-[#3f3f3f]"> <?php endif; ?>
<?php echo get_field('address', 'options') ?> </div>
<?php endif; ?>
<?php if ($address) : ?>
<div>
<?php if (!empty($address['heading'])) : ?>
<p class="text-[14px] text-[#6b7280] mb-[8px]"><?php echo esc_html($address['heading']); ?></p>
<?php endif; ?>
<?php if (!empty($address['address_repeater'])) : ?>
<div class="flex flex-col gap-[8px] mb-[12px]">
<?php foreach ($address['address_repeater'] as $addr_item) : ?>
<div class="text-[16px] text-[#1f2937] leading-[140%]">
<?php if (!empty($addr_item['address_title'])) : ?>
<div class="font-semibold"><?php echo esc_html($addr_item['address_title']); ?></div>
<?php endif; ?>
<?php if (!empty($addr_item['address_extra'])) : ?>
<div><?php echo esc_html($addr_item['address_extra']); ?></div>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if ($contacts) : ?>
<div>
<?php if (!empty($contacts['phone'])) : ?>
<div class="mb-[16px]">
<a href="tel:<?php echo esc_attr($contacts['phone']); ?>"
class="!decoration-transparent hover:!decoration-inherit text-[20px] max-[768px]:text-[18px] font-semibold transition-colors">
<?php echo esc_html($contacts['phone']); ?>
</a>
</div>
<?php endif; ?>
<?php if (!empty($contacts['social_repeater'])) : ?>
<div>
<div class="flex gap-[12px]">
<?php foreach ($contacts['social_repeater'] as $social_item) : ?>
<?php if (!empty($social_item['url'])) : ?>
<a href="<?php echo esc_url($social_item['url']); ?>"
target="_blank"
class="hover:[&>img]:brightness-150 transition">
<?php if (!empty($social_item['icon'])) : ?>
<img src="<?php echo esc_url($social_item['icon']['url']); ?>"
alt="<?php echo esc_attr($social_item['icon']['alt']); ?>"
class="object-contain" />
<?php endif; ?>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div> </div>
</div> </div>
<div class="flex flex-col gap-[10px]"> <?php endif; ?>
<p class="font-light text-[18px] text-[#828282]">E-mail:</p> </div>
<a class="hover:text-[#f62322] !decoration-transparent skip-ink transition-colors font-normal text-[23px] leading-[137%] text-[#3f3f3f]" <?php endif; ?>
href="mailto:info@mylogistika2010.ru"><?php echo get_field('email', 'options') ?></a>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -12,7 +12,22 @@ function initGalleryBlock(blockId) {
const swipers = {}; const swipers = {};
let lightbox; let lightbox;
function initSwiper(tabId) { function initAllSwipers() {
const tabs = container.querySelectorAll('.tab-button');
tabs.forEach(button => {
const tabId = button.getAttribute('data-tab');
const tabContent = container.querySelector(`#tab-${tabId}`);
if (tabContent && tabContent.querySelector('.swiper')) {
const wasHidden = tabContent.classList.contains('hidden');
if (wasHidden) {
tabContent.style.visibility = 'hidden';
tabContent.style.position = 'absolute';
tabContent.classList.remove('hidden');
tabContent.classList.add('block');
}
if (swipers[tabId]) { if (swipers[tabId]) {
swipers[tabId].destroy(true, true); swipers[tabId].destroy(true, true);
} }
@@ -22,6 +37,10 @@ function initGalleryBlock(blockId) {
spaceBetween: 20, spaceBetween: 20,
loop: true, loop: true,
centeredSlides: true, centeredSlides: true,
grabCursor: true,
observer: true,
observeParents: true,
watchSlidesProgress: true,
navigation: { navigation: {
nextEl: `#${blockId} #swiper-${tabId} .swiper-button-next`, nextEl: `#${blockId} #swiper-${tabId} .swiper-button-next`,
prevEl: `#${blockId} #swiper-${tabId} .swiper-button-prev`, prevEl: `#${blockId} #swiper-${tabId} .swiper-button-prev`,
@@ -32,6 +51,15 @@ function initGalleryBlock(blockId) {
} }
} }
}); });
if (wasHidden) {
tabContent.style.visibility = '';
tabContent.style.position = '';
tabContent.classList.add('hidden');
tabContent.classList.remove('block');
}
}
});
} }
function initLightbox(tabId) { function initLightbox(tabId) {
@@ -57,7 +85,14 @@ function initGalleryBlock(blockId) {
}); });
} }
// Табы initAllSwipers();
const activeTab = container.querySelector('.tab-button.active');
if (activeTab) {
const tabId = activeTab.getAttribute('data-tab');
initLightbox(tabId);
}
container.querySelectorAll('.tab-button').forEach(button => { container.querySelectorAll('.tab-button').forEach(button => {
button.addEventListener('click', () => { button.addEventListener('click', () => {
const tabId = button.getAttribute('data-tab'); const tabId = button.getAttribute('data-tab');
@@ -73,17 +108,21 @@ function initGalleryBlock(blockId) {
content.classList.remove('block'); content.classList.remove('block');
content.classList.add('hidden'); content.classList.add('hidden');
}); });
container.querySelector(`#tab-${tabId}`).classList.remove('hidden');
container.querySelector(`#tab-${tabId}`).classList.add('block');
setTimeout(() => { const targetTab = container.querySelector(`#tab-${tabId}`);
initSwiper(tabId); targetTab.classList.remove('hidden');
targetTab.classList.add('block');
if (swipers[tabId]) {
requestAnimationFrame(() => {
swipers[tabId].update();
});
}
initLightbox(tabId); initLightbox(tabId);
}, 100);
}); });
}); });
// Thumbnails
container.addEventListener('click', (e) => { container.addEventListener('click', (e) => {
if (e.target.closest('.thumbnail')) { if (e.target.closest('.thumbnail')) {
const thumbnail = e.target.closest('.thumbnail'); const thumbnail = e.target.closest('.thumbnail');
@@ -98,13 +137,4 @@ function initGalleryBlock(blockId) {
updateThumbnails(tabId, 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);
}
} }

View File

@@ -1,115 +1,60 @@
<?php <?php
// Моковые данные (потом заменить на ACF поля) $id = 'gallery-tabs-' . $block['id'];
$galleryData = [ if ( ! empty($block['anchor'] ) ) {
'reception' => [ $id = $block['anchor'];
'title' => 'Зона ресепшен', }
'images' => [
[ $classes = 'block-gallery-tabs';
'src' => 'https://placehold.co/800x600/4a5568/ffffff?text=Ресепшен+1', if ( ! empty( $block['className'] ) ) {
'thumb' => 'https://placehold.co/150x100/4a5568/ffffff?text=Р1', $classes .= ' ' . $block['className'];
'alt' => 'Ресепшен 1' }
], if ( ! empty( $block['align'] ) ) {
[ $classes .= ' align' . $block['align'];
'src' => 'https://placehold.co/800x600/2d3748/ffffff?text=Ресепшен+2', }
'thumb' => 'https://placehold.co/150x100/2d3748/ffffff?text=Р2',
'alt' => 'Ресепшен 2' $heading = get_field('heading');
], $slider_tabs = get_field('slider_tabs');
[
'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" <div class="gallery-block mt-[24px]"
id="<?php echo $block_id; ?>" id="<?php echo esc_attr( $id ); ?>"
data-gallery-id="<?php echo $block_id; ?>"> data-gallery-id="<?php echo esc_attr( $id ); ?>">
<div class="container mx-auto"> <div class="container mx-auto">
<h2 class="text-[32px] font-bold mb-[30px]">Галерея</h2>
<div class="flex gap-[10px] mb-[30px]"> <?php if ($heading) : ?>
<?php foreach ($galleryData as $index => $tab): ?> <h2 class="text-[32px] font-bold"><?php echo esc_html($heading); ?></h2>
<button class="tab-button px-[24px] py-[12px] border-0 rounded-[25px] cursor-pointer transition-all <?php echo $index === 'reception' ? 'active underline' : ''; ?>" <?php endif; ?>
data-tab="<?php echo $index; ?>">
<?php echo esc_html($tab['title']); ?> <?php if ($slider_tabs && !empty($slider_tabs['slider_tab'])) : ?>
<div class="flex gap-[10px] mt-[24px]">
<?php foreach ($slider_tabs['slider_tab'] as $tab_index => $tab) : ?>
<?php if (!empty($tab['tab_name'])) : ?>
<button class="tab-button px-[24px] py-[12px] border rounded-[25px] cursor-pointer transition-all <?php echo $tab_index === 0 ? 'active underline' : ''; ?>"
data-tab="<?php echo $tab_index; ?>">
<?php echo esc_html($tab['tab_name']); ?>
</button> </button>
<?php endif; ?>
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
<?php endif; ?>
</div> </div>
<?php foreach ($galleryData as $tab_id => $tab_data): ?> <?php if ($slider_tabs && !empty($slider_tabs['slider_tab'])) : ?>
<div class="tab-content <?php echo $tab_id === 'reception' ? 'block' : 'hidden'; ?>" <?php foreach ($slider_tabs['slider_tab'] as $tab_index => $tab) : ?>
id="tab-<?php echo $tab_id; ?>"> <div class="tab-content <?php echo $tab_index === 0 ? 'block' : 'hidden'; ?>"
id="tab-<?php echo $tab_index; ?>">
<div class="swiper gallery-swiper mb-[20px] h-[440px]" id="swiper-<?php echo $tab_id; ?>"> <?php if (!empty($tab['slider_images'])) : ?>
<div class="swiper mt-[24px] gallery-swiper h-[440px]" id="swiper-<?php echo $tab_index; ?>">
<div class="swiper-wrapper"> <div class="swiper-wrapper">
<?php foreach ($tab_data['images'] as $image): ?> <?php foreach ($tab['slider_images'] as $image) : ?>
<div class="swiper-slide cursor-pointer min-h-[440px]"> <div class="swiper-slide cursor-pointer min-h-[440px]">
<a href="<?php echo esc_url($image['src']); ?>" <a href="<?php echo esc_url($image['url']); ?>"
class="glightbox block w-full h-full" class="glightbox block w-full h-full"
data-gallery="gallery-<?php echo $tab_id; ?>"> data-gallery="gallery-<?php echo $tab_index; ?>">
<img src="<?php echo esc_url($image['src']); ?>" <img src="<?php echo esc_url($image['url']); ?>"
alt="<?php echo esc_attr($image['alt']); ?>" alt="<?php echo esc_attr($image['alt']); ?>"
class="w-full h-full object-cover"> class="w-full h-full object-cover">
</a> </a>
@@ -120,17 +65,22 @@ $block_id = 'gallery-' . $block['id'];
<div class="swiper-button-prev"></div> <div class="swiper-button-prev"></div>
</div> </div>
<div class="flex gap-[8px] overflow-x-auto"> <div class="flex mt-[24px] gap-[8px] overflow-x-auto">
<?php foreach ($tab_data['images'] as $thumb_index => $image): ?> <?php foreach ($tab['slider_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' : ''; ?>" <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; ?>"> data-index="<?php echo $thumb_index; ?>">
<img src="<?php echo esc_url($image['thumb']); ?>" <img src="<?php echo esc_url($image['sizes']['thumbnail']); ?>"
alt="<?php echo esc_attr($image['alt']); ?>" alt="<?php echo esc_attr($image['alt']); ?>"
class="w-full h-full object-cover"> class="w-full h-full object-cover">
</div> </div>
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
<?php if (!empty($image['caption'])) : ?>
<p><?php echo esc_html($image['caption']); ?></p>
<?php endif; ?>
<?php endif; ?>
</div> </div>
<?php endforeach; ?> <?php endforeach; ?>
<?php endif; ?>
</div> </div>

View File

@@ -12,16 +12,43 @@ function initReviewsBlock(blockId) {
const swipers = {}; const swipers = {};
let lightbox; let lightbox;
function initSwiper(tabId) { function initAllSwipers() {
const tabs = container.querySelectorAll('.tab-button');
tabs.forEach(button => {
const tabId = button.getAttribute('data-tab');
const tabContent = container.querySelector(`#tab-${tabId}`);
if (tabContent && tabContent.querySelector('.swiper')) {
const wasHidden = tabContent.classList.contains('hidden');
if (wasHidden) {
tabContent.style.visibility = 'hidden';
tabContent.style.position = 'absolute';
tabContent.classList.remove('hidden');
tabContent.classList.add('block');
}
if (swipers[tabId]) { if (swipers[tabId]) {
swipers[tabId].destroy(true, true); swipers[tabId].destroy(true, true);
} }
swipers[tabId] = new Swiper(`#${blockId} #swiper-${tabId}`, { swipers[tabId] = new Swiper(`#${blockId} #swiper-${tabId}`, {
slidesPerView: 3, slidesPerView: 'auto',
spaceBetween: 20, spaceBetween: 20,
loop: true, loop: true,
centeredSlides: true, centeredSlides: true,
observer: true,
observeParents: true,
watchSlidesProgress: true,
});
if (wasHidden) {
tabContent.style.visibility = '';
tabContent.style.position = '';
tabContent.classList.add('hidden');
tabContent.classList.remove('block');
}
}
}); });
} }
@@ -64,8 +91,14 @@ function initReviewsBlock(blockId) {
}); });
} }
initAllSwipers();
const activeTab = container.querySelector('.tab-button.active');
if (activeTab) {
const tabId = activeTab.getAttribute('data-tab');
initLightbox(tabId);
}
// Табы
container.querySelectorAll('.tab-button').forEach(button => { container.querySelectorAll('.tab-button').forEach(button => {
button.addEventListener('click', () => { button.addEventListener('click', () => {
const tabId = button.getAttribute('data-tab'); const tabId = button.getAttribute('data-tab');
@@ -81,24 +114,18 @@ function initReviewsBlock(blockId) {
content.classList.remove('block'); content.classList.remove('block');
content.classList.add('hidden'); content.classList.add('hidden');
}); });
container.querySelector(`#tab-${tabId}`).classList.remove('hidden');
container.querySelector(`#tab-${tabId}`).classList.add('block');
setTimeout(() => { const targetTab = container.querySelector(`#tab-${tabId}`);
initSwiper(tabId); targetTab.classList.remove('hidden');
targetTab.classList.add('block');
if (swipers[tabId]) {
requestAnimationFrame(() => {
swipers[tabId].update();
});
}
initLightbox(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);
}
} }

View File

@@ -1,136 +1,153 @@
<?php <?php
// Моковые данные отзывов (потом заменить на ACF поля) $id = 'reviews-block-' . $block['id'];
$reviewsData = [ if ( ! empty($block['anchor'] ) ) {
'google' => [ $id = $block['anchor'];
'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']; $classes = 'block-reviews-block';
if ( ! empty( $block['className'] ) ) {
$classes .= ' ' . $block['className'];
}
if ( ! empty( $block['align'] ) ) {
$classes .= ' align' . $block['align'];
}
$heading = get_field('heading');
$slider_tabs = get_field('slider_tabs');
$slider_video_reviews = get_field('slider_video_reviews');
$stars = get_field('stars');
?> ?>
<div class="reviews-block container mx-auto" <div class="reviews-block container mx-auto mt-[24px]"
id="<?php echo $block_id; ?>" id="<?php echo esc_attr( $id ); ?>"
data-reviews-id="<?php echo $block_id; ?>"> data-reviews-id="<?php echo esc_attr( $id ); ?>">
<div> <div>
<h2 class="text-[32px] font-bold mb-[30px]">Отзывы клиентов</h2> <?php if ($heading) : ?>
<h2 class="text-[32px] font-bold mt-[24px]"><?php echo esc_html($heading); ?></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; ?> <?php endif; ?>
<div class="flex gap-[10px] mt-[24px]">
<?php if ($slider_tabs && !empty($slider_tabs['slider_tab'])) : ?>
<?php foreach ($slider_tabs['slider_tab'] as $tab_index => $tab) : ?>
<?php if (!empty($tab['tab_name'])) : ?>
<button class="tab-button px-[24px] py-[12px] border rounded-[25px] cursor-pointer transition-all <?php echo $tab_index === 0 ? 'active underline' : ''; ?>"
data-tab="<?php echo $tab_index; ?>">
<?php echo esc_html($tab['tab_name']); ?>
</button>
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>
<?php if ($slider_video_reviews) : ?>
<button class="tab-button px-[24px] py-[12px] border rounded-[25px] cursor-pointer transition-all"
data-tab="video">
Видеоотзывы
</button>
<?php endif; ?>
</div>
<div class="mt-[24px] flex gap-[20px]">
<div class="flex gap-[5px] w-full items-center justify-center">
<svg width="39" height="38" viewBox="0 0 39 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.5 0L25.7658 11.8759L38.9967 14.1652L29.6383 23.7941L31.5496 37.0848L19.5 31.16L7.4504 37.0848L9.36174 23.7941L0.00334167 14.1652L13.2342 11.8759L19.5 0Z" fill="#565656"/>
</svg>
<svg width="39" height="38" viewBox="0 0 39 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.5 0L25.7658 11.8759L38.9967 14.1652L29.6383 23.7941L31.5496 37.0848L19.5 31.16L7.4504 37.0848L9.36174 23.7941L0.00334167 14.1652L13.2342 11.8759L19.5 0Z" fill="#565656"/>
</svg>
<svg width="39" height="38" viewBox="0 0 39 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.5 0L25.7658 11.8759L38.9967 14.1652L29.6383 23.7941L31.5496 37.0848L19.5 31.16L7.4504 37.0848L9.36174 23.7941L0.00334167 14.1652L13.2342 11.8759L19.5 0Z" fill="#565656"/>
</svg>
<svg width="39" height="38" viewBox="0 0 39 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.5 0L25.7658 11.8759L38.9967 14.1652L29.6383 23.7941L31.5496 37.0848L19.5 31.16L7.4504 37.0848L9.36174 23.7941L0.00334167 14.1652L13.2342 11.8759L19.5 0Z" fill="#565656"/>
</svg>
<svg width="39" height="38" viewBox="0 0 39 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.5 0L25.7658 11.8759L38.9967 14.1652L29.6383 23.7941L31.5496 37.0848L19.5 31.16L7.4504 37.0848L9.36174 23.7941L0.00334167 14.1652L13.2342 11.8759L19.5 0Z" fill="#565656"/>
</svg>
<div>
Оценок:  
<?php
echo $stars;
?>
</div>
</div>
</div>
</div>
<?php if ($slider_tabs && !empty($slider_tabs['slider_tab'])) : ?>
<?php foreach ($slider_tabs['slider_tab'] as $tab_index => $tab) : ?>
<div class="tab-content mt-[24px] <?php echo $tab_index === 0 ? 'block' : 'hidden'; ?>"
id="tab-<?php echo $tab_index; ?>">
<?php if (!empty($tab['slider_images'])) : ?>
<div class="swiper reviews-swiper" id="swiper-<?php echo $tab_index; ?>">
<div class="swiper-wrapper">
<?php foreach ($tab['slider_images'] as $image) : ?>
<div class="swiper-slide max-w-[449px] cursor-pointer">
<a href="<?php echo esc_url($image['url']); ?>"
class="glightbox block w-full h-full relative"
data-gallery="reviews-<?php echo $tab_index; ?>">
<img src="<?php echo esc_url($image['url']); ?>"
alt="<?php echo esc_attr($image['alt']); ?>"
class="w-full h-full object-contain">
</a> </a>
</div> </div>
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
</div> </div>
<?php endif; ?>
</div> </div>
<?php endforeach; ?> <?php endforeach; ?>
<?php endif; ?>
<?php if ($slider_video_reviews) : ?>
<div class="tab-content mt-[24px] hidden" id="tab-video">
<div class="swiper reviews-swiper" id="swiper-video">
<div class="swiper-wrapper">
<?php foreach ($slider_video_reviews as $video) : ?>
<?php if (!empty($video['slider_video_review'])) : ?>
<div class="swiper-slide max-w-[449px] cursor-pointer">
<a href="<?php echo esc_url($video['slider_video_review']['url']); ?>"
class="glightbox block w-full h-full relative"
data-gallery="reviews-video"
data-type="video">
<div class="w-full h-[200px] relative overflow-hidden rounded-lg">
<?php if (!empty($video['slider_video_prereview'])) : ?>
<div class="w-full h-full bg-[#f3f4f6] flex items-center justify-center">
<div class="text-center">
<div class="absolute left-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%] w-[60px] h-[60px] bg-white bg-opacity-90 rounded-full flex items-center justify-center mx-auto mb-[8px]">
<svg class="w-[24px] h-[24px]" fill="currentColor" viewBox="0 0 20 20">
<path d="M8 5v10l8-5-8-5z"/>
</svg>
</div>
<img src="<?php echo esc_url($video['slider_video_prereview']['url']); ?>"
alt="<?php echo esc_attr($video['slider_video_prereview']['alt'] ?: 'Превью видеоотзыва'); ?>"
class="w-full h-full object-cover">
</div>
</div>
<?php else : ?>
<div class="w-full h-full bg-[#f3f4f6] flex justify-center">
<div class="text-center">
<div class="absolute left-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%] w-[60px] h-[60px] bg-white bg-opacity-90 rounded-full flex items-center justify-center mx-auto mb-[8px]">
<svg class="w-[24px] h-[24px]" fill="currentColor" viewBox="0 0 20 20">
<path d="M8 5v10l8-5-8-5z"/>
</svg>
</div>
<p class="text-[14px] text-[#6b7280]">Видеоотзыв</p>
</div>
</div>
<?php endif; ?>
</div>
</a>
</div>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
</div>
<?php endif; ?>
</div> </div>

View File

@@ -0,0 +1,62 @@
<?php
$id = 'tiles-block-' . $block['id'];
if ( ! empty($block['anchor'] ) ) {
$id = $block['anchor'];
}
$classes = 'block-tiles-block';
if ( ! empty( $block['className'] ) ) {
$classes .= ' ' . $block['className'];
}
if ( ! empty( $block['align'] ) ) {
$classes .= ' align' . $block['align'];
}
$heading = get_field('heading');
$tiles_repeater = get_field('tiles_repeater');
?>
<section id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $classes ); ?>">
<div class="container mx-auto mt-[24px]">
<?php if ($heading) : ?>
<h2 class="text-[48px] max-[768px]:text-[36px] font-bold text-center text-[#1f2937]">
<?php echo esc_html($heading); ?>
</h2>
<?php endif; ?>
<?php if ($tiles_repeater) : ?>
<div class="mt-[24px] grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-[30px] max-[768px]:gap-[20px]">
<?php foreach ($tiles_repeater as $tile) : ?>
<div class="bg-[#ffffff] border-[1px] border-[#e5e7eb] rounded-[16px] p-[30px] max-[768px]:p-[20px] shadow-lg hover:shadow-xl transition-shadow duration-300">
<?php if (!empty($tile['image'])) : ?>
<div class="w-[80px] h-[80px] rounded-full overflow-hidden mb-[20px] mx-auto bg-[#f3f4f6] flex items-center justify-center">
<img src="<?php echo esc_url($tile['image']['url']); ?>"
alt="<?php echo esc_attr($tile['image']['alt']); ?>"
class="w-full h-full object-cover" />
</div>
<?php endif; ?>
<?php if (!empty($tile['title'])) : ?>
<h3 class="text-[24px] max-[768px]:text-[20px] font-semibold text-[#1f2937] mb-[16px] text-center">
<?php echo esc_html($tile['title']); ?>
</h3>
<?php endif; ?>
<?php if (!empty($tile['text'])) : ?>
<div class="text-[16px] max-[768px]:text-[14px] text-[#6b7280] leading-[150%] text-center">
<?php echo wp_kses_post($tile['text']); ?>
</div>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</section>

View File

@@ -1,7 +1,7 @@
<?php <?php
//test //test
?> ?>
<div class="bg-black text-white"> <div class="bg-black text-white mt-[24px]">
<div class="mx-auto container"> <div class="mx-auto container">
<div> <div>
Время работы: Время работы:
@@ -25,4 +25,3 @@
</div> </div>
</div> </div>
/

View File

@@ -73,6 +73,21 @@ function register_acf_blocks() {
), ),
)); ));
acf_register_block_type(array(
'name' => 'tiles-block',
'title' => __('Блок с плитками'),
'description' => __('Блок с плитками'),
'render_template' => 'template-parts/la-components/blocks/tiles-block/tiles-block.php',
'category' => 'theme-blocks',
'icon' => 'grid-view',
'keywords' => array('плитки', 'карточки', 'tiles', 'cards'),
'supports' => array(
'align' => array('wide', 'full'),
'anchor' => true,
'customClassName' => true,
),
));
acf_register_block_type(array( acf_register_block_type(array(
'name' => 'reviews-block', 'name' => 'reviews-block',
'title' => __('Блок с отзывами'), 'title' => __('Блок с отзывами'),