Switch to version 92: modified src/app/page.tsx
This commit is contained in:
545
src/app/page.tsx
545
src/app/page.tsx
@@ -11,22 +11,191 @@ import FaqBase from "@/components/sections/faq/FaqBase";
|
||||
import ContactCenter from "@/components/sections/contact/ContactCenter";
|
||||
import FooterBaseReveal from "@/components/sections/footer/FooterBaseReveal";
|
||||
import {
|
||||
AlertCircle,
|
||||
CheckCircle,
|
||||
Clock,
|
||||
Droplets,
|
||||
MessageSquare,
|
||||
Phone,
|
||||
Shield,
|
||||
Sparkles,
|
||||
Truck,
|
||||
Waves,
|
||||
Wind,
|
||||
Zap,
|
||||
ArrowRight,
|
||||
Home,
|
||||
Send,
|
||||
Plus,
|
||||
Minus,
|
||||
Radio,
|
||||
Check,
|
||||
MessageCircle,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
Lock,
|
||||
Star,
|
||||
Users,
|
||||
Award,
|
||||
PhoneCall
|
||||
PhoneCall,
|
||||
} from "lucide-react";
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
export default function LandingPage() {
|
||||
const [squareMeters, setSquareMeters] = useState(10);
|
||||
const [cleaningType, setCleaningType] = useState("Standard");
|
||||
const [odorRemoval, setOdorRemoval] = useState(false);
|
||||
const [sliderPosition, setSliderPosition] = useState(50);
|
||||
const [currentBeforeAfterIndex, setCurrentBeforeAfterIndex] = useState(0);
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [mapLoading, setMapLoading] = useState(true);
|
||||
const [ymaps, setYmaps] = useState<any>(null);
|
||||
const [mapInstance, setMapInstance] = useState<any>(null);
|
||||
|
||||
const cleaningTypePrices: Record<string, number> = {
|
||||
Standard: 2500,
|
||||
Premium: 4500,
|
||||
Urgent: 3500,
|
||||
};
|
||||
|
||||
const basePricePerSqm = cleaningTypePrices[cleaningType] || 2500;
|
||||
const subtotal = basePricePerSqm * squareMeters;
|
||||
const odorCost = odorRemoval ? squareMeters * 500 : 0;
|
||||
const totalPrice = subtotal + odorCost;
|
||||
|
||||
const beforeAfterImages = [
|
||||
{
|
||||
before: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3B75MEFIsDC4pJvttFBrgrNRsQ6/uploaded-1774096488811-xievpagm.jpg", after: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3B75MEFIsDC4pJvttFBrgrNRsQ6/uploaded-1774096488811-4glyyjmt.jpg", title: "Восстановление яркости цветов", badge: "Восстановление цвета"
|
||||
},
|
||||
{
|
||||
before: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3B75MEFIsDC4pJvttFBrgrNRsQ6/uploaded-1773997364635-pnmy1wtw.jpg", after: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3B75MEFIsDC4pJvttFBrgrNRsQ6/uploaded-1773997364636-4en53z94.png", title: "Глубокая чистка восточного ковра", badge: "Премиум чистка"
|
||||
},
|
||||
{
|
||||
before: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3B75MEFIsDC4pJvttFBrgrNRsQ6/uploaded-1774096917946-t435vzpj.jpg", after: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3B75MEFIsDC4pJvttFBrgrNRsQ6/uploaded-1774096917947-7qok4c00.png", title: "Удаление пятен от вина", badge: "Удаление пятен"
|
||||
},
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
// Load Yandex Maps API
|
||||
const script = document.createElement('script');
|
||||
script.src = 'https://api-maps.yandex.ru/2.1/?apikey=4b0c70a7-60e5-47ea-99e8-da1c79edac0a&lang=ru_RU';
|
||||
script.async = true;
|
||||
script.onload = () => {
|
||||
if ((window as any).ymaps) {
|
||||
(window as any).ymaps.ready(() => {
|
||||
setYmaps((window as any).ymaps);
|
||||
initializeMap((window as any).ymaps);
|
||||
});
|
||||
}
|
||||
};
|
||||
script.onerror = () => {
|
||||
setMapLoading(false);
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
|
||||
return () => {
|
||||
const existingScript = document.querySelector('script[src*="api-maps.yandex.ru"]');
|
||||
if (existingScript) {
|
||||
existingScript.remove();
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
const initializeMap = (ymapsLib: any) => {
|
||||
try {
|
||||
const map = new ymapsLib.Map('yandex-map', {
|
||||
center: [42.364157, 69.625689],
|
||||
zoom: 15,
|
||||
});
|
||||
|
||||
// Disable scroll zoom
|
||||
map.behaviors.disable('scrollZoom');
|
||||
|
||||
// Add marker with home icon
|
||||
const placemark = new ymapsLib.Placemark(
|
||||
[42.364157, 69.625689],
|
||||
{
|
||||
balloonContent: `
|
||||
<div style="padding: 8px; font-family: Arial, sans-serif;">
|
||||
<h3 style="margin: 0 0 8px 0; font-size: 14px; font-weight: bold; color: #000;">Центр чистки ковров «Нурсат»</h3>
|
||||
<p style="margin: 4px 0; font-size: 12px; color: #666;">Адрес: мкр. Нурсат, 107/2</p>
|
||||
<p style="margin: 4px 0; font-size: 12px; color: #666;">Город: Шымкент, Казахстан</p>
|
||||
<p style="margin: 8px 0 0 0; font-size: 12px; color: #0066cc;">
|
||||
<a href="tel:+77763413030" style="color: #0066cc; text-decoration: none;">+7 776 341 30 30</a>
|
||||
</p>
|
||||
</div>
|
||||
`,
|
||||
},
|
||||
{
|
||||
preset: 'islands#blueDotIcon',
|
||||
iconColor: '#0066cc',
|
||||
}
|
||||
);
|
||||
|
||||
map.geoObjects.add(placemark);
|
||||
placemark.balloon.open();
|
||||
|
||||
setMapInstance(map);
|
||||
setMapLoading(false);
|
||||
} catch (error) {
|
||||
console.error('Error initializing map:', error);
|
||||
setMapLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleWhatsAppOrder = () => {
|
||||
const message = `Заказ услуги по чистке ковров:\n- Площадь: ${squareMeters} м²\n- Тип чистки: ${cleaningType}\n- Удаление запахов: ${odorRemoval ? 'Да' : 'Нет'}\n- Примерная стоимость: ${totalPrice.toLocaleString()} ₸`;
|
||||
const encodedMessage = encodeURIComponent(message);
|
||||
window.open(`https://wa.me/77763413030?text=${encodedMessage}`, "_blank");
|
||||
};
|
||||
|
||||
const goToPrevious = () => {
|
||||
setCurrentBeforeAfterIndex(
|
||||
currentBeforeAfterIndex === 0 ? beforeAfterImages.length - 1 : currentBeforeAfterIndex - 1
|
||||
);
|
||||
};
|
||||
|
||||
const goToNext = () => {
|
||||
setCurrentBeforeAfterIndex(
|
||||
(currentBeforeAfterIndex + 1) % beforeAfterImages.length
|
||||
);
|
||||
};
|
||||
|
||||
const currentImage = beforeAfterImages[currentBeforeAfterIndex];
|
||||
|
||||
const handleMouseDown = () => {
|
||||
setIsDragging(true);
|
||||
};
|
||||
|
||||
const handleMouseUp = () => {
|
||||
setIsDragging(false);
|
||||
};
|
||||
|
||||
const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
|
||||
if (!isDragging) return;
|
||||
const container = e.currentTarget;
|
||||
const rect = container.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left;
|
||||
const percentage = Math.max(0, Math.min(100, (x / rect.width) * 100));
|
||||
setSliderPosition(percentage);
|
||||
};
|
||||
|
||||
const handleTouchStart = () => {
|
||||
setIsDragging(true);
|
||||
};
|
||||
|
||||
const handleTouchEnd = () => {
|
||||
setIsDragging(false);
|
||||
};
|
||||
|
||||
const handleTouchMove = (e: React.TouchEvent<HTMLDivElement>) => {
|
||||
if (!isDragging) return;
|
||||
const container = e.currentTarget;
|
||||
const rect = container.getBoundingClientRect();
|
||||
const x = e.touches[0].clientX - rect.left;
|
||||
const percentage = Math.max(0, Math.min(100, (x / rect.width) * 100));
|
||||
setSliderPosition(percentage);
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
@@ -48,7 +217,7 @@ export default function LandingPage() {
|
||||
{ name: "Главная", id: "/" },
|
||||
{ name: "Услуги", id: "/services" },
|
||||
{ name: "О нас", id: "#process" },
|
||||
{ name: "Контакты", id: "#contact" }
|
||||
{ name: "Контакты", id: "#contact" },
|
||||
]}
|
||||
button={{
|
||||
text: "Заказать чистку", href: "#contact"
|
||||
@@ -74,11 +243,11 @@ export default function LandingPage() {
|
||||
},
|
||||
{
|
||||
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3B75MEFIsDC4pJvttFBrgrNRsQ6/uploaded-1773828380271-bsmriduf.webp?_wi=1", imageAlt: "Профессиональная чистка ковров"
|
||||
}
|
||||
},
|
||||
]}
|
||||
buttons={[
|
||||
{ text: "Оставить заявку", href: "#contact" },
|
||||
{ text: "Позвонить", href: "tel:+77763413030" }
|
||||
{ text: "Позвонить", href: "tel:+77763413030" },
|
||||
]}
|
||||
background={{ variant: "plain" }}
|
||||
buttonAnimation="slide-up"
|
||||
@@ -111,11 +280,339 @@ export default function LandingPage() {
|
||||
{
|
||||
title: "Защита и обработка", description: "Антибактериальная и водоотталкивающая обработка ковра. Защита на долгий срок от грязи и влаги.", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3B75MEFIsDC4pJvttFBrgrNRsQ6/uploaded-1773828380271-bsmriduf.webp?_wi=3", imageAlt: "Защита и обработка", buttonIcon: ArrowRight,
|
||||
buttonHref: "#contact"
|
||||
}
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="calculator" data-section="calculator">
|
||||
<div className="relative w-full overflow-hidden py-16 md:py-20 lg:py-24">
|
||||
<div className="mx-auto flex w-full max-w-[var(--width-content-width)] flex-col gap-8 px-[var(--vw-1_5)] md:flex-row md:gap-12">
|
||||
{/* Calculator Form */}
|
||||
<div className="flex flex-1 flex-col gap-8">
|
||||
<div>
|
||||
<h2 className="text-4xl font-bold md:text-5xl mb-2">Калькулятор стоимости</h2>
|
||||
<p className="text-base text-gray-600 md:text-lg">Рассчитайте стоимость чистки ковра за несколько секунд</p>
|
||||
</div>
|
||||
|
||||
{/* Cleaning Type Dropdown */}
|
||||
<div className="flex flex-col gap-4">
|
||||
<label className="text-sm font-semibold">Тип чистки</label>
|
||||
<select
|
||||
value={cleaningType}
|
||||
onChange={(e) => setCleaningType(e.target.value)}
|
||||
className="rounded-lg border border-gray-300 bg-white p-3 font-medium outline-none focus:border-blue-500 transition-colors"
|
||||
aria-label="Тип чистки"
|
||||
>
|
||||
<option value="Standard">Стандартная (2,500₸/м²)</option>
|
||||
<option value="Premium">Премиум (4,500₸/м²)</option>
|
||||
<option value="Urgent">Срочная (3,500₸/м²)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Square Meter Stepper */}
|
||||
<div className="flex flex-col gap-4">
|
||||
<label className="text-sm font-semibold">Площадь ковра (м²)</label>
|
||||
<div className="flex items-center gap-4 rounded-lg border border-gray-300 bg-white p-3">
|
||||
<button
|
||||
onClick={() => setSquareMeters(Math.max(1, squareMeters - 1))}
|
||||
className="flex items-center justify-center w-10 h-10 rounded-lg hover:bg-gray-100 transition-colors"
|
||||
aria-label="Уменьшить площадь"
|
||||
>
|
||||
<Minus size={20} />
|
||||
</button>
|
||||
<input
|
||||
type="number"
|
||||
min="1"
|
||||
max="200"
|
||||
value={squareMeters}
|
||||
onChange={(e) => setSquareMeters(Math.max(1, parseInt(e.target.value) || 1))}
|
||||
className="flex-1 text-center text-2xl font-bold outline-none"
|
||||
aria-label="Площадь ковра"
|
||||
/>
|
||||
<button
|
||||
onClick={() => setSquareMeters(Math.min(200, squareMeters + 1))}
|
||||
className="flex items-center justify-center w-10 h-10 rounded-lg hover:bg-gray-100 transition-colors"
|
||||
aria-label="Увеличить площадь"
|
||||
>
|
||||
<Plus size={20} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Odor Removal Checkbox */}
|
||||
<div className="flex flex-col gap-4">
|
||||
<label className="text-sm font-semibold">Дополнительные услуги</label>
|
||||
<label className="flex items-center gap-3 cursor-pointer p-3 rounded-lg border border-gray-300 hover:bg-gray-50 transition-colors">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={odorRemoval}
|
||||
onChange={(e) => setOdorRemoval(e.target.checked)}
|
||||
className="w-5 h-5 cursor-pointer"
|
||||
aria-label="Удаление запахов"
|
||||
/>
|
||||
<div className="flex-1">
|
||||
<div className="font-medium">Удаление запахов</div>
|
||||
<div className="text-sm text-gray-500">500₸/м² (защита от неприятных запахов)</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Price Summary Sidebar */}
|
||||
<div className="flex-1 flex flex-col gap-6">
|
||||
<div className="sticky top-20 bg-gradient-to-br from-blue-50 to-indigo-50 rounded-2xl p-6">
|
||||
<h3 className="text-lg font-semibold mb-6">Итоговая стоимость</h3>
|
||||
|
||||
{/* Trust Badge */}
|
||||
<div className="mb-6 p-4 bg-white rounded-lg border border-green-200 flex items-start gap-3">
|
||||
<Lock size={20} className="text-green-600 flex-shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<div className="font-semibold text-green-800">100% Гарантия возврата</div>
|
||||
<div className="text-sm text-green-700">Цена зафиксирована после осмотра</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Price Breakdown */}
|
||||
<div className="space-y-4 mb-6 pb-6 border-b border-blue-200">
|
||||
<div className="flex justify-between text-sm">
|
||||
<span className="text-gray-600">Базовая услуга:</span>
|
||||
<span className="font-semibold">{subtotal.toLocaleString()} ₸</span>
|
||||
</div>
|
||||
{odorRemoval && (
|
||||
<div className="flex justify-between text-sm">
|
||||
<span className="text-gray-600">Удаление запахов:</span>
|
||||
<span className="font-semibold">{odorCost.toLocaleString()} ₸</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex justify-between text-sm">
|
||||
<span className="text-gray-600">Площадь:</span>
|
||||
<span className="font-semibold">{squareMeters} м²</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-sm">
|
||||
<span className="text-gray-600">Тип чистки:</span>
|
||||
<span className="font-semibold">{cleaningType}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Total Price */}
|
||||
<div className="mb-6">
|
||||
<div className="text-sm text-gray-600 mb-2">Примерная стоимость</div>
|
||||
<div className="text-4xl font-bold text-blue-600">{totalPrice.toLocaleString()} ₸</div>
|
||||
<div className="text-xs text-gray-500 mt-2">*Финальная цена уточняется после осмотра ковра</div>
|
||||
</div>
|
||||
|
||||
{/* Phone Call Button */}
|
||||
<a
|
||||
href="tel:+77763413030"
|
||||
className="w-full bg-blue-600 hover:bg-blue-700 text-white font-semibold py-3 rounded-lg flex items-center justify-center gap-2 transition-colors mb-3"
|
||||
aria-label="Позвонить в компанию"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<PhoneCall size={20} />
|
||||
Позвонить
|
||||
</a>
|
||||
|
||||
{/* WhatsApp Order Button */}
|
||||
<button
|
||||
onClick={handleWhatsAppOrder}
|
||||
className="w-full bg-green-500 hover:bg-green-600 text-white font-semibold py-3 rounded-lg flex items-center justify-center gap-2 transition-colors"
|
||||
aria-label="Заказать через WhatsApp"
|
||||
>
|
||||
<MessageCircle size={20} />
|
||||
Написать на WhatsApp
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="before-after" data-section="before-after">
|
||||
<div className="relative w-full overflow-hidden py-16 md:py-20 lg:py-24">
|
||||
<div className="mx-auto flex w-full max-w-[var(--width-content-width)] flex-col gap-12 px-[var(--vw-1_5)]">
|
||||
{/* Header */}
|
||||
<div className="flex flex-col gap-4">
|
||||
<h2 className="text-4xl font-bold md:text-5xl">Результат нашей работы</h2>
|
||||
<p className="text-base text-gray-600 md:text-lg">Посмотрите впечатляющие трансформации наших проектов — от грязных ковров к идеальной чистоте</p>
|
||||
</div>
|
||||
|
||||
{/* Before/After Carousel */}
|
||||
<div className="flex flex-col gap-8">
|
||||
{/* Interactive Slider Container */}
|
||||
<div
|
||||
className="relative rounded-2xl overflow-hidden bg-gray-100 cursor-ew-resize select-none"
|
||||
onMouseDown={handleMouseDown}
|
||||
onMouseUp={handleMouseUp}
|
||||
onMouseLeave={handleMouseUp}
|
||||
onMouseMove={handleMouseMove}
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
onTouchMove={handleTouchMove}
|
||||
>
|
||||
<div className="relative w-full min-h-96 md:min-h-[500px]">
|
||||
{/* Before Image (Full Background) */}
|
||||
<div className="absolute inset-0 overflow-hidden">
|
||||
<img
|
||||
src={currentImage.before}
|
||||
alt="Before"
|
||||
className="w-full h-full object-cover"
|
||||
draggable={false}
|
||||
onLoad={() => setMapLoading(false)}
|
||||
/>
|
||||
{mapLoading && (
|
||||
<div className="absolute inset-0 flex items-center justify-center bg-gray-200">
|
||||
<div className="text-center">
|
||||
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"></div>
|
||||
<p className="text-gray-700 font-medium">Загрузка карты мкр. Нурсат...</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="absolute top-4 left-4 bg-red-500 text-white px-3 py-1 rounded-full text-sm font-semibold pointer-events-none">
|
||||
ДО
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* After Image (Clipped by slider) */}
|
||||
<div
|
||||
className="absolute inset-0 overflow-hidden"
|
||||
style={{ width: `${sliderPosition}%` }}
|
||||
>
|
||||
<img
|
||||
src={currentImage.after}
|
||||
alt="After"
|
||||
className="w-full h-full object-cover"
|
||||
style={{ width: `${(100 / sliderPosition) * 100}%` }}
|
||||
draggable={false}
|
||||
/>
|
||||
<div className="absolute top-4 right-4 bg-green-500 text-white px-3 py-1 rounded-full text-sm font-semibold pointer-events-none">
|
||||
ПОСЛЕ
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Slider Handle */}
|
||||
<div
|
||||
className="absolute top-0 bottom-0 w-1 bg-white shadow-lg"
|
||||
style={{ left: `${sliderPosition}%`, transform: 'translateX(-50%)' }}
|
||||
>
|
||||
{/* Handle Button */}
|
||||
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-white rounded-full p-2 shadow-lg pointer-events-none">
|
||||
<div className="flex gap-1">
|
||||
<ChevronLeft size={20} className="text-gray-700" />
|
||||
<ChevronRight size={20} className="text-gray-700" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Badge */}
|
||||
<div className="absolute bottom-4 left-1/2 transform -translate-x-1/2 bg-blue-600 text-white px-4 py-2 rounded-full text-sm font-semibold pointer-events-none">
|
||||
{currentImage.badge}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Info and Navigation */}
|
||||
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-6">
|
||||
{/* Title */}
|
||||
<div>
|
||||
<h3 className="text-2xl font-bold">{currentImage.title}</h3>
|
||||
<p className="text-gray-600 text-sm mt-2">
|
||||
Проект {currentBeforeAfterIndex + 1} из {beforeAfterImages.length}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Navigation Buttons */}
|
||||
<div className="flex gap-3">
|
||||
<button
|
||||
onClick={goToPrevious}
|
||||
className="flex items-center justify-center w-12 h-12 rounded-full border-2 border-gray-300 hover:border-blue-600 hover:bg-blue-50 transition-all"
|
||||
aria-label="Предыдущий проект"
|
||||
>
|
||||
<ChevronLeft size={24} className="text-gray-600" />
|
||||
</button>
|
||||
<button
|
||||
onClick={goToNext}
|
||||
className="flex items-center justify-center w-12 h-12 rounded-full border-2 border-gray-300 hover:border-blue-600 hover:bg-blue-50 transition-all"
|
||||
aria-label="Следующий проект"
|
||||
>
|
||||
<ChevronRight size={24} className="text-gray-600" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Dots Navigation */}
|
||||
<div className="flex gap-2 justify-center">
|
||||
{beforeAfterImages.map((_, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() => setCurrentBeforeAfterIndex(index)}
|
||||
className={`w-3 h-3 rounded-full transition-all ${
|
||||
index === currentBeforeAfterIndex
|
||||
? "bg-blue-600 w-8"
|
||||
: "bg-gray-300 hover:bg-gray-400"
|
||||
}`}
|
||||
aria-label={`Перейти к проекту ${index + 1}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="map" data-section="map">
|
||||
<div className="relative w-full overflow-hidden py-16 md:py-20 lg:py-24">
|
||||
<div className="mx-auto flex w-full max-w-[var(--width-content-width)] flex-col gap-12 px-[var(--vw-1_5)]">
|
||||
{/* Header */}
|
||||
<div className="flex flex-col gap-4">
|
||||
<h2 className="text-4xl font-bold md:text-5xl">Наше местоположение</h2>
|
||||
<p className="text-base text-gray-600 md:text-lg">Найдите нас по адресу мкр. Нурсат, 107/2 в Шымкенте. Проведем консультацию по всем вопросам чистки ковров.</p>
|
||||
</div>
|
||||
|
||||
{/* Yandex Map Container */}
|
||||
<div className="relative rounded-2xl overflow-hidden shadow-lg">
|
||||
{mapLoading && (
|
||||
<div className="absolute inset-0 flex items-center justify-center bg-gray-200 z-10">
|
||||
<div className="text-center">
|
||||
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"></div>
|
||||
<p className="text-gray-700 font-medium">Загрузка карты мкр. Нурсат...</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
id="yandex-map"
|
||||
className="w-full h-96 md:h-[500px] bg-gray-100"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Contact Information */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div className="p-6 bg-blue-50 rounded-xl">
|
||||
<h3 className="font-bold text-lg mb-2">Адрес</h3>
|
||||
<p className="text-gray-700">мкр. Нурсат, 107/2</p>
|
||||
<p className="text-gray-600 text-sm mt-1">Шымкент, Казахстан</p>
|
||||
</div>
|
||||
<div className="p-6 bg-blue-50 rounded-xl">
|
||||
<h3 className="font-bold text-lg mb-2">Телефон</h3>
|
||||
<a href="tel:+77763413030" className="text-blue-600 hover:text-blue-700 font-semibold flex items-center gap-2" target="_blank" rel="noopener noreferrer">
|
||||
<PhoneCall size={20} />
|
||||
+7 776 341 30 30
|
||||
</a>
|
||||
<p className="text-gray-600 text-sm mt-2">Доступны с 9:00 до 20:00</p>
|
||||
</div>
|
||||
<div className="p-6 bg-green-50 rounded-xl">
|
||||
<h3 className="font-bold text-lg mb-2">WhatsApp</h3>
|
||||
<a href="https://wa.me/77763413030?text=Здравствуйте!%20Я%20хочу%20узнать%20больше%20о%20ваших%20услугах%20по%20чистке%20ковров." className="text-green-600 hover:text-green-700 font-semibold" target="_blank" rel="noopener noreferrer">
|
||||
Написать сообщение
|
||||
</a>
|
||||
<p className="text-gray-600 text-sm mt-2">Быстрый ответ на ваши вопросы</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="process" data-section="process">
|
||||
<FeatureBento
|
||||
title="Как мы работаем"
|
||||
@@ -128,8 +625,8 @@ export default function LandingPage() {
|
||||
title: "Заявка", description: "Обсуждаем детали и фиксируем цену", bentoComponent: "icon-info-cards", items: [
|
||||
{ icon: Phone, label: "Телефон", value: "+7 776 341 30 30" },
|
||||
{ icon: Clock, label: "Время ответа", value: "В течение часа" },
|
||||
{ icon: CheckCircle, label: "Консультация", value: "Бесплатная" }
|
||||
]
|
||||
{ icon: CheckCircle, label: "Консультация", value: "Бесплатная" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Забор / Выезд", description: "Приезжаем со своим оборудованием и химией", bentoComponent: "timeline", heading: "Этап доставки", subheading: "Удобный сервис для вас", items: [
|
||||
@@ -141,7 +638,7 @@ export default function LandingPage() {
|
||||
},
|
||||
{
|
||||
label: "Забор на склад", detail: "Аккуратно упаковываем ковер"
|
||||
}
|
||||
},
|
||||
],
|
||||
completedLabel: "Готово"
|
||||
},
|
||||
@@ -149,8 +646,8 @@ export default function LandingPage() {
|
||||
title: "Процесс чистки", description: "Удаляем пятна, запахи и пылевых клещей", bentoComponent: "3d-task-list", items: [
|
||||
{ icon: Droplets, label: "Предварительная обработка", time: "15 мин" },
|
||||
{ icon: Waves, label: "Основная стирка", time: "30 мин" },
|
||||
{ icon: Wind, label: "Отжим и сушка", time: "20 мин" }
|
||||
]
|
||||
{ icon: Wind, label: "Отжим и сушка", time: "20 мин" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Доставка", description: "Доставляем свежий, чистый ковер на дом", bentoComponent: "timeline", heading: "Финальный этап", subheading: "Ковер готов к использованию", items: [
|
||||
@@ -162,10 +659,10 @@ export default function LandingPage() {
|
||||
},
|
||||
{
|
||||
label: "Установка", detail: "Помогаем расположить ковер на месте"
|
||||
}
|
||||
},
|
||||
],
|
||||
completedLabel: "Завершено"
|
||||
}
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
@@ -186,7 +683,7 @@ export default function LandingPage() {
|
||||
{
|
||||
id: "3", name: "Жанар К.", handle: "Клиент", testimonial: "Профессиональный подход и внимательное отношение. Цена честная, работа быстрая. Буду заказывать еще. Спасибо!", rating: 5,
|
||||
imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3B75MEFIsDC4pJvttFBrgrNRsQ6/uploaded-1773838829021-h67xp226.jpg?_wi=1", imageAlt: "Клиент Марат"
|
||||
}
|
||||
},
|
||||
]}
|
||||
showRating={true}
|
||||
animationType="slide-up"
|
||||
@@ -208,22 +705,22 @@ export default function LandingPage() {
|
||||
price: "от 2,500₸", subtitle: "за м² чистки", buttons: [{ text: "Рассчитать стоимость", href: "#calculator" }],
|
||||
features: [
|
||||
"Стандартная чистка ковра", "Использование эко-средств", "Быстрая сушка", "Консультация специалиста"
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "premium", badge: "Премиум", badgeIcon: Sparkles,
|
||||
price: "от 4,500₸", subtitle: "за м² химчистки", buttons: [{ text: "Рассчитать стоимость", href: "#calculator" }],
|
||||
features: [
|
||||
"Глубокая химическая чистка", "Удаление пятен и запахов", "Антибактериальная обработка", "Водоотталкивающая защита"
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "express", badge: "Срочно", badgeIcon: Zap,
|
||||
price: "от 3,500₸", subtitle: "за м² срочной доставки", buttons: [{ text: "Рассчитать стоимость", href: "#calculator" }],
|
||||
features: [
|
||||
"Выездная чистка на дом", "Экспресс-обработка", "Быстрая доставка (24 часа)", "Гарантия качества"
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
@@ -320,25 +817,25 @@ export default function LandingPage() {
|
||||
{ label: "О нас", href: "#process" },
|
||||
{ label: "Услуги", href: "/services" },
|
||||
{ label: "Цены", href: "#pricing" },
|
||||
{ label: "Контакты", href: "#contact" }
|
||||
]
|
||||
{ label: "Контакты", href: "#contact" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Услуги", items: [
|
||||
{ label: "Чистка ковров", href: "/services" },
|
||||
{ label: "Химчистка", href: "/services" },
|
||||
{ label: "Удаление пятен", href: "/services" },
|
||||
{ label: "Выездная чистка", href: "/services" }
|
||||
]
|
||||
{ label: "Выездная чистка", href: "/services" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Контакты", items: [
|
||||
{ label: "Телефон: +7 776 341 30 30", href: "tel:+77763413030" },
|
||||
{ label: "Адрес: Шымкент", href: "https://yandex.kz/maps/-/CPRbzOPdL" },
|
||||
{ label: "WhatsApp", href: "https://wa.me/77763413030?text=Здравствуйте!%20Я%20хочу%20узнать%20больше%20о%20ваших%20услугах%20по%20чистке%20ковров." },
|
||||
{ label: "Email: info@nursat.kz", href: "mailto:info@nursat.kz" }
|
||||
]
|
||||
}
|
||||
{ label: "Email: info@nursat.kz", href: "mailto:info@nursat.kz" },
|
||||
],
|
||||
},
|
||||
]}
|
||||
copyrightText="© 2024 Центр чистка ковров «Нурсат». Все права защищены."
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user