parent
5afe066576
commit
d21a1ed939
@ -1,40 +1,375 @@ |
|||||||
<?php |
<?php |
||||||
|
|
||||||
add_filter('woocommerce_currency_symbol', 'change_aed_currency_symbol', 10, 2); |
add_filter('woocommerce_currency_symbol', 'change_aed_currency_symbol', 10, 2); |
||||||
|
|
||||||
function change_aed_currency_symbol($currency_symbol, $currency) { |
function change_aed_currency_symbol($currency_symbol, $currency) { |
||||||
if ($currency == 'AED') { |
if ($currency == 'AED') { |
||||||
$currency_symbol = 'AED'; |
$currency_symbol = 'AED'; |
||||||
} |
} |
||||||
return $currency_symbol; |
return $currency_symbol; |
||||||
} |
} |
||||||
|
|
||||||
add_filter('timber/context', function($context) { |
add_filter('timber/context', function($context) { |
||||||
// Передаем все нужные константы в контекст Twig |
// Передаем все нужные константы в контекст Twig |
||||||
$context['CONSTANTS'] = [ |
$context['CONSTANTS'] = [ |
||||||
'DOMAIN' => defined('SITE_DOMAIN') ? SITE_DOMAIN : null, |
'DOMAIN' => defined('SITE_DOMAIN') ? SITE_DOMAIN : null, |
||||||
]; |
]; |
||||||
|
|
||||||
return $context; |
return $context; |
||||||
}); |
}); |
||||||
|
|
||||||
|
|
||||||
// Отключаем канонические ссылки и hreflang от Yoast SEO |
// Отключаем канонические ссылки и hreflang от Yoast SEO |
||||||
add_filter('wpseo_canonical', '__return_false'); |
add_filter('wpseo_canonical', '__return_false'); |
||||||
add_filter('wpseo_opengraph_url', '__return_false'); // Отключаем OG URL |
add_filter('wpseo_opengraph_url', '__return_false'); // Отключаем OG URL |
||||||
add_filter('wpseo_add_x_default_hreflang', '__return_false'); // Отключаем hreflang от Yoast |
add_filter('wpseo_add_x_default_hreflang', '__return_false'); // Отключаем hreflang от Yoast |
||||||
add_filter('wpseo_disable_adjacent_rel_links', '__return_true'); // Отключаем соседние rel-ссылки |
add_filter('wpseo_disable_adjacent_rel_links', '__return_true'); // Отключаем соседние rel-ссылки |
||||||
|
|
||||||
// Добавляем каноническую ссылку |
// Добавляем каноническую ссылку |
||||||
add_action('wp_head', 'custom_canonical_url', 5); |
add_action('wp_head', 'custom_canonical_url', 5); |
||||||
function custom_canonical_url() { |
function custom_canonical_url() { |
||||||
// Защищаем от дублирования |
if (!is_admin()) { |
||||||
static $canonical_added = false; |
// Защищаем от дублирования |
||||||
if ($canonical_added) { |
static $canonical_added = false; |
||||||
return; |
if ($canonical_added) { |
||||||
} |
return; |
||||||
$canonical_added = true; |
} |
||||||
|
$canonical_added = true; |
||||||
$current_url = home_url(add_query_arg('', $_SERVER['REQUEST_URI'])); |
|
||||||
echo '<link rel="canonical" href="' . esc_url($current_url) . '" />' . "\n"; |
// Формируем текущий URL без лишних параметров |
||||||
|
$current_url = trailingslashit(home_url($_SERVER['REQUEST_URI'])); |
||||||
|
// Удаляем возможные параметры запроса, если они не нужны |
||||||
|
$current_url = strtok($current_url, '?'); |
||||||
|
echo '<link rel="canonical" href="' . esc_url($current_url) . '" />' . "\n"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
add_action('wp_head', 'add_facebook_pixel'); |
||||||
|
function add_facebook_pixel() { |
||||||
|
?> |
||||||
|
<!-- Meta Pixel Code --> |
||||||
|
<script> |
||||||
|
!function(f,b,e,v,n,t,s) |
||||||
|
{if(f.fbq)return;n=f.fbq=function(){n.callMethod? |
||||||
|
n.callMethod.apply(n,arguments):n.queue.push(arguments)}; |
||||||
|
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0'; |
||||||
|
n.queue=[];t=b.createElement(e);t.async=!0; |
||||||
|
t.src=v;s=b.getElementsByTagName(e)[0]; |
||||||
|
s.parentNode.insertBefore(t,s)}(window, document,'script', |
||||||
|
'https://connect.facebook.net/en_US/fbevents.js'); |
||||||
|
fbq('init', '1791804684725971'); |
||||||
|
fbq('track', 'PageView'); |
||||||
|
</script> |
||||||
|
<noscript> |
||||||
|
<img height="1" width="1" style="display:none" |
||||||
|
src="https://www.facebook.com/tr?id=1791804684725971&ev=PageView&noscript=1"/> |
||||||
|
</noscript> |
||||||
|
<!-- End Meta Pixel Code --> |
||||||
|
<?php |
||||||
|
} |
||||||
|
|
||||||
|
add_action('wp_footer', 'add_facebook_pixel_events'); |
||||||
|
function add_facebook_pixel_events() { |
||||||
|
// 1. Событие AddToCart (Добавление в корзину) |
||||||
|
if (is_product() || is_shop() || is_cart()) { |
||||||
|
?> |
||||||
|
<script> |
||||||
|
document.addEventListener('DOMContentLoaded', function() { |
||||||
|
jQuery(function($) { |
||||||
|
$(document.body).on('added_to_cart', function(event, fragments, cart_hash, $button) { |
||||||
|
var productId = $button.data('product_id') || ''; |
||||||
|
var quantity = $button.data('quantity') || 1; |
||||||
|
var productName = $button.data('product_sku') || |
||||||
|
$button.closest('.product').find('.woocommerce-loop-product__title').text().trim() || 'Unknown'; |
||||||
|
var priceElement = $button.closest('.product').find('.price .amount').text().replace(/[^0-9.]/g, '') || '0.00'; |
||||||
|
var currency = '<?php echo get_woocommerce_currency(); ?>'; // Динамическая валюта
|
||||||
|
|
||||||
|
// Событие для Facebook Pixel |
||||||
|
fbq('track', 'AddToCart', { |
||||||
|
content_ids: [productId], |
||||||
|
content_type: 'product', |
||||||
|
value: parseFloat(priceElement) * quantity, |
||||||
|
currency: currency |
||||||
|
}); |
||||||
|
|
||||||
|
// Событие для Google Analytics |
||||||
|
window.dataLayer = window.dataLayer || []; |
||||||
|
window.dataLayer.push({ |
||||||
|
'event': 'add_to_cart', |
||||||
|
'ecommerce': { |
||||||
|
'currency': currency, |
||||||
|
'value': parseFloat(priceElement) * quantity, |
||||||
|
'items': [{ |
||||||
|
'item_id': productId, |
||||||
|
'item_name': productName, |
||||||
|
'price': parseFloat(priceElement), |
||||||
|
'quantity': quantity |
||||||
|
}] |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
</script> |
||||||
|
<?php |
||||||
|
} |
||||||
|
|
||||||
|
// 2. Событие Purchase (Покупка) |
||||||
|
if (is_wc_endpoint_url('order-received')) { |
||||||
|
$order_id = absint(get_query_var('order-received')); |
||||||
|
if (!$order_id) return; |
||||||
|
|
||||||
|
$order = wc_get_order($order_id); |
||||||
|
if (!$order || ($order->get_status() !== 'processing' && $order->get_status() !== 'completed')) return; |
||||||
|
|
||||||
|
$items = []; |
||||||
|
foreach ($order->get_items() as $item) { |
||||||
|
$product = $item->get_product(); |
||||||
|
$items[] = [ |
||||||
|
'item_id' => $product->get_id(), |
||||||
|
'item_name' => $product->get_name(), |
||||||
|
'price' => $product->get_price(), |
||||||
|
'quantity' => $item->get_quantity() |
||||||
|
]; |
||||||
|
} |
||||||
|
?> |
||||||
|
<script> |
||||||
|
document.addEventListener('DOMContentLoaded', function() { |
||||||
|
fbq('track', 'Purchase', { |
||||||
|
value: <?php echo $order->get_total(); ?>,
|
||||||
|
currency: '<?php echo $order->get_currency(); ?>',
|
||||||
|
content_ids: [<?php echo implode(',', array_column($items, 'item_id')); ?>],
|
||||||
|
content_type: 'product' |
||||||
|
}); |
||||||
|
|
||||||
|
window.dataLayer = window.dataLayer || []; |
||||||
|
window.dataLayer.push({ |
||||||
|
'event': 'purchase', |
||||||
|
'ecommerce': { |
||||||
|
'currency': '<?php echo $order->get_currency(); ?>',
|
||||||
|
'value': <?php echo $order->get_total(); ?>,
|
||||||
|
'items': <?php echo json_encode($items); ?> |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
</script> |
||||||
|
<?php |
||||||
|
} |
||||||
|
|
||||||
|
// 3. Событие AddPaymentInfo |
||||||
|
if (is_checkout() && !is_wc_endpoint_url('order-received')) { |
||||||
|
$currency = get_woocommerce_currency(); |
||||||
|
$cart_total = WC()->cart ? WC()->cart->get_total('edit') : 0; |
||||||
|
?> |
||||||
|
<script> |
||||||
|
document.addEventListener('DOMContentLoaded', function() { |
||||||
|
fbq('track', 'AddPaymentInfo', { |
||||||
|
value: <?php echo $cart_total; ?>,
|
||||||
|
currency: '<?php echo $currency; ?>'
|
||||||
|
}); |
||||||
|
|
||||||
|
window.dataLayer = window.dataLayer || []; |
||||||
|
window.dataLayer.push({ |
||||||
|
'event': 'add_payment_info', |
||||||
|
'ecommerce': { |
||||||
|
'currency': '<?php echo $currency; ?>',
|
||||||
|
'value': <?php echo $cart_total; ?> |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
</script> |
||||||
|
<?php |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Ваш код для custom_enqueue_ajax_add_to_cart остается без изменений |
||||||
|
add_action('wp_enqueue_scripts', 'custom_enqueue_ajax_add_to_cart'); |
||||||
|
function custom_enqueue_ajax_add_to_cart() { |
||||||
|
// Подключаем скрипт только на странице товара |
||||||
|
if (is_product()) { |
||||||
|
// Убедимся, что jQuery подключен |
||||||
|
wp_enqueue_script('jquery'); |
||||||
|
|
||||||
|
// Inline JavaScript с поддержкой jQuery.noConflict |
||||||
|
$ajax_script = " |
||||||
|
jQuery(document).ready(function($) { |
||||||
|
console.log('AJAX Add to Cart script loaded'); // Отладка: проверяем загрузку скрипта |
||||||
|
|
||||||
|
// Перехват клика по кнопке |
||||||
|
$('.single_add_to_cart_button').on('click', function(e) { |
||||||
|
e.preventDefault(); |
||||||
|
e.stopPropagation(); // Предотвращаем всплытие события |
||||||
|
console.log('Add to cart button clicked'); // Отладка: клик по кнопке |
||||||
|
|
||||||
|
var \$button = $(this); |
||||||
|
var \$form = \$button.closest('form.cart'); |
||||||
|
var product_id = \$button.val(); // Извлекаем product_id из value кнопки |
||||||
|
var quantity = \$form.find('input[name=\"quantity\"]').val() || 1; |
||||||
|
|
||||||
|
// Проверка на корректность product_id |
||||||
|
if (!product_id || isNaN(product_id)) { |
||||||
|
console.log('Invalid product_id:', product_id); // Отладка |
||||||
|
console.log('Error: Неверный ID товара'); |
||||||
|
\$button.removeClass('loading').prop('disabled', false); // Разблокируем кнопку |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// Блокируем кнопку |
||||||
|
\$button.addClass('loading').prop('disabled', true); |
||||||
|
console.log('Sending AJAX request for product_id: ' + product_id + ', quantity: ' + quantity); // Отладка |
||||||
|
|
||||||
|
// Подготовка данных |
||||||
|
var data = { |
||||||
|
action: 'woocommerce_ajax_add_to_cart', |
||||||
|
product_id: product_id, |
||||||
|
quantity: quantity |
||||||
|
}; |
||||||
|
|
||||||
|
// Добавляем поле url, если есть |
||||||
|
var urlField = \$form.find('input[name=\"url\"]'); |
||||||
|
if (urlField.length) { |
||||||
|
data.url = urlField.val(); |
||||||
|
} |
||||||
|
|
||||||
|
$.ajax({ |
||||||
|
type: 'POST', |
||||||
|
url: ajax_object.ajax_url, |
||||||
|
data: data, |
||||||
|
dataType: 'json', |
||||||
|
success: function(response) { |
||||||
|
console.log('AJAX response:', response); // Отладка |
||||||
|
if (response.success) { |
||||||
|
console.log('Товар добавлен в корзину'); // Уведомление в консоли |
||||||
|
// Обновляем фрагменты корзины |
||||||
|
if (response.data.fragments) { |
||||||
|
$.each(response.data.fragments, function(key, value) { |
||||||
|
console.log('Updating fragment:', key); // Отладка |
||||||
|
$(key).replaceWith(value); |
||||||
|
}); |
||||||
|
} |
||||||
|
$(document.body).trigger('wc_fragment_refresh'); |
||||||
|
$(document.body).trigger('added_to_cart', [response.data.fragments, response.data.cart_hash]); |
||||||
|
// Сбрасываем форму |
||||||
|
\$form[0].reset(); |
||||||
|
console.log('Form reset after successful add to cart'); // Отладка |
||||||
|
} else { |
||||||
|
console.log('Error: ' + (response.data.message || 'Ошибка при добавлении товара в корзину')); // Уведомление в консоли |
||||||
|
} |
||||||
|
}, |
||||||
|
error: function(xhr, status, error) { |
||||||
|
console.error('AJAX error:', status, error); // Отладка |
||||||
|
console.log('Error: Произошла ошибка при добавлении товара: ' + error); |
||||||
|
}, |
||||||
|
complete: function() { |
||||||
|
console.log('AJAX request completed'); // Отладка |
||||||
|
\$button.removeClass('loading').prop('disabled', false); // Разблокируем кнопку |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
// Перехват отправки формы |
||||||
|
$('form.cart').on('submit', function(e) { |
||||||
|
e.preventDefault(); |
||||||
|
e.stopPropagation(); // Предотвращаем всплытие |
||||||
|
console.log('Form submit prevented'); // Отладка |
||||||
|
}); |
||||||
|
}); |
||||||
|
"; |
||||||
|
|
||||||
|
wp_add_inline_script('jquery', $ajax_script); |
||||||
|
|
||||||
|
// Передаем AJAX URL |
||||||
|
wp_localize_script('jquery', 'ajax_object', array( |
||||||
|
'ajax_url' => admin_url('admin-ajax.php') |
||||||
|
)); |
||||||
|
|
||||||
|
// Inline CSS |
||||||
|
wp_enqueue_style('woocommerce-custom-styles', get_template_directory_uri() . '/style.css', array(), '1.0'); |
||||||
|
$custom_css = " |
||||||
|
.single_add_to_cart_button.loading { |
||||||
|
opacity: 0.5; |
||||||
|
cursor: not-allowed; |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
.single_add_to_cart_button.loading:after { |
||||||
|
content: ''; |
||||||
|
display: inline-block; |
||||||
|
width: 16px; |
||||||
|
height: 16px; |
||||||
|
border: 2px solid #fff; |
||||||
|
border-radius: 50%; |
||||||
|
border-top-color: transparent; |
||||||
|
animation: spin 1s linear infinite; |
||||||
|
position: absolute; |
||||||
|
right: 10px; |
||||||
|
} |
||||||
|
@keyframes spin { |
||||||
|
100% { |
||||||
|
transform: rotate(360deg); |
||||||
|
} |
||||||
|
} |
||||||
|
"; |
||||||
|
wp_add_inline_style('woocommerce-custom-styles', $custom_css); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Отключаем кэширование для страниц товаров |
||||||
|
add_action('template_redirect', function() { |
||||||
|
if (is_product()) { |
||||||
|
header('Cache-Control: no-cache, no-store, must-revalidate'); |
||||||
|
header('Pragma: no-cache'); |
||||||
|
header('Expires: 0'); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// Обработчик AJAX |
||||||
|
add_action('wp_ajax_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart'); |
||||||
|
add_action('wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart'); |
||||||
|
|
||||||
|
function woocommerce_ajax_add_to_cart() { |
||||||
|
error_log('AJAX handler called'); // Отладка: логируем вызов |
||||||
|
|
||||||
|
$product_id = isset($_POST['product_id']) ? absint($_POST['product_id']) : 0; |
||||||
|
$quantity = isset($_POST['quantity']) ? absint($_POST['quantity']) : 1; |
||||||
|
|
||||||
|
error_log('Received product_id: ' . $product_id . ', quantity: ' . $quantity); // Отладка |
||||||
|
|
||||||
|
if (!$product_id) { |
||||||
|
error_log('Invalid product_id received'); // Отладка |
||||||
|
wp_send_json_error(array('message' => 'Неверный ID товара')); |
||||||
|
wp_die(); |
||||||
|
} |
||||||
|
|
||||||
|
$passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity); |
||||||
|
|
||||||
|
if ($passed_validation) { |
||||||
|
$added = WC()->cart->add_to_cart($product_id, $quantity); |
||||||
|
if ($added) { |
||||||
|
error_log('Product added to cart: ' . $product_id); // Отладка |
||||||
|
// Подготавливаем фрагменты корзины |
||||||
|
ob_start(); |
||||||
|
woocommerce_mini_cart(); |
||||||
|
$mini_cart = ob_get_clean(); |
||||||
|
|
||||||
|
// Фрагменты для стандартной корзины и кастомного счетчика |
||||||
|
$fragments = array( |
||||||
|
'div.widget_shopping_cart_content' => '<div class="widget_shopping_cart_content">' . $mini_cart . '</div>', |
||||||
|
'.mini-profile__button--counter' => '<div class="mini-profile__button--counter">' . WC()->cart->get_cart_contents_count() . '</div>' |
||||||
|
); |
||||||
|
|
||||||
|
wp_send_json_success(array( |
||||||
|
'message' => 'Товар успешно добавлен в корзину', |
||||||
|
'fragments' => apply_filters('woocommerce_add_to_cart_fragments', $fragments), |
||||||
|
'cart_hash' => apply_filters('woocommerce_add_to_cart_hash', WC()->cart->get_cart_hash(), array()) |
||||||
|
)); |
||||||
|
} else { |
||||||
|
error_log('Failed to add product to cart: ' . $product_id); // Отладка |
||||||
|
wp_send_json_error(array('message' => 'Не удалось добавить товар в корзину')); |
||||||
|
} |
||||||
|
} else { |
||||||
|
error_log('Validation failed for product: ' . $product_id); // Отладка |
||||||
|
wp_send_json_error(array('message' => 'Ошибка валидации товара')); |
||||||
|
} |
||||||
|
|
||||||
|
wp_die(); |
||||||
} |
} |
@ -1,502 +1,136 @@ |
|||||||
<?php |
<?php |
||||||
/* |
/* |
||||||
Template Name: Where to byu |
Template Name: Where to Buy |
||||||
Template Post Type: page |
Template Post Type: page |
||||||
*/ |
*/ |
||||||
|
|
||||||
wp_enqueue_style( 'gp-wtb-style', get_template_directory_uri() . '/gp-include/assets/where-to-buy/css/gp-style-core.css?v=1.14' ); |
// Инициализация Timber |
||||||
wp_enqueue_style( 'gp-wtb-style-dt', get_template_directory_uri() . '/gp-include/assets/where-to-buy/css/gp-style-desktop.css?v=1.22' ); |
$context = Timber::context(); |
||||||
wp_enqueue_style( 'gp-wtb-style-tb', get_template_directory_uri() . '/gp-include/assets/where-to-buy/css/gp-style-tablet.css?v=1.22' ); |
|
||||||
wp_enqueue_style( 'gp-wtb-style-mb', get_template_directory_uri() . '/gp-include/assets/where-to-buy/css/gp-style-mobile?v=1.122' ); |
// Подключение стилей |
||||||
|
wp_enqueue_style('gp-wtb-style', get_template_directory_uri() . '/gp-include/assets/where-to-buy/css/gp-style-core.css?v=1.14'); |
||||||
get_header('gp_eng'); |
wp_enqueue_style('gp-wtb-style-dt', get_template_directory_uri() . '/gp-include/assets/where-to-buy/css/gp-style-desktop.css?v=1.22'); |
||||||
// wp_head(); |
wp_enqueue_style('gp-wtb-style-tb', get_template_directory_uri() . '/gp-include/assets/where-to-buy/css/gp-style-tablet.css?v=1.22'); |
||||||
add_filter('wpcf7_autop_or_not', '__return_false'); |
wp_enqueue_style('gp-wtb-style-mb', get_template_directory_uri() . '/gp-include/assets/where-to-buy/css/gp-style-mobile.css?v=1.122'); |
||||||
?> |
|
||||||
|
// Получение данных маркеров из ACF |
||||||
<div class="body-wrap"> |
$locations = get_field('location_markers') ?: []; |
||||||
|
$acf_locations = array_map(function($location) { |
||||||
<main class="wrapper" style="padding-top: 0;"> |
return [ |
||||||
|
'title' => $location['title'], |
||||||
<!-- Where home --> |
'address' => $location['address'], |
||||||
<section class="where-home"> |
'url' => $location['website'], |
||||||
<div class="container"> |
'latitude' => isset($location['latitude']) ? (float)$location['latitude'] : null, |
||||||
<h1>Where to Buy</h1> |
'longitude' => isset($location['longitude']) ? (float)$location['longitude'] : null |
||||||
<p>Looking for Cosmopet products in stores? You can find our premium pet treats in select pet shops and retail stores across the UAE.</p> |
]; |
||||||
</div> |
}, $locations); |
||||||
</section> |
|
||||||
<!-- Where home end --> |
// Предопределенные данные локаций |
||||||
<div class="container"> |
$predefined_locations = [ |
||||||
<?php |
[ |
||||||
// Get marker data from ACF |
'title' => 'Roots Supermarket', |
||||||
$locations = get_field('location_markers'); |
'address' => 'Waves Grande, Retail unit 1-2 Shobha Hartland, Dubai DU United Arab Emirates', |
||||||
?> |
'position' => ['lat' => 25.1896, 'lng' => 55.3662], |
||||||
|
'url' => '' |
||||||
<div class="locations-map-container"> |
], |
||||||
<div id="map" style="width: 100%; height: 600px; border-radius: 20px; overflow: hidden;"></div> |
[ |
||||||
</div> |
'title' => 'Pawdy Neighbors', |
||||||
|
'address' => 'Souk Al Manzil - Old Town Downtown, Dubai, United Arab Emirates', |
||||||
<script> |
'position' => ['lat' => 25.1915, 'lng' => 55.2758], |
||||||
// Array of locations with predefined coordinates |
'url' => '' |
||||||
const locationData = [ |
], |
||||||
{ |
[ |
||||||
title: "Roots Supermarket", |
'title' => 'The Pet Co', |
||||||
address: "Waves Grande, Retail unit 1-2 Shobha Hartland, Dubai DU United Arab Emirates", |
'address' => 'Tower A, Shop 01, Prime Business Centre, JVC, Dubai, UAE', |
||||||
position: { lat: 25.1896, lng: 55.3662 }, |
'position' => ['lat' => 25.0580, 'lng' => 55.2282], |
||||||
url: '' |
'url' => '' |
||||||
}, |
], |
||||||
{ |
[ |
||||||
title: "Pawdy Neighbors", |
'title' => 'Ivy Secret Garden', |
||||||
address: "Souk Al Manzil - Old Town Downtown, Dubai, United Arab Emirates", |
'address' => 'Al Wasl Warehouse Complex, Unit 14 - 26th St - Al Quoz Industrial Area 4 - Dubai', |
||||||
position: { lat: 25.1915, lng: 55.2758 }, |
'position' => ['lat' => 25.1416, 'lng' => 55.2358], |
||||||
url: '' |
'url' => '' |
||||||
}, |
], |
||||||
{ |
[ |
||||||
title: "The Pet Co", |
'title' => 'Petzone', |
||||||
address: "Tower A, Shop 01, Prime Business Centre, JVC, Dubai, UAE", |
'address' => 'Petzone Sheikh Zayed Road - Petzone Umm Suqeim', |
||||||
position: { lat: 25.0580, lng: 55.2282 }, |
'position' => ['lat' => 25.1530, 'lng' => 55.2145], |
||||||
url: '' |
'url' => 'https://petzone.com/uae/en/' |
||||||
}, |
], |
||||||
{ |
[ |
||||||
title: "Ivy Secret Garden", |
'title' => 'Pet Corner', |
||||||
address: "Al Wasl Warehouse Complex, Unit 14 - 26th St - Al Quoz Industrial Area 4 - Dubai", |
'address' => 'Pet Corner Sheikh Zayed Road, Al Fardan Building 1, Sheikh Zayed Road, Next to Deals on Wheels & Business Bay Metro Station', |
||||||
position: { lat: 25.1416, lng: 55.2358 }, |
'position' => ['lat' => 25.1868, 'lng' => 55.2527], |
||||||
url: '' |
'url' => 'https://petcornerdubai.com/' |
||||||
}, |
], |
||||||
{ |
[ |
||||||
title: "Petzone", |
'title' => 'Pet Corner Motor City - Dubai', |
||||||
address: "Petzone Sheikh Zayed Road - Petzone Umm Suqeim", |
'address' => 'Unit R7, Fox Hill 8, Motor City, Opposite Arabian Ranches', |
||||||
position: { lat: 25.1530, lng: 55.2145 }, |
'position' => ['lat' => 25.0499, 'lng' => 55.2350], |
||||||
url: "https://petzone.com/uae/en/" |
'url' => '' |
||||||
}, |
], |
||||||
{ |
[ |
||||||
title: "Pet Corner", |
'title' => 'Pet Corner Jumeirah Golf Estates - Dubai', |
||||||
address: "Pet Corner Sheikh Zayed Road, Al Fardan Building 1, Sheikh Zayed Road, Next to Deals on Wheels & Business Bay Metro Station", |
'address' => 'Shop No. 7, The Fairway Mall Jumeirah Golf Estates Dubai', |
||||||
position: { lat: 25.1868, lng: 55.2527 }, |
'position' => ['lat' => 25.0394, 'lng' => 55.2269], |
||||||
url: "https://petcornerdubai.com/" |
'url' => '' |
||||||
}, |
], |
||||||
{ |
[ |
||||||
title: "Pet Corner Motor City - Dubai", |
'title' => 'Pet Corner Khalifa City - Abu Dhabi', |
||||||
address: "Unit R7, Fox Hill 8, Motor City, Opposite Arabian Ranches", |
'address' => 'Shop No 5, Al Raha Gardens, Khalifa City Abu Dhabi', |
||||||
position: { lat: 25.0499, lng: 55.2350 }, |
'position' => ['lat' => 24.4243, 'lng' => 54.5754], |
||||||
url: '' |
'url' => '' |
||||||
}, |
], |
||||||
{ |
[ |
||||||
title: "Pet Corner Jumeirah Golf Estates - Dubai", |
'title' => 'Pet Corner- Sharjah Al Mamsha', |
||||||
address: "Shop No. 7, The Fairway Mall Jumeirah Golf Estates Dubai", |
'address' => 'Al Sharjah, University Road', |
||||||
position: { lat: 25.0394, lng: 55.2269 }, |
'position' => ['lat' => 25.3126, 'lng' => 55.4783], |
||||||
url: '' |
'url' => '' |
||||||
}, |
], |
||||||
{ |
[ |
||||||
title: "Pet Corner Khalifa City - Abu Dhabi", |
'title' => 'Pet Corner Fujairah- Lulu Mall', |
||||||
address: "Shop No 5, Al Raha Gardens, Khalifa City Abu Dhabi", |
'address' => 'Al - Korthabah Road - Fujairah City Center - Fujairah', |
||||||
position: { lat: 24.4243, lng: 54.5754 }, |
'position' => ['lat' => 25.1221, 'lng' => 56.3244], |
||||||
url: '' |
'url' => '' |
||||||
}, |
], |
||||||
{ |
[ |
||||||
title: "Pet Corner- Sharjah Al Mamsha", |
'title' => 'Tail Waggin Al Quoz', |
||||||
address: "Al Sharjah, University Road", |
'address' => 'Warehouse 7, Street 8, Al Khail Road, Al Quoz 1, Dubai, United Arab Emirates', |
||||||
position: { lat: 25.3126, lng: 55.4783 }, |
'position' => ['lat' => 25.1368, 'lng' => 55.2364], |
||||||
url: '' |
'url' => '' |
||||||
}, |
], |
||||||
{ |
[ |
||||||
title: "Pet Corner Fujairah- Lulu Mall", |
'title' => "Tail Waggin' Pet Spa Dubai Hills", |
||||||
address: "Al - Korthabah Road - Fujairah City Center - Fujairah", |
'address' => 'SWAY Residences, Retail 2 - near Kings College Hospital Dubai Hills Estate - Dubai - United Arab Emirates', |
||||||
position: { lat: 25.1221, lng: 56.3244 }, |
'position' => ['lat' => 25.1276, 'lng' => 55.2714], |
||||||
url: '' |
'url' => '' |
||||||
}, |
], |
||||||
{ |
[ |
||||||
title: "Tail Waggin Al Quoz", |
'title' => 'Goofy Groom', |
||||||
address: "Warehouse 7, Street 8, Al Khail Road, Al Quoz 1, Dubai, United Arab Emirates", |
'address' => 'Dubai, UAE Midtown Central Majan, Shop G-17', |
||||||
position: { lat: 25.1368, lng: 55.2364 }, |
'position' => ['lat' => 25.0834, 'lng' => 55.1743], |
||||||
url: '' |
'url' => '' |
||||||
}, |
] |
||||||
{ |
]; |
||||||
title: "Tail Waggin' Pet Spa Dubai Hills", |
|
||||||
address: "SWAY Residences, Retail 2 - near Kings College Hospital Dubai Hills Estate - Dubai - United Arab Emirates", |
// Получение изображений из галереи ACF |
||||||
position: { lat: 25.1276, lng: 55.2714 }, |
$partners_logos = get_field('partners_logos') ?: []; |
||||||
url: '' |
$partners_logos_formatted = array_map(function($image) { |
||||||
}, |
return [ |
||||||
{ |
'url' => esc_url($image['title']), |
||||||
title: "Goofy Groom", |
'src' => esc_url($image['sizes']['medium']), |
||||||
address: "Dubai, UAE Midtown Central Majan, Shop G-17", |
'alt' => esc_attr($image['alt']) |
||||||
position: { lat: 25.0834, lng: 55.1743 }, |
]; |
||||||
url: '' |
}, $partners_logos); |
||||||
} |
|
||||||
]; |
// Добавление данных в контекст |
||||||
|
$context['acf_locations'] = $acf_locations; |
||||||
// Get data from ACF with added latitude and longitude fields |
$context['predefined_locations'] = $predefined_locations; |
||||||
const acfLocations = <?php
|
$context['partners_logos'] = $partners_logos_formatted; |
||||||
if ($locations && !empty($locations)) { |
|
||||||
echo json_encode(array_map(function($location) { |
// Отключение автопараграфов для Contact Form 7 |
||||||
return [ |
add_filter('wpcf7_autop_or_not', '__return_false'); |
||||||
'title' => $location['title'], |
|
||||||
'address' => $location['address'], |
// Рендеринг шаблона |
||||||
'url' => $location['website'], |
Timber::render('templates/where_to_buy/wtb.twig', $context); |
||||||
'latitude' => isset($location['latitude']) ? (float)$location['latitude'] : null, |
?> |
||||||
'longitude' => isset($location['longitude']) ? (float)$location['longitude'] : null |
|
||||||
]; |
|
||||||
}, $locations)); |
|
||||||
} else { |
|
||||||
echo 'null'; |
|
||||||
} |
|
||||||
?>; |
|
||||||
|
|
||||||
// Map initialization function |
|
||||||
function initMap() { |
|
||||||
console.log("Map is initializing"); |
|
||||||
|
|
||||||
// Map center - approximately Dubai center |
|
||||||
const dubai = { lat: 25.2048, lng: 55.2708 }; |
|
||||||
|
|
||||||
// Create map |
|
||||||
const map = new google.maps.Map(document.getElementById("map"), { |
|
||||||
zoom: 11, |
|
||||||
center: dubai, |
|
||||||
styles: [ |
|
||||||
{ |
|
||||||
"featureType": "water", |
|
||||||
"elementType": "geometry", |
|
||||||
"stylers": [ |
|
||||||
{ |
|
||||||
"color": "#93d5eb" |
|
||||||
} |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
"featureType": "landscape", |
|
||||||
"elementType": "geometry", |
|
||||||
"stylers": [ |
|
||||||
{ |
|
||||||
"color": "#f5f5f5" |
|
||||||
} |
|
||||||
] |
|
||||||
} |
|
||||||
] |
|
||||||
}); |
|
||||||
|
|
||||||
// Info window for markers |
|
||||||
const infoWindow = new google.maps.InfoWindow(); |
|
||||||
|
|
||||||
// If ACF data exists, use it for markers |
|
||||||
if (acfLocations && acfLocations.length > 0) { |
|
||||||
console.log("Using ACF data:", acfLocations.length, "locations"); |
|
||||||
|
|
||||||
const geocoder = new google.maps.Geocoder(); |
|
||||||
|
|
||||||
// Create and place markers |
|
||||||
acfLocations.forEach((location, i) => { |
|
||||||
// Check if we have manual coordinates |
|
||||||
if (location.latitude && location.longitude) { |
|
||||||
console.log(`Using manual coordinates for: ${location.title}`); |
|
||||||
const position = { lat: location.latitude, lng: location.longitude }; |
|
||||||
createMarker(location, position, map, infoWindow); |
|
||||||
} else { |
|
||||||
// No coordinates provided, try geocoding |
|
||||||
console.log(`Geocoding address: ${location.address}`); |
|
||||||
|
|
||||||
geocoder.geocode({ address: location.address }, (results, status) => { |
|
||||||
if (status === "OK") { |
|
||||||
console.log(`Geocoding successful for: ${location.title}`); |
|
||||||
createMarker(location, results[0].geometry.location, map, infoWindow); |
|
||||||
} else { |
|
||||||
console.error(`Geocode failed for address: ${location.address}. Reason: ${status}`); |
|
||||||
|
|
||||||
// If geocoding fails, try to find matching location in predefined data |
|
||||||
const predefinedLocation = locationData.find(item => |
|
||||||
item.title.toLowerCase() === location.title.toLowerCase() || |
|
||||||
item.address.toLowerCase().includes(location.address.toLowerCase()) |
|
||||||
); |
|
||||||
|
|
||||||
if (predefinedLocation) { |
|
||||||
console.log(`Using predefined coordinates for: ${location.title}`); |
|
||||||
createMarker(location, predefinedLocation.position, map, infoWindow); |
|
||||||
} |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
}); |
|
||||||
} else { |
|
||||||
// Use predefined data |
|
||||||
console.log("Using predefined data:", locationData.length, "locations"); |
|
||||||
|
|
||||||
locationData.forEach((location) => { |
|
||||||
createMarker(location, location.position, map, infoWindow); |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
// Marker creation function |
|
||||||
function createMarker(location, position, map, infoWindow) { |
|
||||||
// Create marker |
|
||||||
const marker = new google.maps.Marker({ |
|
||||||
map: map, |
|
||||||
position: position, |
|
||||||
animation: google.maps.Animation.DROP, |
|
||||||
icon: { |
|
||||||
url: 'https://maps.google.com/mapfiles/ms/icons/blue-dot.png' |
|
||||||
} |
|
||||||
}); |
|
||||||
|
|
||||||
// Add click event handler for marker |
|
||||||
marker.addListener("click", () => { |
|
||||||
let content = `<div><h3>${location.title}</h3><p>${location.address}</p>`; |
|
||||||
|
|
||||||
if (location.url) { |
|
||||||
content += `<p><a href="${location.url}" target="_blank">Visit website</a></p>`; |
|
||||||
} |
|
||||||
|
|
||||||
content += `</div>`; |
|
||||||
|
|
||||||
infoWindow.setContent(content); |
|
||||||
infoWindow.open(map, marker); |
|
||||||
}); |
|
||||||
|
|
||||||
// Add slight delay for animation |
|
||||||
setTimeout(() => { |
|
||||||
marker.setAnimation(null); |
|
||||||
}, 750); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// Check if Google Maps API is loaded |
|
||||||
window.addEventListener('load', function() { |
|
||||||
if (typeof google === 'undefined' || typeof google.maps === 'undefined') { |
|
||||||
console.error('Google Maps API failed to load'); |
|
||||||
document.getElementById('map').innerHTML = '<div style="padding: 20px; text-align: center;">Map loading error. Please check your internet connection and refresh the page.</div>'; |
|
||||||
} else { |
|
||||||
console.log('Google Maps API loaded successfully'); |
|
||||||
} |
|
||||||
}); |
|
||||||
</script> |
|
||||||
|
|
||||||
<!-- Google Maps API connection with your key --> |
|
||||||
<script async defer |
|
||||||
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDQVXQyGsqWmUdJ84UgKOPymFlISaKoiuw&callback=initMap&libraries=places"> |
|
||||||
</script> |
|
||||||
</div> |
|
||||||
<br><br> |
|
||||||
<!-- Find us --> |
|
||||||
<section class="find-us"> |
|
||||||
<div class="container"> |
|
||||||
<h2>📍 Find us at:</h2> |
|
||||||
<ul> |
|
||||||
<?php |
|
||||||
$items = get_field('location_markers'); |
|
||||||
foreach($items as $item): |
|
||||||
?> |
|
||||||
<li> |
|
||||||
<h3> |
|
||||||
<?php if($item['website']): ?> |
|
||||||
<a href="<?php echo $item['website'];?>"><?php echo $item['title'];?></a>
|
|
||||||
<?php endif; ?> |
|
||||||
<?php if(!$item['website']): ?> |
|
||||||
<?php echo $item['title'];?> |
|
||||||
<?php endif; ?> |
|
||||||
</h3> |
|
||||||
<p><?php echo $item['address'];?></p>
|
|
||||||
</li> |
|
||||||
<?php endforeach; ?> |
|
||||||
</ul> |
|
||||||
</div> |
|
||||||
</section> |
|
||||||
<!-- Find us end --> |
|
||||||
|
|
||||||
|
|
||||||
<style> |
|
||||||
.sell-form-form:not(.submited) + .thx-text{ |
|
||||||
display:none; |
|
||||||
} |
|
||||||
.sell-form-form.submited{ |
|
||||||
display:none; |
|
||||||
} |
|
||||||
</style> |
|
||||||
<!-- Sell form --> |
|
||||||
|
|
||||||
<div class="container"> |
|
||||||
<?php |
|
||||||
// Получаем изображения из галереи ACF |
|
||||||
$images = get_field('partners_logos'); |
|
||||||
if ($images): ?> |
|
||||||
<!-- Бегущая строка (слайдер) --> |
|
||||||
<div class="partners-slider-section"> |
|
||||||
<h3 style="font-size:36px;">Our partners</h3> |
|
||||||
<div class="partners-swiper swiper"> |
|
||||||
<div class="swiper-wrapper"> |
|
||||||
<?php
|
|
||||||
// Повторяем логотипы больше раз для создания эффекта бесконечности |
|
||||||
for ($i = 0; $i < 5; $i++) { |
|
||||||
foreach($images as $image): ?> |
|
||||||
<div class="swiper-slide"> |
|
||||||
<a href="<?php echo esc_url($image['title']); ?>" target="_blank">
|
|
||||||
<img src="<?php echo esc_url($image['sizes']['medium']); ?>" alt="<?php echo esc_attr($image['alt']); ?>">
|
|
||||||
</a> |
|
||||||
</div> |
|
||||||
<?php endforeach;
|
|
||||||
} ?> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<script> |
|
||||||
document.addEventListener('DOMContentLoaded', function() { |
|
||||||
const swiper = new Swiper('.partners-swiper', { |
|
||||||
slidesPerView: 'auto', |
|
||||||
spaceBetween: 30, |
|
||||||
loop: true, |
|
||||||
loopedSlides: 999, |
|
||||||
loopAdditionalSlides: 999, |
|
||||||
centeredSlides: false, |
|
||||||
autoplay: { |
|
||||||
delay: 1, // Почти нулевая задержка |
|
||||||
disableOnInteraction: false, // Автоплей не отключается при взаимодействии |
|
||||||
}, |
|
||||||
speed: 8000, // Медленная скорость для плавности |
|
||||||
allowTouchMove: false, // Отключаем свайп вручную |
|
||||||
freeMode: false, // Свободный скроллинг |
|
||||||
cssMode: false, |
|
||||||
watchSlidesProgress: true, |
|
||||||
simulateTouch: false, |
|
||||||
observer: true, |
|
||||||
observeParents: true, |
|
||||||
resistanceRatio: 0, |
|
||||||
breakpoints: { |
|
||||||
320: { |
|
||||||
slidesPerView: 2, |
|
||||||
}, |
|
||||||
768: { |
|
||||||
slidesPerView: 4, |
|
||||||
}, |
|
||||||
1024: { |
|
||||||
slidesPerView: 5, |
|
||||||
} |
|
||||||
} |
|
||||||
}); |
|
||||||
|
|
||||||
// Принудительно перезапускаем автоплей после касания |
|
||||||
swiper.el.addEventListener('touchend', function() { |
|
||||||
if (!swiper.autoplay.running) { |
|
||||||
swiper.autoplay.start(); // Перезапускаем автоплей, если он остановлен |
|
||||||
} |
|
||||||
}); |
|
||||||
}); |
|
||||||
</script> |
|
||||||
<style> |
|
||||||
/* Стили для слайдера */ |
|
||||||
.partners-slider-section, |
|
||||||
.partners-grid-section { |
|
||||||
margin: 50px 0; |
|
||||||
} |
|
||||||
.partners-slider-section { |
|
||||||
overflow: hidden; /* Скрываем переполнение */ |
|
||||||
} |
|
||||||
.partners-swiper { |
|
||||||
width: 100%; |
|
||||||
padding: 20px 0; |
|
||||||
} |
|
||||||
.swiper-slide { |
|
||||||
text-align: center; |
|
||||||
height: auto; |
|
||||||
width: auto !important; /* Позволяем слайдам быть разной ширины */ |
|
||||||
} |
|
||||||
.swiper-slide img { |
|
||||||
max-height: 60px; |
|
||||||
width: auto; |
|
||||||
filter: grayscale(100%); |
|
||||||
transition: filter 0.3s; |
|
||||||
object-fit: contain; |
|
||||||
} |
|
||||||
.swiper-slide img:hover { |
|
||||||
filter: grayscale(0%); |
|
||||||
} |
|
||||||
/* Убираем анимацию трансформации для устранения рывков */ |
|
||||||
.swiper-wrapper { |
|
||||||
position: relative; |
|
||||||
width: 100%; |
|
||||||
height: 100px; |
|
||||||
z-index: 1; |
|
||||||
display: flex; |
|
||||||
box-sizing: content-box; |
|
||||||
transition-timing-function: linear !important; |
|
||||||
} |
|
||||||
/* Стили для плиток */ |
|
||||||
.partners-grid { |
|
||||||
display: grid; |
|
||||||
grid-template-columns: repeat(4, 1fr); |
|
||||||
gap: 20px; |
|
||||||
} |
|
||||||
.grid-item { |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
justify-content: center; |
|
||||||
padding: 20px; |
|
||||||
/* border: 1px solid #eee; */ |
|
||||||
border-radius: 24px; |
|
||||||
transition: 0.3s; |
|
||||||
} |
|
||||||
.grid-item:hover { |
|
||||||
box-shadow: 0 10px 20px rgba(0,0,0,0.1); |
|
||||||
} |
|
||||||
.grid-item img { |
|
||||||
max-height: 60px; |
|
||||||
max-width: 100%; |
|
||||||
filter: grayscale(100%); |
|
||||||
transition: filter 0.3s; |
|
||||||
} |
|
||||||
.grid-item img:hover { |
|
||||||
filter: grayscale(0%); |
|
||||||
} |
|
||||||
h3 { |
|
||||||
font-size: 26px; |
|
||||||
color: #fff; |
|
||||||
text-transform: uppercase; |
|
||||||
font-weight: bold; |
|
||||||
} |
|
||||||
@media (max-width: 768px) { |
|
||||||
.partners-grid { |
|
||||||
grid-template-columns: repeat(2, 1fr); |
|
||||||
} |
|
||||||
.grid-item { |
|
||||||
width: 80%; |
|
||||||
margin: 0 auto; |
|
||||||
} |
|
||||||
} |
|
||||||
@media (max-width: 480px) { |
|
||||||
.partners-grid { |
|
||||||
grid-template-columns: 1fr; |
|
||||||
} |
|
||||||
} |
|
||||||
</style> |
|
||||||
<?php endif; ?> |
|
||||||
</div> |
|
||||||
|
|
||||||
<section class="sell-form"> |
|
||||||
<div class="container sell-form__container"> |
|
||||||
|
|
||||||
<h2>Want to sell Cosmopet in your store?</h2> |
|
||||||
<p>Join our growing network of retailers! Fill out the contact form below, and we’ll get in touch to discuss the details.</p> |
|
||||||
<form action="" class="form--contact sell-form-form"> |
|
||||||
|
|
||||||
<input type="hidden" name="action" value="message" > |
|
||||||
<input type="text" placeholder="Your Name" name="name" class="form-inp"> |
|
||||||
<input type="tel" placeholder="Your Phone" name="phone" class="form-inp" id=""> |
|
||||||
<input type="email" placeholder="E-mail" name="email" class="form-inp" id=""> |
|
||||||
<textarea placeholder="Message" class="form-textarea" name="msg" id=""></textarea> |
|
||||||
<button type="submit">SUBMIT</button> |
|
||||||
|
|
||||||
|
|
||||||
</form> |
|
||||||
<div class="thx-text"> |
|
||||||
<h2>Thanks for request!</h2> |
|
||||||
<p>We will answer your message as soon as possible</p> |
|
||||||
|
|
||||||
</div> |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div> |
|
||||||
</section> |
|
||||||
<!-- Sell form end --> |
|
||||||
|
|
||||||
</main> |
|
||||||
</div> |
|
||||||
|
|
||||||
<?php get_footer('gp_eng'); ?> |
|
@ -0,0 +1,365 @@ |
|||||||
|
{% set bodyClass = 'main-np' %} |
||||||
|
|
||||||
|
{% extends 'layout.twig' %} |
||||||
|
|
||||||
|
{% block content %} |
||||||
|
<div class="body-wrap"> |
||||||
|
<main class="wrapper" style="padding-top: 0;"> |
||||||
|
<!-- Where home --> |
||||||
|
<section class="where-home"> |
||||||
|
<div class="container"> |
||||||
|
<h1>Where to Buy</h1> |
||||||
|
<p>Looking for Cosmopet products in stores? You can find our premium pet treats in select pet shops and retail stores across the UAE.</p> |
||||||
|
</div> |
||||||
|
</section> |
||||||
|
<!-- Where home end --> |
||||||
|
|
||||||
|
<div class="container"> |
||||||
|
<div class="locations-map-container"> |
||||||
|
<div id="map" style="width: 100%; height: 600px; border-radius: 20px; overflow: hidden;"></div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<script> |
||||||
|
// Данные локаций из PHP (через Timber) |
||||||
|
const locationData = {{ predefined_locations|json_encode|raw }}; |
||||||
|
|
||||||
|
// Данные из ACF |
||||||
|
const acfLocations = {{ acf_locations|json_encode|raw }}; |
||||||
|
|
||||||
|
// Функция инициализации карты |
||||||
|
function initMap() { |
||||||
|
console.log("Map is initializing"); |
||||||
|
|
||||||
|
// Центр карты - Дубай |
||||||
|
const dubai = { lat: 25.2048, lng: 55.2708 }; |
||||||
|
|
||||||
|
// Создание карты |
||||||
|
const map = new google.maps.Map(document.getElementById("map"), { |
||||||
|
zoom: 11, |
||||||
|
center: dubai, |
||||||
|
styles: [ |
||||||
|
{ |
||||||
|
"featureType": "water", |
||||||
|
"elementType": "geometry", |
||||||
|
"stylers": [ |
||||||
|
{ |
||||||
|
"color": "#93d5eb" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
"featureType": "landscape", |
||||||
|
"elementType": "geometry", |
||||||
|
"stylers": [ |
||||||
|
{ |
||||||
|
"color": "#f5f5f5" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
] |
||||||
|
}); |
||||||
|
|
||||||
|
// Окно с информацией для маркеров |
||||||
|
const infoWindow = new google.maps.InfoWindow(); |
||||||
|
|
||||||
|
// Если есть данные ACF, используем их для маркеров |
||||||
|
if (acfLocations && acfLocations.length > 0) { |
||||||
|
console.log("Using ACF data:", acfLocations.length, "locations"); |
||||||
|
|
||||||
|
const geocoder = new google.maps.Geocoder(); |
||||||
|
|
||||||
|
// Создание и размещение маркеров |
||||||
|
acfLocations.forEach((location, i) => { |
||||||
|
// Проверка наличия координат |
||||||
|
if (location.latitude && location.longitude) { |
||||||
|
console.log(`Using manual coordinates for: ${location.title}`); |
||||||
|
const position = { lat: location.latitude, lng: location.longitude }; |
||||||
|
createMarker(location, position, map, infoWindow); |
||||||
|
} else { |
||||||
|
// Координаты отсутствуют, пробуем геокодирование |
||||||
|
console.log(`Geocoding address: ${location.address}`); |
||||||
|
|
||||||
|
geocoder.geocode({ address: location.address }, (results, status) => { |
||||||
|
if (status === "OK") { |
||||||
|
console.log(`Geocoding successful for: ${location.title}`); |
||||||
|
createMarker(location, results[0].geometry.location, map, infoWindow); |
||||||
|
} else { |
||||||
|
console.error(`Geocode failed for address: ${location.address}. Reason: ${status}`); |
||||||
|
|
||||||
|
// Если геокодирование не удалось, ищем совпадение в предопределенных данных |
||||||
|
const predefinedLocation = locationData.find(item => |
||||||
|
item.title.toLowerCase() === location.title.toLowerCase() || |
||||||
|
item.address.toLowerCase().includes(location.address.toLowerCase()) |
||||||
|
); |
||||||
|
|
||||||
|
if (predefinedLocation) { |
||||||
|
console.log(`Using predefined coordinates for: ${location.title}`); |
||||||
|
createMarker(location, predefinedLocation.position, map, infoWindow); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}); |
||||||
|
} else { |
||||||
|
// Используем предопределенные данные |
||||||
|
console.log("Using predefined data:", locationData.length, "locations"); |
||||||
|
|
||||||
|
locationData.forEach((location) => { |
||||||
|
createMarker(location, location.position, map, infoWindow); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
// Функция создания маркера |
||||||
|
function createMarker(location, position, map, infoWindow) { |
||||||
|
// Создание маркера |
||||||
|
const marker = new google.maps.Marker({ |
||||||
|
map: map, |
||||||
|
position: position, |
||||||
|
animation: google.maps.Animation.DROP, |
||||||
|
icon: { |
||||||
|
url: 'https://maps.google.com/mapfiles/ms/icons/blue-dot.png' |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// Обработчик клика по маркеру |
||||||
|
marker.addListener("click", () => { |
||||||
|
let content = `<div><h3>${location.title}</h3><p>${location.address}</p>`; |
||||||
|
|
||||||
|
if (location.url) { |
||||||
|
content += `<p><a href="${location.url}" target="_blank">Visit website</a></p>`; |
||||||
|
} |
||||||
|
|
||||||
|
content += `</div>`; |
||||||
|
|
||||||
|
infoWindow.setContent(content); |
||||||
|
infoWindow.open(map, marker); |
||||||
|
}); |
||||||
|
|
||||||
|
// Отключение анимации после небольшой задержки |
||||||
|
setTimeout(() => { |
||||||
|
marker.setAnimation(null); |
||||||
|
}, 750); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Проверка загрузки Google Maps API |
||||||
|
window.addEventListener('load', function() { |
||||||
|
if (typeof google === 'undefined' || typeof google.maps === 'undefined') { |
||||||
|
console.error('Google Maps API failed to load'); |
||||||
|
document.getElementById('map').innerHTML = '<div style="padding: 20px; text-align: center;">Map loading error. Please check your internet connection and refresh the page.</div>'; |
||||||
|
} else { |
||||||
|
console.log('Google Maps API loaded successfully'); |
||||||
|
} |
||||||
|
}); |
||||||
|
</script> |
||||||
|
|
||||||
|
<!-- Подключение Google Maps API --> |
||||||
|
<script async defer |
||||||
|
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDQVXQyGsqWmUdJ84UgKOPymFlISaKoiuw&callback=initMap&libraries=places"> |
||||||
|
</script> |
||||||
|
</div> |
||||||
|
<br><br> |
||||||
|
|
||||||
|
<!-- Find us --> |
||||||
|
<section class="find-us"> |
||||||
|
<div class="container"> |
||||||
|
<h2>📍 Find us at:</h2> |
||||||
|
<ul> |
||||||
|
{% for item in acf_locations %} |
||||||
|
<li> |
||||||
|
<h3> |
||||||
|
{% if item.url %} |
||||||
|
<a href="{{ item.url }}">{{ item.title }}</a> |
||||||
|
{% else %} |
||||||
|
{{ item.title }} |
||||||
|
{% endif %} |
||||||
|
</h3> |
||||||
|
<p>{{ item.address }}</p> |
||||||
|
</li> |
||||||
|
{% endfor %} |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
</section> |
||||||
|
<!-- Find us end --> |
||||||
|
|
||||||
|
<style> |
||||||
|
.sell-form-form:not(.submited) + .thx-text { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
.sell-form-form.submited { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
</style> |
||||||
|
|
||||||
|
<div class="container"> |
||||||
|
{% if partners_logos %} |
||||||
|
<!-- Бегущая строка (слайдер) --> |
||||||
|
<div class="partners-slider-section"> |
||||||
|
<h3 style="font-size: 36px;">Our partners</h3> |
||||||
|
<div class="partners-swiper swiper"> |
||||||
|
<div class="swiper-wrapper"> |
||||||
|
{% for i in 1..5 %} |
||||||
|
{% for image in partners_logos %} |
||||||
|
<div class="swiper-slide"> |
||||||
|
<a href="{{ image.url }}" target="_blank"> |
||||||
|
<img src="{{ image.src }}" alt="{{ image.alt }}"> |
||||||
|
</a> |
||||||
|
</div> |
||||||
|
{% endfor %} |
||||||
|
{% endfor %} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<script> |
||||||
|
document.addEventListener('DOMContentLoaded', function() { |
||||||
|
const swiper = new Swiper('.partners-swiper', { |
||||||
|
slidesPerView: 'auto', |
||||||
|
spaceBetween: 30, |
||||||
|
loop: true, |
||||||
|
loopedSlides: 999, |
||||||
|
loopAdditionalSlides: 999, |
||||||
|
centeredSlides: false, |
||||||
|
autoplay: { |
||||||
|
delay: 1, |
||||||
|
disableOnInteraction: false, |
||||||
|
}, |
||||||
|
speed: 8000, |
||||||
|
allowTouchMove: false, |
||||||
|
freeMode: false, |
||||||
|
cssMode: false, |
||||||
|
watchSlidesProgress: true, |
||||||
|
simulateTouch: false, |
||||||
|
observer: true, |
||||||
|
observeParents: true, |
||||||
|
resistanceRatio: 0, |
||||||
|
breakpoints: { |
||||||
|
320: { |
||||||
|
slidesPerView: 2, |
||||||
|
}, |
||||||
|
768: { |
||||||
|
slidesPerView: 4, |
||||||
|
}, |
||||||
|
1024: { |
||||||
|
slidesPerView: 5, |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
swiper.el.addEventListener('touchend', function() { |
||||||
|
if (!swiper.autoplay.running) { |
||||||
|
swiper.autoplay.start(); |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
</script> |
||||||
|
|
||||||
|
<style> |
||||||
|
/* Стили для слайдера */ |
||||||
|
.partners-slider-section, |
||||||
|
.partners-grid-section { |
||||||
|
margin: 50px 0; |
||||||
|
} |
||||||
|
.partners-slider-section { |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
.partners-swiper { |
||||||
|
width: 100%; |
||||||
|
padding: 20px 0; |
||||||
|
} |
||||||
|
.swiper-slide { |
||||||
|
text-align: center; |
||||||
|
height: auto; |
||||||
|
width: auto !important; |
||||||
|
} |
||||||
|
.swiper-slide img { |
||||||
|
max-height: 60px; |
||||||
|
width: auto; |
||||||
|
filter: grayscale(100%); |
||||||
|
transition: filter 0.3s; |
||||||
|
object-fit: contain; |
||||||
|
} |
||||||
|
.swiper-slide img:hover { |
||||||
|
filter: grayscale(0%); |
||||||
|
} |
||||||
|
.swiper-wrapper { |
||||||
|
position: relative; |
||||||
|
width: 100%; |
||||||
|
height: 100px; |
||||||
|
z-index: 1; |
||||||
|
display: flex; |
||||||
|
box-sizing: content-box; |
||||||
|
transition-timing-function: linear !important; |
||||||
|
} |
||||||
|
.partners-grid { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: repeat(4, 1fr); |
||||||
|
gap: 20px; |
||||||
|
} |
||||||
|
.grid-item { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
padding: 20px; |
||||||
|
border-radius: 24px; |
||||||
|
transition: 0.3s; |
||||||
|
} |
||||||
|
.grid-item:hover { |
||||||
|
box-shadow: 0 10px 20px rgba(0,0,0,0.1); |
||||||
|
} |
||||||
|
.grid-item img { |
||||||
|
max-height: 60px; |
||||||
|
max-width: 100%; |
||||||
|
filter: grayscale(100%); |
||||||
|
transition: filter 0.3s; |
||||||
|
} |
||||||
|
.grid-item img:hover { |
||||||
|
filter: grayscale(0%); |
||||||
|
} |
||||||
|
h3 { |
||||||
|
font-size: 26px; |
||||||
|
color: #fff; |
||||||
|
text-transform: uppercase; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
@media (max-width: 768px) { |
||||||
|
.partners-grid { |
||||||
|
grid-template-columns: repeat(2, 1fr); |
||||||
|
} |
||||||
|
.grid-item { |
||||||
|
width: 80%; |
||||||
|
margin: 0 auto; |
||||||
|
} |
||||||
|
} |
||||||
|
@media (max-width: 480px) { |
||||||
|
.partners-grid { |
||||||
|
grid-template-columns: 1fr; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
|
{% endif %} |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- Sell form --> |
||||||
|
<section class="sell-form"> |
||||||
|
<div class="container sell-form__container"> |
||||||
|
<h2>Want to sell Cosmopet in your store?</h2> |
||||||
|
<p>Join our growing network of retailers! Fill out the contact form below, and we’ll get in touch to discuss the details.</p> |
||||||
|
<form action="" class="form--contact sell-form-form"> |
||||||
|
<input type="hidden" name="action" value="message"> |
||||||
|
<input type="text" placeholder="Your Name" name="name" class="form-inp"> |
||||||
|
<input type="tel" placeholder="Your Phone" name="phone" class="form-inp"> |
||||||
|
<input type="email" placeholder="E-mail" name="email" class="form-inp"> |
||||||
|
<textarea placeholder="Message" class="form-textarea" name="msg"></textarea> |
||||||
|
<button type="submit">SUBMIT</button> |
||||||
|
</form> |
||||||
|
<div class="thx-text"> |
||||||
|
<h2>Thanks for request!</h2> |
||||||
|
<p>We will answer your message as soon as possible</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</section> |
||||||
|
<!-- Sell form end --> |
||||||
|
</main> |
||||||
|
</div> |
||||||
|
{% endblock %} |
Loading…
Reference in new issue