- Под ключ с учетом каждой детали
Гарантии 100% соблюдения сроков и расхода бюджета
Предлагаем индивидуальные решения основанные на принципах голландского дизайна
Спроектировали более 20 мастерпланов за 10 лет активной работы
проектирование комфорных и стильных поселков по европейским стандартам
Кто вы?
Какую площадь планируете застраивать?
Какое количество домов планируется в поселке?
Какая классификация поселка?
Где планируете строительство поселка?
Остался последний шаг. Получите бесплатный анализ территории вашего будущего поселка
Отправка формы
Подтвердите, что вы не робот
или нажмите Enter
проектируем поселки с ярким харрактером
Мастер-план поселение «Росы» — стратегия развития поселения с сохранением и возрождением исторического наследия до 2030 года
Основная идея проекта — создание экологичного коттеджного посёлка, который гармонично впишется в окружающий ландшафт.

Посёлок расположен вблизи города Можайск, что обеспечивает удобную транспортную доступность. Проект направлен на развитие экологически чистого и комфортного для жизни пространства, которое будет привлекать людей, ценящих природу и стремящихся к здоровому образу жизни.

Проектирование поселка на исторической территорий в Калининградской области площадью 4Га
Коттеджный посёлок под Можайском 43Га, на 466 домов
Каталог с работами автоматически придет на указанный номер
получите все портфолио в WhatsApp
Основатель архитектурного бюро  голландский
убранист Лекс те Лоо 
Дорожу своей репутацией, и с каждым клиентом выстраиваю открытые и доверительные отношения

- Уделяю внимание каждому клиенту, внимательно слушаю ваши пожелания и предлагаю наилучшие решения, соответствующие вашим потребностям

- Ценю ваше время, поэтому выстроил процессы так, что в 99% проектов укладываемся раньше согласованных сроков, а если задерживаемся - то платим за каждый день просрочки
Всего 5 шагов от идеи до готового Проекта вашего поселка
Создание единого стиля посёлка, выбор цветовой гаммы материалов, разработка дизайна деталей и въездной группы. Проектирование зданий.
Архитекторы разрабатывают генеральный план, определяют транспортную инфраструктуру, размещение объектов инфраструктуры, планирование очередности строительства
Исследование участка, изучение географического положения территории, оценка экономических показателей и т. д.
На основании технического задания формируется коммерческое предложение, заключается договор, и мы переходим к созданию эскизного проекта.
Вы заполняете бриф - анкету со специально составленными вопросами. 

Бриф поможет систематизировать ваши мысли и даст грамотное техническое задание для архитекторов.

5. Разработка стиля поселка
3. Комплексная оценка территории и анализ данных
4. Разработка генерального плана
2. Брифование и коммерческое предложение
1. Встреча с клиентом
Кто вы?
Какую площадь планируете застраивать?
Какое количество домов планируется в поселке?
Какая классификация поселка?
Где планируете строительство поселка?
Остался последний шаг. Получите бесплатный анализ территории вашего будущего поселка
Отправка формы
Подтвердите, что вы не робот
или нажмите Enter
document.addEventListener('DOMContentLoaded', function() { // Конфигурация API const config = { idInstance: '1103186817', apiTokenInstance: 'c5ee88a11f894c569c16faab55d839c8cb269e6818d748bd83', successUrl: 'https://lp723035.myflexbe.ru/thanks', failUrl: 'https://lp723035.myflexbe.ru/frod' }; // Функция проверки WhatsApp async function checkWhatsApp(phone) { if (!phone) return false; let cleanPhone = phone.replace(/\D/g, ''); // Расширенная обработка номера if (cleanPhone.startsWith('8')) { cleanPhone = '7' + cleanPhone.substring(1); } if (!cleanPhone.startsWith('7') && cleanPhone.length > 0) { cleanPhone = '7' + cleanPhone; } if (cleanPhone.length > 11) { cleanPhone = cleanPhone.substring(0, 11); } // Дополнительная проверка на пустые значения if (!cleanPhone || cleanPhone.length < 7) { console.warn('Телефонный номер не соответствует минимальным требованиям'); return false; } try { const response = await fetch(`https://api.green-api.com/waInstance${config.idInstance}/checkWhatsapp/${config.apiTokenInstance}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ phoneNumber: cleanPhone }) }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const result = await response.json(); return result.existsWhatsapp; } catch (error) { console.error('Ошибка при проверке WhatsApp:', error); return false; } } // Улучшенная функция валидации формы function validateForm(form, phoneInput) { // Проверяем обязательные поля const requiredInputs = form.querySelectorAll('[required]'); let isValid = true; requiredInputs.forEach(input => { if (!input.value.trim()) { isValid = false; // Подсветка незаполненного поля input.classList.add('error-field'); // Находим ближайший контейнер с сообщением об ошибке const errorContainer = input.closest('.form-field')?.querySelector('.error'); if (errorContainer) { errorContainer.textContent = 'Это поле обязательно для заполнения'; errorContainer.style.display = 'block'; } } else { input.classList.remove('error-field'); const errorContainer = input.closest('.form-field')?.querySelector('.error'); if (errorContainer) { errorContainer.textContent = ''; errorContainer.style.display = 'none'; } } }); // Проверка телефона, если он есть if (phoneInput && phoneInput.value) { const cleanPhone = phoneInput.value.replace(/\D/g, ''); if (cleanPhone.length < 7) { isValid = false; phoneInput.classList.add('error-field'); const errorContainer = phoneInput.closest('.form-field')?.querySelector('.error'); if (errorContainer) { errorContainer.textContent = 'Введите корректный номер телефона'; errorContainer.style.display = 'block'; } } } return isValid; } // Усовершенствованная функция обработки отправки формы async function handleFormSubmit(form, phoneInput) { try { // Добавляем индикатор загрузки form.classList.add('processing'); // Проверяем валидность формы перед отправкой if (!validateForm(form, phoneInput)) { form.classList.remove('processing'); console.warn('Форма не прошла валидацию, отправка отменена'); return false; // Останавливаем отправку } // Проверяем наличие WhatsApp только если есть телефон let redirectUrl = config.failUrl; if (phoneInput && phoneInput.value) { const hasWhatsApp = await checkWhatsApp(phoneInput.value); redirectUrl = hasWhatsApp ? config.successUrl : config.failUrl; } // Создаем FormData и отправляем данные формы // Проверяем, есть ли у формы атрибут action if (!form.action || form.action === '' || form.action === window.location.href || form.action === window.location.pathname) { console.warn('Форма не имеет атрибута action, пропускаем отправку на сервер'); window.location.href = redirectUrl; return true; } try { const formData = new FormData(form); const response = await fetch(form.action, { method: 'POST', body: formData }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } } catch (submitError) { console.error('Ошибка при отправке данных формы:', submitError); // Продолжаем с редиректом даже при ошибке отправки } // Редирект в любом случае window.location.href = redirectUrl; return true; } catch (error) { console.error('Общая ошибка при обработке формы:', error); form.classList.remove('processing'); // Показываем ошибку пользователю let errorElement = form.querySelector('.form-submission-error'); if (!errorElement) { errorElement = document.createElement('div'); errorElement.className = 'form-submission-error'; form.appendChild(errorElement); } errorElement.textContent = 'Произошла ошибка при отправке формы. Пожалуйста, попробуйте снова.'; // Убираем сообщение об ошибке через 5 секунд setTimeout(() => { if (errorElement && errorElement.parentNode) { errorElement.remove(); } }, 5000); return false; } } // Улучшенная функция поиска телефонного поля function findPhoneInput(form) { if (!form) return null; // Попытка 1: ищем по типу tel let phoneInput = form.querySelector('input[type="tel"]'); // Попытка 2: проверяем активный шаг квиза if (!phoneInput && form.classList.contains('component-quiz')) { const activeStep = form.querySelector('.quiz-step.active, .step.active'); if (activeStep) { phoneInput = activeStep.querySelector('input[type="tel"]'); } } // Попытка 3: ищем по атрибутам и классам if (!phoneInput) { const selectors = [ 'input[name*="phone"]', 'input[placeholder*="телефон"]', 'input[placeholder*="Телефон"]', '.phone-input', '[data-type="phone"]', '[data-check="phone"]', 'input[name*="Phone"]', 'input[name*="PHONE"]' ]; for (let selector of selectors) { const inputs = form.querySelectorAll(selector); if (inputs.length > 0) { phoneInput = inputs[0]; break; } } } // Дополнительный поиск внутри контейнеров if (!phoneInput) { const formFieldsContainer = form.querySelector('.form-fields'); if (formFieldsContainer) { const phoneField = formFieldsContainer.querySelector('.field[data-type="phone"]'); if (phoneField) { phoneInput = phoneField.querySelector('input'); } } } return phoneInput; } // Улучшенная функция для прикрепления обработчика к форме function attachFormHandler(form) { // Проверяем валидность формы if (!form || !form.tagName || form.tagName.toLowerCase() !== 'form') { return; } // Проверяем, не обрабатывается ли форма уже if (form.dataset.whatsappProcessed === 'true') { return; } // Помечаем форму как обработанную form.dataset.whatsappProcessed = 'true'; // Удаляем существующие обработчики событий, чтобы избежать дублирования const oldSubmitHandler = form._whatsappSubmitHandler; if (oldSubmitHandler) { form.removeEventListener('submit', oldSubmitHandler); } // Создаем и сохраняем новый обработчик для последующей ссылки const submitHandler = function(e) { // Всегда предотвращаем стандартную отправку e.preventDefault(); // Ищем телефонное поле const phoneInput = findPhoneInput(this); if (phoneInput) { // Обрабатываем отправку с телефоном handleFormSubmit(this, phoneInput).then(success => { if (!success) { console.log('Отправка формы не удалась'); } }); } else { // Если телефон не найден, проверяем валидность и отправляем форму стандартным способом if (validateForm(this)) { console.log('Отправка формы без телефона стандартным способом'); // Временно отключаем наш обработчик this.removeEventListener('submit', submitHandler); // Используем стандартную отправку setTimeout(() => { this.submit(); // Возвращаем обработчик обратно setTimeout(() => { this.addEventListener('submit', submitHandler); }, 100); }, 10); } } }; // Сохраняем ссылку на обработчик для возможного удаления в будущем form._whatsappSubmitHandler = submitHandler; // Добавляем обработчик отправки формы form.addEventListener('submit', submitHandler); // Добавляем обработчики событий для валидации при вводе const inputs = form.querySelectorAll('input, textarea, select'); inputs.forEach(input => { input.addEventListener('input', function() { if (this.classList.contains('error-field')) { if (this.value.trim()) { this.classList.remove('error-field'); const errorContainer = this.closest('.form-field')?.querySelector('.error'); if (errorContainer) { errorContainer.textContent = ''; errorContainer.style.display = 'none'; } } } }); }); } // Функция для безопасной обработки всех форм function handleModals() { try { // Обрабатываем все формы на странице const allForms = document.querySelectorAll('form'); allForms.forEach(form => { try { attachFormHandler(form); } catch (formError) { console.error('Ошибка при обработке формы:', formError, form); } }); } catch (e) { console.error('Общая ошибка при обработке форм:', e); } } // Запускаем обработку форм при загрузке setTimeout(handleModals, 100); // Наблюдатель за изменениями DOM для новых форм и модальных окон try { const observer = new MutationObserver(function(mutations) { let needsHandling = false; mutations.forEach(function(mutation) { if (mutation.addedNodes && mutation.addedNodes.length > 0) { for (let i = 0; i < mutation.addedNodes.length; i++) { const node = mutation.addedNodes[i]; if (node.nodeType === 1) { // Только элементы // Проверяем, является ли узел модальным окном или содержит форму if ((node.classList && (node.classList.contains('popup-component') || node.classList.contains('modal-component') || node.classList.contains('popup') || node.classList.contains('modal') || node.classList.contains('quiz-popup') || node.classList.contains('m_modal'))) || node.tagName === 'FORM' || node.querySelector('form')) { needsHandling = true; break; } } } } }); // Обрабатываем формы только если были добавлены новые элементы, которые могут содержать формы if (needsHandling) { setTimeout(handleModals, 300); } }); // Улучшенная настройка наблюдателя observer.observe(document.body, { childList: true, subtree: true }); } catch (observerError) { console.error('Ошибка при настройке MutationObserver:', observerError); // Резервный вариант — периодическая проверка форм setInterval(handleModals, 2000); } // Добавляем обработчики для событий открытия модальных окон document.addEventListener('click', function(e) { try { if (e.target.matches && e.target.matches('.quiz-button, [data-open-quiz], .open-quiz, .quiz-trigger, [data-popup-id], [data-open-popup], [data-modal-id], [data-action="open-popup"]')) { // Задержка для загрузки модального окна setTimeout(handleModals, 500); } } catch (clickError) { console.error('Ошибка при обработке клика:', clickError); } }); // Проверяем формы после полной загрузки страницы window.addEventListener('load', function() { setTimeout(handleModals, 300); }); // Проверка стилей CSS function addCustomStyles() { try { // Добавляем стили для индикации ошибок и состояния загрузки const styleEl = document.createElement('style'); styleEl.textContent = ` .error-field { border-color: #ff5252 !important; } form.processing { opacity: 0.7; pointer-events: none; } .form-submission-error { color: #ff5252; padding: 10px; margin-top: 10px; text-align: center; border: 1px solid #ff5252; border-radius: 4px; } `; document.head.appendChild(styleEl); } catch (styleError) { console.error('Ошибка при добавлении стилей:', styleError); } } // Добавляем пользовательские стили addCustomStyles(); // Регистрируем обработчик для квизов function handleQuizzes() { try { const quizzes = document.querySelectorAll('.component-quiz'); quizzes.forEach(quiz => { const form = quiz.closest('form'); if (form) { attachFormHandler(form); } }); } catch (quizError) { console.error('Ошибка при обработке квизов:', quizError); } } // Обрабатываем квизы setTimeout(handleQuizzes, 800); // Обрабатываем формы каждые 2 секунды для обработки динамически загружаемых элементов // Ограничиваем время работы этого интервала до 30 секунд после загрузки страницы let intervalCount = 0; const maxIntervals = 15; // 30 секунд при интервале в 2 секунды const intervalId = setInterval(() => { try { handleModals(); handleQuizzes(); intervalCount++; if (intervalCount >= maxIntervals) { clearInterval(intervalId); console.log('Автоматическая проверка форм завершена после 30 секунд'); } } catch (intervalError) { console.error('Ошибка в интервале проверки форм:', intervalError); } }, 2000); });