/
varsl
/
HTML-CSS
Обзор
Документация
Войти
/
varsl
/
HTML-CSS
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
frontend/excursion.html
1 357 строк
63 KB
varsl
Добавление файлов фронтеда
21 дек 2025, 23:11
21 дек 2025, 23:11
7b4bf01
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Экскурсии - Зоопарк Дикий Мир</title> <link rel="stylesheet" href="css/style.css"> <link rel="stylesheet" href="css/animations.css"> <link rel="stylesheet" href="libs/all.min.css"> <style> .excursions-hero { background: linear-gradient(rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7)), url('assets/images/zoo-tour.jpg'); background-size: cover; background-position: center; color: var(--white); padding: 6rem 0; text-align: center; } .excursions-hero h1 { font-size: 3.5rem; margin-bottom: 1rem; } .excursions-hero p { font-size: 1.3rem; opacity: 0.9; max-width: 800px; margin: 0 auto 2rem; } .excursions-section { padding: 4rem 0; } .excursion-filters { background: var(--white); border-radius: var(--border-radius); padding: 2rem; box-shadow: var(--shadow); margin-bottom: 3rem; } .filter-tabs-excursion { display: flex; gap: 1rem; margin-bottom: 1.5rem; flex-wrap: wrap; } .filter-tab-excursion { padding: 0.75rem 1.5rem; background: var(--bg-color); border: none; border-radius: 50px; cursor: pointer; font-size: 1rem; transition: var(--transition); } .filter-tab-excursion:hover, .filter-tab-excursion.active { background: var(--primary-color); color: var(--white); } .filter-options-excursion { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1.5rem; margin-top: 1.5rem; } .excursions-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); gap: 2rem; margin-bottom: 4rem; } .excursion-card { background: var(--white); border-radius: var(--border-radius); overflow: hidden; box-shadow: var(--shadow); transition: var(--transition); position: relative; } .excursion-card:hover { transform: translateY(-10px); box-shadow: 0 15px 30px rgba(0,0,0,0.15); } .excursion-badge { position: absolute; top: 1rem; right: 1rem; background: var(--primary-color); color: var(--white); padding: 0.25rem 1rem; border-radius: 50px; font-size: 0.8rem; z-index: 1; } .excursion-badge.popular { background: #FF9800; } .excursion-badge.new { background: #2196F3; } .excursion-image { height: 200px; overflow: hidden; position: relative; } .excursion-image img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s; } .excursion-card:hover .excursion-image img { transform: scale(1.1); } .excursion-content { padding: 1.5rem; } .excursion-header { margin-bottom: 1rem; } .excursion-title { font-size: 1.4rem; margin-bottom: 0.5rem; color: var(--text-color); } .excursion-subtitle { color: var(--text-light); font-size: 0.9rem; } .excursion-details { margin-bottom: 1.5rem; } .detail-row { display: flex; justify-content: space-between; margin-bottom: 0.75rem; font-size: 0.9rem; } .detail-label { color: var(--text-light); } .detail-value { font-weight: 500; } .excursion-description { margin-bottom: 1.5rem; line-height: 1.5; } .excursion-actions { display: flex; gap: 0.75rem; } .btn-excursion { flex: 1; } .booking-section { background: linear-gradient(135deg, #f8f9fa, #e9ecef); padding: 4rem 0; border-radius: var(--border-radius); margin-bottom: 4rem; } .booking-form { background: var(--white); border-radius: var(--border-radius); padding: 2.5rem; box-shadow: var(--shadow); max-width: 800px; margin: 0 auto; } .form-section { margin-bottom: 2rem; } .form-section h3 { margin-bottom: 1.5rem; color: var(--text-color); display: flex; align-items: center; gap: 0.5rem; } .form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.5rem; } .form-group { margin-bottom: 1.5rem; } .form-group label { display: block; margin-bottom: 0.5rem; font-weight: 500; color: var(--text-color); } .form-group input, .form-group select, .form-group textarea { width: 100%; padding: 0.75rem 1rem; border: 1px solid #ddd; border-radius: var(--border-radius); font-size: 1rem; transition: var(--transition); } .form-group input:focus, .form-group select:focus, .form-group textarea:focus { outline: none; border-color: var(--primary-color); box-shadow: 0 0 0 3px rgba(46, 125, 50, 0.1); } .participants-control { display: flex; align-items: center; gap: 1rem; } .quantity-control-excursion { display: flex; align-items: center; gap: 0.5rem; } .quantity-btn-excursion { width: 40px; height: 40px; border-radius: 6px; border: 1px solid #ddd; background: var(--white); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: var(--transition); } .quantity-btn-excursion:hover { background: var(--primary-color); color: var(--white); border-color: var(--primary-color); } .quantity-input-excursion { width: 60px; text-align: center; padding: 0.5rem; border: 1px solid #ddd; border-radius: 6px; } .booking-summary { background: #f8f9fa; border-radius: var(--border-radius); padding: 1.5rem; margin-top: 2rem; } .summary-row { display: flex; justify-content: space-between; margin-bottom: 1rem; padding-bottom: 1rem; border-bottom: 1px solid #eee; } .summary-row:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; font-weight: 600; font-size: 1.1rem; } .guarantee-section { text-align: center; padding: 3rem 0; } .guarantee-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 2rem; margin-top: 2rem; } .guarantee-card { text-align: center; padding: 2rem; } .guarantee-icon { width: 80px; height: 80px; background: var(--primary-color); border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 1.5rem; color: var(--white); font-size: 2rem; } @media (max-width: 768px) { .excursions-grid { grid-template-columns: 1fr; } .excursion-actions { flex-direction: column; } .form-grid { grid-template-columns: 1fr; } .guarantee-grid { grid-template-columns: 1fr; } } </style> </head> <body> <div class="page-wrapper"> <header class="header"> <nav class="navbar container"> <div class="logo"> <i class="fas fa-paw"></i> <span>Зоопарк Дикий Мир</span> </div> <button class="menu-toggle" id="menuToggle"> <i class="fas fa-bars"></i> </button> <ul class="nav-menu" id="navMenu"> <li><a href="index.html"><i class="fas fa-home"></i> Главная</a></li> <li><a href="about.html"><i class="fas fa-info-circle"></i> О нас</a></li> <li><a href="animals.html"><i class="fas fa-dove"></i> Животные</a></li> <li><a href="catalog.html"><i class="fas fa-th-list"></i> Каталог</a></li> <li><a href="prices.html"><i class="fas fa-tag"></i> Цены</a></li> <li><a href="ticket.html"><i class="fas fa-ticket-alt"></i> Билеты</a></li> <li><a href="excursion.html" class="active"><i class="fas fa-calendar-alt"></i> Экскурсии</a></li> <li><a href="contacts.html"><i class="fas fa-address-book"></i> Контакты</a></li> <li><a href="map.html"><i class="fas fa-map-marked-alt"></i> Карта</a></li> <li class="auth-buttons"> <a href="login.html" class="btn btn-outline"><i class="fas fa-sign-in-alt"></i> Вход</a> <a href="register.html" class="btn btn-primary"><i class="fas fa-user-plus"></i> Регистрация</a> </li> </ul> </nav> </header> <main class="main-content"> <section class="excursions-hero"> <div class="container"> <h1>Экскурсии по зоопарку</h1> <p>Откройте для себя мир дикой природы с нашими профессиональными гидами. Уникальные маршруты, интересные факты и незабываемые впечатления</p> <a href="#booking" class="btn btn-primary btn-large"> <i class="fas fa-calendar-check"></i> Записаться на экскурсию </a> </div> </section> <section class="excursions-section"> <div class="container"> <div class="excursion-filters"> <h2>Выберите экскурсию</h2> <div class="filter-tabs-excursion"> <button class="filter-tab-excursion active" data-category="all">Все экскурсии</button> <button class="filter-tab-excursion" data-category="family">Семейные</button> <button class="filter-tab-excursion" data-category="children">Для детей</button> <button class="filter-tab-excursion" data-category="educational">Образовательные</button> <button class="filter-tab-excursion" data-category="photography">Фото-туры</button> <button class="filter-tab-excursion" data-category="evening">Вечерние</button> </div> <div class="filter-options-excursion"> <div class="form-group"> <label for="durationFilter">Длительность</label> <select id="durationFilter"> <option value="all">Любая</option> <option value="1">1 час</option> <option value="2">2 часа</option> <option value="3">3 часа</option> <option value="4">4+ часа</option> </select> </div> <div class="form-group"> <label for="priceFilter">Цена</label> <select id="priceFilter"> <option value="all">Любая</option> <option value="low">До 1000 ₽</option> <option value="medium">1000-2000 ₽</option> <option value="high">От 2000 ₽</option> </select> </div> <div class="form-group"> <label for="groupSizeFilter">Размер группы</label> <select id="groupSizeFilter"> <option value="all">Любой</option> <option value="small">До 10 человек</option> <option value="medium">10-20 человек</option> <option value="large">От 20 человек</option> </select> </div> </div> </div> <div class="excursions-grid" id="excursionsGrid"> <div class="excursion-card" data-category="family" data-duration="2" data-price="medium" data-group="medium"> <div class="excursion-badge popular">Популярная</div> <div class="excursion-image"> <img src="assets/images/lion.jpg" alt="Семейная экскурсия"> </div> <div class="excursion-content"> <div class="excursion-header"> <h3 class="excursion-title">Семейное сафари</h3> <p class="excursion-subtitle">Для родителей с детьми от 5 лет</p> </div> <div class="excursion-details"> <div class="detail-row"> <span class="detail-label">Длительность:</span> <span class="detail-value">2 часа</span> </div> <div class="detail-row"> <span class="detail-label">Цена:</span> <span class="detail-value">1500 ₽ с человека</span> </div> <div class="detail-row"> <span class="detail-label">Размер группы:</span> <span class="detail-value">до 15 человек</span> </div> <div class="detail-row"> <span class="detail-label">Сложность:</span> <span class="detail-value">Легкая</span> </div> </div> <div class="excursion-description"> Интерактивная экскурсия для всей семьи. Посещение самых интересных животных, интерактивные игры для детей, возможность покормить некоторых животных. </div> <div class="excursion-actions"> <button class="btn btn-primary btn-excursion book-excursion" data-id="1"> <i class="fas fa-calendar-plus"></i> Забронировать </button> <button class="btn btn-outline btn-excursion" onclick="showExcursionDetails(1)"> <i class="fas fa-info-circle"></i> Подробнее </button> </div> </div> </div> <div class="excursion-card" data-category="educational" data-duration="3" data-price="high" data-group="small"> <div class="excursion-badge new">Новая</div> <div class="excursion-image"> <img src="assets/images/elephant.jpg" alt="Экскурсия с зоологом"> </div> <div class="excursion-content"> <div class="excursion-header"> <h3 class="excursion-title">С зоологом за кулисы</h3> <p class="excursion-subtitle">Эксклюзивная экскурсия с ученым</p> </div> <div class="excursion-details"> <div class="detail-row"> <span class="detail-label">Длительность:</span> <span class="detail-value">3 часа</span> </div> <div class="detail-row"> <span class="detail-label">Цена:</span> <span class="detail-value">3500 ₽ с человека</span> </div> <div class="detail-row"> <span class="detail-label">Размер группы:</span> <span class="detail-value">до 8 человек</span> </div> <div class="detail-row"> <span class="detail-label">Сложность:</span> <span class="detail-value">Средняя</span> </div> </div> <div class="excursion-description"> Уникальная возможность посетить служебные помещения, пообщаться с зоологами, увидеть процесс ухода за животными и узнать научные подробности о жизни обитателей зоопарка. </div> <div class="excursion-actions"> <button class="btn btn-primary btn-excursion book-excursion" data-id="2"> <i class="fas fa-calendar-plus"></i> Забронировать </button> <button class="btn btn-outline btn-excursion" onclick="showExcursionDetails(2)"> <i class="fas fa-info-circle"></i> Подробнее </button> </div> </div> </div> <div class="excursion-card" data-category="children" data-duration="1" data-price="low" data-group="large"> <div class="excursion-image"> <img src="assets/images/penguin.jpg" alt="Детская экскурсия"> </div> <div class="excursion-content"> <div class="excursion-header"> <h3 class="excursion-title">Мир животных для малышей</h3> <p class="excursion-subtitle">Для детей 3-6 лет</p> </div> <div class="excursion-details"> <div class="detail-row"> <span class="detail-label">Длительность:</span> <span class="detail-value">1 час</span> </div> <div class="detail-row"> <span class="detail-label">Цена:</span> <span class="detail-value">800 ₽ с ребенка</span> </div> <div class="detail-row"> <span class="detail-label">Размер группы:</span> <span class="detail-value">до 20 детей</span> </div> <div class="detail-row"> <span class="detail-label">Сложность:</span> <span class="detail-value">Очень легкая</span> </div> </div> <div class="excursion-description"> Специально адаптированная экскурсия для самых маленьких. Короткие остановки, интересные истории, подвижные игры и возможность увидеть самых дружелюбных животных. </div> <div class="excursion-actions"> <button class="btn btn-primary btn-excursion book-excursion" data-id="3"> <i class="fas fa-calendar-plus"></i> Забронировать </button> <button class="btn btn-outline btn-excursion" onclick="showExcursionDetails(3)"> <i class="fas fa-info-circle"></i> Подробнее </button> </div> </div> </div> <div class="excursion-card" data-category="photography" data-duration="4" data-price="high" data-group="small"> <div class="excursion-image"> <img src="assets/images/tiger.jpg" alt="Фото-тур"> </div> <div class="excursion-content"> <div class="excursion-header"> <h3 class="excursion-title">Фото-сафари</h3> <p class="excursion-subtitle">Для фотографов-любителей</p> </div> <div class="excursion-details"> <div class="detail-row"> <span class="detail-label">Длительность:</span> <span class="detail-value">4 часа</span> </div> <div class="detail-row"> <span class="detail-label">Цена:</span> <span class="detail-value">5000 ₽ с человека</span> </div> <div class="detail-row"> <span class="detail-label">Размер группы:</span> <span class="detail-value">до 6 человек</span> </div> <div class="detail-row"> <span class="detail-label">Сложность:</span> <span class="detail-value">Средняя</span> </div> </div> <div class="excursion-description"> Специальный тур для фотографов. Ранний вход в зоопарк, лучшие точки для съемки, советы профессионального фотографа, возможность съемки в нестандартное время. </div> <div class="excursion-actions"> <button class="btn btn-primary btn-excursion book-excursion" data-id="4"> <i class="fas fa-calendar-plus"></i> Забронировать </button> <button class="btn btn-outline btn-excursion" onclick="showExcursionDetails(4)"> <i class="fas fa-info-circle"></i> Подробнее </button> </div> </div> </div> <div class="excursion-card" data-category="evening" data-duration="2" data-price="medium" data-group="medium"> <div class="excursion-badge">Особенная</div> <div class="excursion-image"> <img src="assets/images/zoo-entrance.jpg" alt="Вечерняя экскурсия"> </div> <div class="excursion-content"> <div class="excursion-header"> <h3 class="excursion-title">Ночные обитатели</h3> <p class="excursion-subtitle">Вечерняя экскурсия</p> </div> <div class="excursion-details"> <div class="detail-row"> <span class="detail-label">Длительность:</span> <span class="detail-value">2 часа</span> </div> <div class="detail-row"> <span class="detail-label">Цена:</span> <span class="detail-value">2000 ₽ с человека</span> </div> <div class="detail-row"> <span class="detail-label">Размер группы:</span> <span class="detail-value">до 12 человек</span> </div> <div class="detail-row"> <span class="detail-label">Сложность:</span> <span class="detail-value">Легкая</span> </div> </div> <div class="excursion-description"> Уникальная возможность увидеть зоопарк после закрытия. Наблюдение за ночными животными, специальное освещение, атмосферная прогулка по пустынным аллеям. </div> <div class="excursion-actions"> <button class="btn btn-primary btn-excursion book-excursion" data-id="5"> <i class="fas fa-calendar-plus"></i> Забронировать </button> <button class="btn btn-outline btn-excursion" onclick="showExcursionDetails(5)"> <i class="fas fa-info-circle"></i> Подробнее </button> </div> </div> </div> </div> </div> </section> <section id="booking" class="booking-section"> <div class="container"> <h2 class="section-title">Забронировать экскурсию</h2> <div class="booking-form" id="bookingForm"> <div class="form-section"> <h3><i class="fas fa-user-friends"></i> Информация об участниках</h3> <div class="form-grid"> <div class="form-group"> <label for="bookingName">ФИО *</label> <input type="text" id="bookingName" required placeholder="Иванов Иван Иванович"> </div> <div class="form-group"> <label for="bookingEmail">Email *</label> <input type="email" id="bookingEmail" required placeholder="example@mail.ru"> </div> <div class="form-group"> <label for="bookingPhone">Телефон *</label> <input type="tel" id="bookingPhone" required placeholder="+7 (999) 123-45-67"> </div> <div class="form-group"> <label for="excursionSelect">Выберите экскурсию *</label> <select id="excursionSelect" required> <option value="">Выберите экскурсию</option> <option value="1">Семейное сафари (1500 ₽)</option> <option value="2">С зоологом за кулисы (3500 ₽)</option> <option value="3">Мир животных для малышей (800 ₽)</option> <option value="4">Фото-сафари (5000 ₽)</option> <option value="5">Ночные обитатели (2000 ₽)</option> </select> </div> </div> <div class="form-group"> <label>Количество участников *</label> <div class="participants-control"> <div class="quantity-control-excursion"> <button type="button" class="quantity-btn-excursion" id="decreaseParticipants"> <i class="fas fa-minus"></i> </button> <input type="number" id="participantsCount" class="quantity-input-excursion" value="1" min="1" max="20" readonly> <button type="button" class="quantity-btn-excursion" id="increaseParticipants"> <i class="fas fa-plus"></i> </button> </div> <span id="participantsPrice">1500 ₽</span> </div> </div> </div> <div class="form-section"> <h3><i class="fas fa-calendar-alt"></i> Дата и время</h3> <div class="form-grid"> <div class="form-group"> <label for="bookingDate">Дата экскурсии *</label> <input type="date" id="bookingDate" required> </div> <div class="form-group"> <label for="bookingTime">Время *</label> <select id="bookingTime" required> <option value="">Выберите время</option> <option value="10:00">10:00</option> <option value="12:00">12:00</option> <option value="14:00">14:00</option> <option value="16:00">16:00</option> <option value="18:00">18:00</option> </select> </div> <div class="form-group"> <label for="languageSelect">Язык экскурсии</label> <select id="languageSelect"> <option value="ru">Русский</option> <option value="en">English</option> <option value="de">Deutsch</option> </select> </div> </div> </div> <div class="form-section"> <h3><i class="fas fa-comment"></i> Дополнительная информация</h3> <div class="form-group"> <label for="specialRequests">Особые пожелания</label> <textarea id="specialRequests" rows="4" placeholder="Аллергии, ограничения по здоровью, особые интересы..."></textarea> </div> <div class="form-group"> <label class="checkbox-label"> <input type="checkbox" id="needGuide" checked> <span>Нужен гид (включено в стоимость)</span> </label> </div> <div class="form-group"> <label class="checkbox-label"> <input type="checkbox" id="transportation"> <span>Нужен трансфер от метро (+500 ₽)</span> </label> </div> </div> <div class="booking-summary"> <div class="summary-row"> <span>Стоимость экскурсии:</span> <span id="excursionPrice">1500 ₽</span> </div> <div class="summary-row"> <span>Количество участников:</span> <span id="summaryParticipants">1</span> </div> <div class="summary-row"> <span>Дополнительные услуги:</span> <span id="additionalServices">0 ₽</span> </div> <div class="summary-row"> <span>Итого к оплате:</span> <span id="totalPrice">1500 ₽</span> </div> </div> <div class="form-group"> <label class="checkbox-label"> <input type="checkbox" id="termsAgreeBooking" required> <span>Я согласен с <a href="#">правилами бронирования</a> и <a href="#">политикой отмены</a> *</span> </label> </div> <button type="submit" class="btn btn-primary btn-large btn-block" id="submitBooking"> <i class="fas fa-calendar-check"></i> Забронировать экскурсию </button> </div> </div> </section> <section class="guarantee-section"> <div class="container"> <h2 class="section-title">Наши гарантии</h2> <div class="guarantee-grid"> <div class="guarantee-card"> <div class="guarantee-icon"> <i class="fas fa-shield-alt"></i> </div> <h3>Безопасность</h3> <p>Все экскурсии проводятся с соблюдением мер безопасности. Наши гиды прошли специальную подготовку.</p> </div> <div class="guarantee-card"> <div class="guarantee-icon"> <i class="fas fa-graduation-cap"></i> </div> <h3>Профессионализм</h3> <p>Наши гиды - профессиональные зоологи и биологи с опытом работы от 5 лет.</p> </div> <div class="guarantee-card"> <div class="guarantee-icon"> <i class="fas fa-undo"></i> </div> <h3>Бесплатная отмена</h3> <p>Бесплатная отмена бронирования за 48 часов до начала экскурсии.</p> </div> <div class="guarantee-card"> <div class="guarantee-icon"> <i class="fas fa-smile"></i> </div> <h3>100% удовлетворение</h3> <p>Если экскурсия не понравится, мы вернем 50% стоимости.</p> </div> </div> </div> </section> </main> <footer class="footer"> <div class="container"> <div class="footer-content"> <div class="footer-section"> <h3>Зоопарк Дикий Мир</h3> <p>г. Москва, ул. Зоологическая, 123</p> <p>Ежедневно с 9:00 до 20:00</p> </div> <div class="footer-section"> <h3>Контакты</h3> <p><i class="fas fa-phone"></i> +7 (495) 123-45-67</p> <p><i class="fas fa-envelope"></i> info@wildzoo.ru</p> </div> </div> <div class="footer-bottom"> <p>© 2025 Зоопарк Дикий Мир. Все права защищены.</p> </div> </div> </footer> </div> <!-- Модальное окно деталей экскурсии --> <div class="modal" id="excursionModal"> <div class="modal-content"> <div class="modal-header"> <h3>Детали экскурсии</h3> <button class="modal-close"> <i class="fas fa-times"></i> </button> </div> <div class="modal-body"> <div id="excursionModalContent"> <!-- Контент будет загружен через JavaScript --> </div> </div> <div class="modal-footer"> <button class="btn btn-outline modal-close">Закрыть</button> <button class="btn btn-primary" id="bookFromModal"> <i class="fas fa-calendar-plus"></i> Забронировать </button> </div> </div> </div> <script src="js/main.js"></script> <script> document.addEventListener('DOMContentLoaded', function() { const filterTabs = document.querySelectorAll('.filter-tab-excursion'); const durationFilter = document.getElementById('durationFilter'); const priceFilter = document.getElementById('priceFilter'); const groupSizeFilter = document.getElementById('groupSizeFilter'); const excursionCards = document.querySelectorAll('.excursion-card'); const bookButtons = document.querySelectorAll('.book-excursion'); const bookingForm = document.getElementById('bookingForm'); const excursionSelect = document.getElementById('excursionSelect'); const participantsCount = document.getElementById('participantsCount'); const decreaseBtn = document.getElementById('decreaseParticipants'); const increaseBtn = document.getElementById('increaseParticipants'); const excursionPrice = document.getElementById('excursionPrice'); const participantsPrice = document.getElementById('participantsPrice'); const summaryParticipants = document.getElementById('summaryParticipants'); const additionalServices = document.getElementById('additionalServices'); const totalPrice = document.getElementById('totalPrice'); const bookingDate = document.getElementById('bookingDate'); const needGuide = document.getElementById('needGuide'); const transportation = document.getElementById('transportation'); const submitBooking = document.getElementById('submitBooking'); const excursionModal = document.getElementById('excursionModal'); const bookFromModal = document.getElementById('bookFromModal'); const excursionPrices = { '1': 1500, '2': 3500, '3': 800, '4': 5000, '5': 2000 }; const excursionDetails = { '1': { title: 'Семейное сафари', description: 'Интерактивная экскурсия для всей семьи. Посещение самых интересных животных, интерактивные игры для детей, возможность покормить некоторых животных.', duration: '2 часа', price: '1500 ₽ с человека', groupSize: 'до 15 человек', difficulty: 'Легкая', includes: ['Посещение 5 основных зон', 'Интерактивные игры для детей', 'Кормление дружелюбных животных', 'Фотографии с животными', 'Подарок для детей'], recommendedFor: 'Семьи с детьми от 5 лет' }, '2': { title: 'С зоологом за кулисы', description: 'Уникальная возможность посетить служебные помещения, пообщаться с зоологами, увидеть процесс ухода за животными и узнать научные подробности о жизни обитателей зоопарка.', duration: '3 часа', price: '3500 ₽ с человека', groupSize: 'до 8 человек', difficulty: 'Средняя', includes: ['Посещение служебных помещений', 'Общение с зоологами', 'Наблюдение за кормлением', 'Научные лекции', 'Эксклюзивные фотографии'], recommendedFor: 'Взрослые и подростки от 14 лет' }, '3': { title: 'Мир животных для малышей', description: 'Специально адаптированная экскурсия для самых маленьких. Короткие остановки, интересные истории, подвижные игры и возможность увидеть самых дружелюбных животных.', duration: '1 час', price: '800 ₽ с ребенка', groupSize: 'до 20 детей', difficulty: 'Очень легкая', includes: ['3 остановки у самых интересных животных', 'Подвижные игры', 'Короткие истории о животных', 'Воздушные шары', 'Диплом юного зоолога'], recommendedFor: 'Дети 3-6 лет с родителями' }, '4': { title: 'Фото-сафари', description: 'Специальный тур для фотографов. Ранний вход в зоопарк, лучшие точки для съемки, советы профессионального фотографа, возможность съемки в нестандартное время.', duration: '4 часа', price: '5000 ₽ с человека', groupSize: 'до 6 человек', difficulty: 'Средняя', includes: ['Ранний вход в зоопарк', 'Советы профессионального фотографа', 'Лучшие точки для съемки', 'Обработка 5 фотографий', 'Печать 3 лучших снимков'], recommendedFor: 'Фотографы-любители и профессионалы' }, '5': { title: 'Ночные обитатели', description: 'Уникальная возможность увидеть зоопарк после закрытия. Наблюдение за ночными животными, специальное освещение, атмосферная прогулка по пустынным аллеям.', duration: '2 часа', price: '2000 ₽ с человека', groupSize: 'до 12 человек', difficulty: 'Легкая', includes: ['Эксклюзивный доступ после закрытия', 'Наблюдение за ночными животными', 'Специальное освещение', 'Горячие напитки', 'Сувенирный фонарик'], recommendedFor: 'Взрослые и дети от 10 лет' } }; if (bookingDate) { const today = new Date(); const tomorrow = new Date(today); tomorrow.setDate(tomorrow.getDate() + 1); bookingDate.min = tomorrow.toISOString().split('T')[0]; const maxDate = new Date(today); maxDate.setDate(maxDate.getDate() + 90); bookingDate.max = maxDate.toISOString().split('T')[0]; bookingDate.value = tomorrow.toISOString().split('T')[0]; } filterTabs.forEach(tab => { tab.addEventListener('click', function() { filterTabs.forEach(t => t.classList.remove('active')); this.classList.add('active'); filterExcursions(); }); }); [durationFilter, priceFilter, groupSizeFilter].forEach(filter => { if (filter) { filter.addEventListener('change', filterExcursions); } }); bookButtons.forEach(button => { button.addEventListener('click', function() { const excursionId = this.getAttribute('data-id'); selectExcursion(excursionId); bookingForm.scrollIntoView({ behavior: 'smooth' }); if (excursionSelect) { excursionSelect.value = excursionId; updatePrice(); } }); }); if (decreaseBtn && increaseBtn && participantsCount) { decreaseBtn.addEventListener('click', function() { let count = parseInt(participantsCount.value); if (count > 1) { count--; participantsCount.value = count; updatePrice(); } }); increaseBtn.addEventListener('click', function() { let count = parseInt(participantsCount.value); const max = parseInt(participantsCount.max); if (count < max) { count++; participantsCount.value = count; updatePrice(); } }); } if (excursionSelect) { excursionSelect.addEventListener('change', updatePrice); } if (needGuide) { needGuide.addEventListener('change', updatePrice); } if (transportation) { transportation.addEventListener('change', updatePrice); } if (submitBooking) { submitBooking.addEventListener('click', function(e) { e.preventDefault(); if (!validateBookingForm()) { return; } const submitBtn = this; const originalText = submitBtn.innerHTML; submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Бронирование...'; submitBtn.disabled = true; setTimeout(() => { submitBtn.innerHTML = originalText; submitBtn.disabled = false; showBookingSuccess(); }, 2000); }); } const modalClose = document.querySelectorAll('.modal-close'); modalClose.forEach(btn => { btn.addEventListener('click', function() { const modal = this.closest('.modal'); if (modal) { modal.classList.remove('show'); } }); }); if (bookFromModal) { bookFromModal.addEventListener('click', function() { excursionModal.classList.remove('show'); bookingForm.scrollIntoView({ behavior: 'smooth' }); }); } function filterExcursions() { const activeCategory = document.querySelector('.filter-tab-excursion.active').getAttribute('data-category'); const durationValue = durationFilter ? durationFilter.value : 'all'; const priceValue = priceFilter ? priceFilter.value : 'all'; const groupValue = groupSizeFilter ? groupSizeFilter.value : 'all'; let visibleCount = 0; excursionCards.forEach(card => { const category = card.getAttribute('data-category'); const duration = card.getAttribute('data-duration'); const price = card.getAttribute('data-price'); const group = card.getAttribute('data-group'); let shouldShow = true; if (activeCategory !== 'all' && category !== activeCategory) { shouldShow = false; } if (durationValue !== 'all' && duration !== durationValue) { shouldShow = false; } if (priceValue !== 'all' && price !== priceValue) { shouldShow = false; } if (groupValue !== 'all' && group !== groupValue) { shouldShow = false; } if (shouldShow) { card.style.display = 'block'; visibleCount++; card.classList.add('animate-fade-in'); } else { card.style.display = 'none'; card.classList.remove('animate-fade-in'); } }); if (visibleCount === 0) { const grid = document.getElementById('excursionsGrid'); if (grid) { grid.innerHTML = ` <div class="no-results" style="grid-column: 1 / -1; text-align: center; padding: 3rem;"> <i class="fas fa-search" style="font-size: 3rem; color: var(--text-light); margin-bottom: 1rem;"></i> <h3>Экскурсии не найдены</h3> <p>Попробуйте изменить параметры фильтрации</p> </div> `; } } } function selectExcursion(id) { const selectedOption = excursionSelect.querySelector(`option[value="${id}"]`); if (selectedOption) { excursionSelect.value = id; updatePrice(); } } function updatePrice() { const selectedId = excursionSelect.value; const participants = parseInt(participantsCount.value); const pricePerPerson = excursionPrices[selectedId] || 1500; let total = pricePerPerson * participants; let additional = 0; if (transportation && transportation.checked) { additional += 500; } excursionPrice.textContent = `${pricePerPerson} ₽`; participantsPrice.textContent = `${total} ₽`; summaryParticipants.textContent = participants; additionalServices.textContent = `${additional} ₽`; totalPrice.textContent = `${total + additional} ₽`; const maxParticipants = getMaxParticipants(selectedId); if (participantsCount) { participantsCount.max = maxParticipants; } } function getMaxParticipants(excursionId) { switch(excursionId) { case '1': return 15; case '2': return 8; case '3': return 20; case '4': return 6; case '5': return 12; default: return 10; } } function validateBookingForm() { const name = document.getElementById('bookingName'); const email = document.getElementById('bookingEmail'); const phone = document.getElementById('bookingPhone'); const date = document.getElementById('bookingDate'); const time = document.getElementById('bookingTime'); const terms = document.getElementById('termsAgreeBooking'); if (!name.value.trim()) { alert('Пожалуйста, введите ФИО'); name.focus(); return false; } if (!email.value.trim() || !isValidEmail(email.value)) { alert('Пожалуйста, введите корректный email'); email.focus(); return false; } if (!phone.value.trim() || !isValidPhone(phone.value)) { alert('Пожалуйста, введите корректный номер телефона'); phone.focus(); return false; } if (!excursionSelect.value) { alert('Пожалуйста, выберите экскурсию'); excursionSelect.focus(); return false; } if (!date.value) { alert('Пожалуйста, выберите дату'); date.focus(); return false; } if (!time.value) { alert('Пожалуйста, выберите время'); time.focus(); return false; } if (!terms.checked) { alert('Пожалуйста, согласитесь с правилами бронирования'); terms.focus(); return false; } return true; } function isValidEmail(email) { const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return re.test(email); } function isValidPhone(phone) { const re = /^[\+]?[0-9\s\-\(\)]+$/; return re.test(phone) && phone.replace(/\D/g, '').length >= 10; } function showBookingSuccess() { const excursionName = excursionSelect.options[excursionSelect.selectedIndex].text; const date = bookingDate.value; const time = document.getElementById('bookingTime').value; const participants = participantsCount.value; const total = totalPrice.textContent; const successMessage = ` <div class="booking-success" style="text-align: center; padding: 2rem;"> <div style="font-size: 4rem; color: var(--primary-color); margin-bottom: 1rem;"> <i class="fas fa-check-circle"></i> </div> <h3 style="margin-bottom: 1rem; color: var(--text-color);">Экскурсия забронирована!</h3> <div style="background: #f8f9fa; padding: 1.5rem; border-radius: var(--border-radius); margin: 1.5rem 0;"> <p><strong>Экскурсия:</strong> ${excursionName}</p> <p><strong>Дата и время:</strong> ${date} в ${time}</p> <p><strong>Участников:</strong> ${participants} человек</p> <p><strong>Сумма:</strong> ${total}</p> </div> <p style="color: var(--text-light); margin-bottom: 1.5rem;"> Подтверждение бронирования отправлено на ваш email. Приходите за 15 минут до начала экскурсии. </p> <button class="btn btn-primary" onclick="window.location.href='dashboard.html'"> <i class="fas fa-user"></i> Перейти в личный кабинет </button> </div> `; bookingForm.innerHTML = successMessage; } window.showExcursionDetails = function(id) { const details = excursionDetails[id]; if (!details) return; const modalContent = document.getElementById('excursionModalContent'); if (modalContent) { modalContent.innerHTML = ` <div class="excursion-details-modal"> <h3 style="margin-bottom: 1rem; color: var(--primary-color);">${details.title}</h3> <p style="margin-bottom: 1.5rem; line-height: 1.5;">${details.description}</p> <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 1.5rem;"> <div style="background: #f8f9fa; padding: 1rem; border-radius: 6px;"> <strong>Длительность:</strong><br>${details.duration} </div> <div style="background: #f8f9fa; padding: 1rem; border-radius: 6px;"> <strong>Цена:</strong><br>${details.price} </div> <div style="background: #f8f9fa; padding: 1rem; border-radius: 6px;"> <strong>Размер группы:</strong><br>${details.groupSize} </div> <div style="background: #f8f9fa; padding: 1rem; border-radius: 6px;"> <strong>Сложность:</strong><br>${details.difficulty} </div> </div> <div style="margin-bottom: 1.5rem;"> <h4 style="margin-bottom: 0.5rem; color: var(--text-color);">Что включено:</h4> <ul style="list-style: none; padding-left: 0;"> ${details.includes.map(item => `<li style="margin-bottom: 0.5rem; padding-left: 1.5rem; position: relative;"> <i class="fas fa-check" style="position: absolute; left: 0; color: var(--primary-color);"></i> ${item} </li>`).join('')} </ul> </div> <div style="background: #e8f5e9; padding: 1rem; border-radius: 6px; border-left: 4px solid var(--primary-color);"> <strong>Рекомендуется для:</strong> ${details.recommendedFor} </div> </div> `; } if (excursionModal) { excursionModal.classList.add('show'); } if (bookFromModal) { bookFromModal.onclick = function() { selectExcursion(id); excursionModal.classList.remove('show'); bookingForm.scrollIntoView({ behavior: 'smooth' }); }; } }; filterExcursions(); updatePrice(); }); </script> </body> <script src="js/auth-manager.js"></script> </html>