161 lines
8.5 KiB
Text
161 lines
8.5 KiB
Text
|
|
---
|
|||
|
|
import { CONTACT_CONSTANTS } from '@constants/constants.ts';
|
|||
|
|
|
|||
|
|
interface Props {
|
|||
|
|
variant?: 'full' | 'card' | 'simple';
|
|||
|
|
title?: string;
|
|||
|
|
subtitle?: string;
|
|||
|
|
address?: string;
|
|||
|
|
mapUrl?: string;
|
|||
|
|
showRouteButton?: boolean;
|
|||
|
|
lazyLoad?: boolean;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const {
|
|||
|
|
variant = 'full',
|
|||
|
|
title = "Наш офис",
|
|||
|
|
subtitle = "г. Сургут, пр. Комсомольский, 19",
|
|||
|
|
address = CONTACT_CONSTANTS.address,
|
|||
|
|
mapUrl = "https://yandex.ru/maps/-/CDu~yK-j",
|
|||
|
|
showRouteButton = true,
|
|||
|
|
lazyLoad = true
|
|||
|
|
} = Astro.props;
|
|||
|
|
|
|||
|
|
const defaultMapUrl = "https://yandex.ru/map-widget/v1/?um=constructor%3Acdxezk6x&source=constructor";
|
|||
|
|
const currentMapUrl = variant === 'card' ? defaultMapUrl : mapUrl;
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
{variant === 'full' ? (
|
|||
|
|
<div class="w-full px-4 md:container md:mx-auto md:px-4 md:max-w-7xl mb-12">
|
|||
|
|
<section id="map-section" class="relative w-full h-[500px] overflow-hidden rounded-3xl shadow-2xl">
|
|||
|
|
<div class="absolute inset-0 bg-gray-200">
|
|||
|
|
<iframe
|
|||
|
|
data-src={currentMapUrl}
|
|||
|
|
class="map-iframe w-full h-full border-0 grayscale contrast-125 opacity-0 transition-opacity duration-700"
|
|||
|
|
allowfullscreen
|
|||
|
|
loading={lazyLoad ? "lazy" : "eager"}
|
|||
|
|
title="Карта проезда"
|
|||
|
|
></iframe>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="absolute inset-0 flex items-center justify-center pointer-events-none">
|
|||
|
|
<div class="bg-white/95 backdrop-blur-xl p-8 md:p-10 rounded-2xl shadow-2xl max-w-sm text-center pointer-events-auto border border-white/50 mx-4">
|
|||
|
|
<div class="w-16 h-16 bg-gradient-to-br from-[var(--color-gold)] to-[var(--color-gold-hover)] rounded-2xl flex items-center justify-center mx-auto mb-6 shadow-lg">
|
|||
|
|
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/>
|
|||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/>
|
|||
|
|
</svg>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<h3 class="text-gray-900 font-bold text-lg uppercase tracking-wider mb-3">
|
|||
|
|
{title}
|
|||
|
|
</h3>
|
|||
|
|
|
|||
|
|
<p class="text-gray-600 mb-6 leading-relaxed">
|
|||
|
|
{address}
|
|||
|
|
</p>
|
|||
|
|
|
|||
|
|
{showRouteButton && (
|
|||
|
|
<a
|
|||
|
|
href={currentMapUrl}
|
|||
|
|
target="_blank"
|
|||
|
|
rel="noopener noreferrer"
|
|||
|
|
class="inline-flex items-center gap-2 px-6 py-3 bg-gray-900 text-white text-sm font-bold uppercase tracking-wider rounded-xl hover:bg-[var(--color-gold)] transition-colors shadow-lg hover:shadow-xl"
|
|||
|
|
>
|
|||
|
|
Открыть в картах
|
|||
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
|
|||
|
|
</svg>
|
|||
|
|
</a>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
</div>
|
|||
|
|
) : variant === 'card' ? (
|
|||
|
|
<div class="relative bg-white/80 backdrop-blur-xl border border-white/50 rounded-3xl overflow-hidden shadow-2xl shadow-gray-900/5 hover:shadow-2xl hover:shadow-[var(--color-blue-primary)]/10 transition-all duration-500 group">
|
|||
|
|
<div class="absolute inset-0 bg-gradient-to-b from-transparent via-transparent to-gray-100/80 pointer-events-none z-10"></div>
|
|||
|
|
|
|||
|
|
<div class="relative z-20 p-8 pb-0 flex flex-col items-center text-center md:flex-row md:items-center md:justify-between gap-4">
|
|||
|
|
<div>
|
|||
|
|
<h2 class="text-xl sm:text-2xl md:text-3xl font-bold text-gray-900 mb-2 flex items-center gap-3 justify-center md:justify-start">
|
|||
|
|
<span class="w-2 h-6 sm:h-8 bg-gradient-to-b from-[var(--color-gold)] to-[var(--color-gold-hover)] rounded-full hidden md:block"></span>
|
|||
|
|
{title}
|
|||
|
|
</h2>
|
|||
|
|
<p class="text-gray-600 text-base sm:text-lg flex items-center gap-2 justify-center md:justify-start">
|
|||
|
|
<svg class="w-4 sm:w-5 h-4 sm:h-5 text-[var(--color-gold)] hidden md:block" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/>
|
|||
|
|
</svg>
|
|||
|
|
{subtitle}
|
|||
|
|
</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{showRouteButton && (
|
|||
|
|
<a href={currentMapUrl} target="_blank" class="inline-flex items-center justify-center gap-2 px-4 sm:px-6 py-2 sm:py-3 bg-[var(--color-gold)]/10 hover:bg-[var(--color-gold)]/20 text-[var(--color-gold)] font-semibold rounded-xl transition-all duration-300 border border-[var(--color-gold)]/20 hover:border-[var(--color-gold)]/40 self-center md:self-auto">
|
|||
|
|
<span class="text-sm sm:text-base">Маршрут</span>
|
|||
|
|
<svg class="w-4 sm:w-5 h-4 sm:h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
|
|||
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
|||
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M4 20L20 4" opacity="0.2" stroke-width="1" />
|
|||
|
|
</svg>
|
|||
|
|
</a>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="relative h-[450px] mt-8 bg-gray-100 overflow-hidden">
|
|||
|
|
<iframe
|
|||
|
|
src={currentMapUrl}
|
|||
|
|
width="100%"
|
|||
|
|
height="100%"
|
|||
|
|
frameborder="0"
|
|||
|
|
class="filter grayscale-[30%] contrast-125 group-hover:grayscale-0 transition-all duration-700"
|
|||
|
|
loading={lazyLoad ? "lazy" : "eager"}
|
|||
|
|
title="Офис на карте Сургута"
|
|||
|
|
></iframe>
|
|||
|
|
|
|||
|
|
<div class="absolute inset-0 flex items-center justify-center bg-gray-900/0 group-hover:bg-gray-900/0 transition-all duration-500 pointer-events-none">
|
|||
|
|
<span class="px-4 sm:px-6 py-2 sm:py-3 bg-white/95 backdrop-blur-sm text-gray-900 rounded-full text-xs sm:text-sm font-bold border border-gray-200 shadow-xl transform translate-y-4 opacity-0 group-hover:translate-y-0 group-hover:opacity-100 transition-all duration-500 pointer-events-auto cursor-pointer hover:bg-[var(--color-gold)] hover:text-white hover:border-[var(--color-gold)]">
|
|||
|
|
Наведите для взаимодействия
|
|||
|
|
</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
) : (
|
|||
|
|
<div class="relative h-[400px] bg-gray-100 overflow-hidden rounded-xl">
|
|||
|
|
<iframe
|
|||
|
|
src={currentMapUrl}
|
|||
|
|
width="100%"
|
|||
|
|
height="100%"
|
|||
|
|
frameborder="0"
|
|||
|
|
loading={lazyLoad ? "lazy" : "eager"}
|
|||
|
|
title="Карта"
|
|||
|
|
></iframe>
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
|
|||
|
|
{lazyLoad && variant === 'full' && (
|
|||
|
|
<script>
|
|||
|
|
const mapSection = document.getElementById('map-section');
|
|||
|
|
const iframe = mapSection?.querySelector('.map-iframe');
|
|||
|
|
|
|||
|
|
if (mapSection && iframe) {
|
|||
|
|
const observer = new IntersectionObserver((entries) => {
|
|||
|
|
entries.forEach(entry => {
|
|||
|
|
if (entry.isIntersecting) {
|
|||
|
|
const frame = entry.target.querySelector('iframe');
|
|||
|
|
if (frame && frame.dataset.src) {
|
|||
|
|
frame.src = frame.dataset.src;
|
|||
|
|
frame.onload = () => {
|
|||
|
|
frame.classList.remove('opacity-0');
|
|||
|
|
frame.classList.add('opacity-100');
|
|||
|
|
};
|
|||
|
|
observer.unobserve(entry.target);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}, { rootMargin: '200px', threshold: 0.1 });
|
|||
|
|
|
|||
|
|
observer.observe(mapSection);
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
)}
|