Zero Block
Click "Block Editor" to enter the edit mode. Use layers, shapes and customize adaptability. Everything is in your hands.
Tilda Publishing
create your own block from scratch
// Время до метро const metroTimes = ["5 мин", "8 мин", "10 мин", "12 мин", "15 мин", "18 мин"]; const metroTime = metroTimes[Math.floor(Math.random() * metroTimes.length)]; properties.push({ id: i, name: `ЖК «${getRandomName()}»`, builder: builder, district: district, rooms: uniqueRooms.join(", "), price: Math.round(basePrice * 10) / 10, minArea: Math.round(minArea), maxArea: Math.round(maxArea), area: `${Math.round(minArea)}-${Math.round(maxArea)} м²`, deadline: deadline, metro: metro, metroTime: metroTime, features: features, lat: lat, lng: lng, badge: badge.text, badgeClass: badge.class }); } return properties; } function getRandomName() { const names = [ "Серебряный бор", "Лесные поляны", "Центральный парк", "Речные дали", "Солнечный берег", "Северное сияние", "Южные сады", "Восточный ветер", "Западные ворота", "Город мечты", "Алые паруса", "Бриз", "Весна", "Грани", "Долина", "Европейский", "Жемчужина", "Зарядье", "Изумрудный", "Квартал", "Лето", "Мирный", "Небо", "Оазис", "Парковый", "Рассвет", "Светлый", "Триумф", "Уютный", "Фортуна", "Цветной", "Чистые пруды", "Шереметьевский", "Эдельвейс", "Юбилейный", "Ясный", "Авеню", "Бульвар", "Версаль", "Гранд", "Дом на набережной", "Евразия", "Живой район", "Зеленый город", "Императорский", "Королевский парк", "Лайф" ]; return names[Math.floor(Math.random() * names.length)]; } // Инициализация карты function initMap() { map = L.map('map').setView([55.7558, 37.6173], 11); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map); // Добавление маркеров updateMapMarkers(properties); } // Обновление маркеров на карте function updateMapMarkers(props) { // Очистка старых маркеров markers.forEach(marker => map.removeLayer(marker)); markers = []; // Добавление новых маркеров props.forEach(prop => { const markerIcon = L.divIcon({ html: `
`, className: 'custom-marker', iconSize: [16, 16] }); const marker = L.marker([prop.lat, prop.lng], { icon: markerIcon }) .addTo(map) .bindPopup(`
${prop.name}
${prop.district}

От ${prop.price} млн руб.
${prop.rooms} комнаты
${prop.area}
Метро: ${prop.metro} (${prop.metroTime})
`); marker.propertyId = prop.id; marker.on('click', function() { highlightPropertyCard(prop.id); }); markers.push(marker); }); } function getMarkerColor(prop) { if (prop.deadline === 'completed') return '#28a745'; if (prop.deadline === '2024') return '#ff6b35'; if (prop.deadline === '2025') return '#17a2b8'; return '#6c757d'; } // Рендеринг карточек с пагинацией function renderProperties(props, page = 1) { const container = document.getElementById('propertyList'); const loader = document.getElementById('loader'); if (props.length === 0) { container.innerHTML = `

Ничего не найдено

Попробуйте изменить параметры поиска

`; document.getElementById('pagination').innerHTML = ''; return; } // Показываем лоадер на мгновение loader.style.display = 'block'; container.innerHTML = ''; // Пагинация const totalPages = Math.ceil(props.length / itemsPerPage); const startIndex = (page - 1) * itemsPerPage; const endIndex = startIndex + itemsPerPage; const pageProperties = props.slice(startIndex, endIndex); // Рендеринг карточек текущей страницы setTimeout(() => { pageProperties.forEach(prop => { const card = document.createElement('div'); card.className = 'property-card'; card.dataset.id = prop.id; card.innerHTML = `
${prop.name}
${prop.badge}
${prop.district} • ${prop.metro} (${prop.metroTime})
${prop.builder} Сдача: ${prop.deadline === 'completed' ? 'Сдан' : prop.deadline + ' год'}
${prop.rooms}
${prop.area}
${prop.features[0]}
от ${prop.price} млн руб.
`; card.addEventListener('click', (e) => { if (!e.target.closest('button')) { selectProperty(prop.id); } }); container.appendChild(card); }); loader.style.display = 'none'; document.getElementById('resultsCount').textContent = props.length; renderPagination(totalPages, page); // Обновляем статистику document.getElementById('totalProperties').textContent = props.length + '+'; }, 300); } // Рендеринг пагинации function renderPagination(totalPages, currentPage) { const container = document.getElementById('pagination'); if (totalPages <= 1) { container.innerHTML = ''; return; } let html = ''; // Кнопка "Назад" if (currentPage > 1) { html += ``; } // Страницы const maxVisible = 5; let startPage = Math.max(1, currentPage - Math.floor(maxVisible / 2)); let endPage = Math.min(totalPages, startPage + maxVisible - 1); if (endPage - startPage + 1 < maxVisible) { startPage = Math.max(1, endPage - maxVisible + 1); } for (let i = startPage; i <= endPage; i++) { html += ``; } // Кнопка "Вперед" if (currentPage < totalPages) { html += ``; } container.innerHTML = html; } // Смена страницы function changePage(page) { currentPage = page; renderProperties(filteredProperties, page); window.scrollTo({ top: document.querySelector('.results-section').offsetTop - 100, behavior: 'smooth' }); } // Фильтрация function filterProperties() { const district = document.getElementById('district').value; const rooms = document.getElementById('rooms').value; const maxPrice = parseFloat(document.getElementById('maxPrice').value); const minArea = parseFloat(document.getElementById('minArea').value); const deadline = document.getElementById('deadline').value; const builder = document.getElementById('builder').value; filteredProperties = properties.filter(prop => { // Фильтр по району if (district && prop.district !== district) return false; // Фильтр по комнатам if (rooms) { if (rooms === 'studio' && !prop.rooms.includes('студия')) return false; if (rooms !== 'studio' && !prop.rooms.includes(rooms)) return false; } // Фильтр по цене if (maxPrice && prop.price > maxPrice) return false; // Фильтр по площади if (minArea && prop.minArea < minArea) return false; // Фильтр по сроку сдачи if (deadline && prop.deadline !== deadline) return false; // Фильтр по застройщику if (builder && prop.builder !== builder) return false; return true; }); // Сортировка const sortBy = document.getElementById('sortBy').value; if (sortBy === 'price_asc') { filteredProperties.sort((a, b) => a.price - b.price); } else if (sortBy === 'price_desc') { filteredProperties.sort((a, b) => b.price - a.price); } else if (sortBy === 'area_asc') { filteredProperties.sort((a, b) => a.minArea - b.minArea); } else if (sortBy === 'name') { filteredProperties.sort((a, b) => a.name.localeCompare(b.name)); } currentPage = 1; renderProperties(filteredProperties, currentPage); updateMapMarkers(filteredProperties); // Если мало результатов, увеличиваем масштаб карты if (filteredProperties.length > 0 && filteredProperties.length < 10) { const avgLat = filteredProperties.reduce((sum, p) => sum + p.lat, 0) / filteredProperties.length; const avgLng = filteredProperties.reduce((sum, p) => sum + p.lng, 0) / filteredProperties.length; map.setView([avgLat, avgLng], 13); } else if (filteredProperties.length > 0) { map.setView([55.7558, 37.6173], 11); } } // Выбор объекта function selectProperty(id) { const prop = properties.find(p => p.id === id); if (!prop) return; highlightPropertyCard(id); map.setView([prop.lat, prop.lng], 14); // Анимация маркера markers.forEach(marker => { if (marker.propertyId === id) { marker.openPopup(); } }); } // Подсветка карточки function highlightPropertyCard(id) { document.querySelectorAll('.property-card').forEach(card => { card.classList.remove('active'); if (parseInt(card.dataset.id) === id) { card.classList.add('active'); card.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); } }); } // Показать планировки function showPlans(id) { const prop = properties.find(p => p.id === id); const roomTypes = prop.rooms.split(', '); const roomsList = roomTypes.map(room => { if (room === 'студия') return 'Студии'; if (room === '1') return '1-комнатные'; if (room === '2') return '2-комнатные'; if (room === '3') return '3-комнатные'; return '4+ комнатные'; }).join(', '); alert(`Планировки ЖК «${prop.name}»\n\nДоступны: ${roomsList}\nПлощадь: ${prop.area}\n\nДля детального просмотра планировок и цен перейдите на страницу комплекса.`); } // Запись на просмотр function bookViewing(id) { const prop = properties.find(p => p.id === id); const roomTypes = prop.rooms.split(', ')[0]; document.getElementById('modalPropertyName').value = prop.name; document.getElementById('modalPropertyType').value = roomTypes === 'студия' ? 'Студия' : `${roomTypes}-комнатная`; document.getElementById('bookingModal').style.display = 'flex'; } // Закрыть модальное окно document.getElementById('closeModal').addEventListener('click', () => { document.getElementById('bookingModal').style.display = 'none'; }); // Отправка формы document.getElementById('bookingForm').addEventListener('submit', (e) => { e.preventDefault(); const formData = { property: document.getElementById('modalPropertyName').value, type: document.getElementById('modalPropertyType').value, name: document.getElementById('clientName').value, phone: document.getElementById('clientPhone').value, email: document.getElementById('clientEmail').value, date: document.getElementById('visitDate').value, comment: document.getElementById('comment').value }; console.log('Форма отправлена:', formData); // Здесь обычно отправка на сервер // fetch('/api/booking', { method: 'POST', body: JSON.stringify(formData) }) alert(`Спасибо, ${formData.name}!\n\nВаша заявка на просмотр ${formData.type} квартиры в ЖК «${formData.property}» принята.\n\nСпециалист свяжется с вами в течение 30 минут для подтверждения даты.`); document.getElementById('bookingModal').style.display = 'none'; document.getElementById('bookingForm').reset(); // Сброс типа квартиры document.getElementById('modalPropertyType').value = ''; }); // Инициализация document.addEventListener('DOMContentLoaded', () => { initMap(); renderProperties(properties, currentPage); // Обновляем статистику document.getElementById('totalProperties').textContent = properties.length + '+'; // События document.getElementById('searchBtn').addEventListener('click', filterProperties); document.getElementById('sortBy').addEventListener('change', filterProperties); // Автоматический поиск при изменении фильтров document.querySelectorAll('.filter-select, .filter-input').forEach(el => { el.addEventListener('change', filterProperties); }); // Закрыть модальное окно при клике вне его window.addEventListener('click', (e) => { const modal = document.getElementById('bookingModal'); if (e.target === modal) { modal.style.display = 'none'; } }); // Установить минимальную дату в календаре на завтра const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); document.getElementById('visitDate').min = tomorrow.toISOString().split('T')[0]; document.getElementById('visitDate').value = tomorrow.toISOString().split('T')[0]; // Маска для телефона document.getElementById('clientPhone').addEventListener('input', function(e) { let x = e.target.value.replace(/\D/g, '').match(/(\d{0,1})(\d{0,3})(\d{0,3})(\d{0,2})(\d{0,2})/); e.target.value = !x[2] ? x[1] : '+' + x[1] + ' (' + x[2] + ') ' + x[3] + (x[4] ? '-' + x[4] : '') + (x[5] ? '-' + x[5] : ''); }); });