commit
11337a4754
@ -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