246 lines
12 KiB
PHP
246 lines
12 KiB
PHP
<section class="info-page">
|
||
<div class="info-hero">
|
||
<div>
|
||
<p class="eyebrow">Москва и Московская область</p>
|
||
<h1>Доставка и самовывоз</h1>
|
||
<p>Привозим заказы после подтверждения по телефону. В день заказа можно получить товар, если оформить заказ в будний день до 14:00.</p>
|
||
</div>
|
||
<div class="info-visual" aria-hidden="true">
|
||
<span></span>
|
||
<strong>18:00-24:00</strong>
|
||
<small>Пн.-Пт.</small>
|
||
</div>
|
||
</div>
|
||
|
||
<section class="delivery-calculator panel">
|
||
<div class="section-heading">
|
||
<div>
|
||
<p class="eyebrow">Калькулятор</p>
|
||
<h2>Рассчитать доставку</h2>
|
||
</div>
|
||
<span class="calculator-note">Расчет предварительный, финально подтвердит менеджер.</span>
|
||
</div>
|
||
|
||
<form class="calculator-form" id="delivery-calculator">
|
||
<label>
|
||
Адрес доставки
|
||
<input type="text" name="address" placeholder="Например: Москва, ул. Привольная, 13к1">
|
||
<small class="cart-address-status" id="delivery-address-status" hidden></small>
|
||
</label>
|
||
|
||
<label>
|
||
Сумма заказа, руб.
|
||
<input type="number" name="order_sum" min="0" step="100" value="5000">
|
||
</label>
|
||
|
||
<label>
|
||
Способ получения
|
||
<select name="zone">
|
||
<option value="inside_mkad">Доставка внутри МКАД</option>
|
||
<option value="outside_mkad">Доставка за МКАД</option>
|
||
<option value="pickup">Самовывоз</option>
|
||
</select>
|
||
</label>
|
||
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" name="lift">
|
||
Нужен подъем до квартиры/офиса
|
||
</label>
|
||
|
||
<button class="secondary-button calculator-submit" type="button" data-delivery-calc-button>Рассчитать</button>
|
||
</form>
|
||
|
||
<div class="calculator-result" id="delivery-result">
|
||
<strong>Доставка: 0 руб.</strong>
|
||
<span>Введите сумму заказа и условия доставки.</span>
|
||
</div>
|
||
</section>
|
||
|
||
<div class="info-grid">
|
||
<section class="info-card">
|
||
<figure class="delivery-vehicle-visual delivery-city">
|
||
<img src="/assets/img/delivery-van-city.svg" alt="Рефрижератор Рыбсток для доставки внутри МКАД">
|
||
</figure>
|
||
<h2>Доставка внутри МКАД</h2>
|
||
<ul class="clean-list">
|
||
<li>Заказы от 5000 руб. - бесплатно до подъезда.</li>
|
||
<li>В остальных случаях доставка 599 руб.</li>
|
||
<li>Минимальная сумма заказа на доставку внутри МКАД - 2000 руб.</li>
|
||
<li>Подъем до квартиры или офиса - 390 руб.</li>
|
||
</ul>
|
||
<p class="muted">Водитель может оставить заказ у консьержа, соседа и т. д. при полной оплате по QR-коду и оплате подъема.</p>
|
||
</section>
|
||
|
||
<section class="info-card">
|
||
<figure class="delivery-vehicle-visual delivery-region">
|
||
<img src="/assets/img/delivery-van-region.svg" alt="Рефрижератор Рыбсток для доставки за МКАД">
|
||
</figure>
|
||
<h2>Доставка за МКАД</h2>
|
||
<ul class="clean-list">
|
||
<li>До 10 км от МКАД бесплатная доставка от 10000 руб.</li>
|
||
<li>От 10 км и дальше: каждый километр от МКАД = 1000 руб. к сумме заказа для бесплатной доставки.</li>
|
||
<li>Если заказ не попадает под бесплатную доставку: 199 руб. + 60 руб./км.</li>
|
||
<li>Минимальная сумма заказа - 5000 руб.</li>
|
||
<li>Подъем до квартиры или офиса - 390 руб.</li>
|
||
</ul>
|
||
<p class="muted">Например, 15 км от МКАД - бесплатная доставка от 15000 руб.; 17 км - от 17000 руб.</p>
|
||
</section>
|
||
</div>
|
||
|
||
<div class="info-grid three">
|
||
<section class="info-card compact">
|
||
<h2>Как мы развозим</h2>
|
||
<p>Понедельник-пятница: 18:00-24:00 без ограничения по точному времени.</p>
|
||
<p>При построении маршрута учитываем комментарии к заказу, например: “буду дома после 19:00”.</p>
|
||
</section>
|
||
|
||
<section class="info-card compact">
|
||
<h2>Самовывоз</h2>
|
||
<p>Понедельник-пятница: 18:00-21:00.</p>
|
||
<p>Минимальная сумма заказа на самовывоз - 1 руб. Самовывоз возможен только после подтверждения заказа.</p>
|
||
</section>
|
||
|
||
<section class="info-card compact">
|
||
<h2>Когда получить заказ</h2>
|
||
<p>Заказы до 14:00 в будние дни можно получить день в день.</p>
|
||
<p>Заказы после 14:00 - на следующий или другой удобный для вас день.</p>
|
||
</section>
|
||
</div>
|
||
|
||
<section class="info-card">
|
||
<h2>Оплата при получении</h2>
|
||
<p>На сайте ничего оплачивать не нужно. Вы оформляете заказ, чтобы мы его увидели, проверили наличие и собрали с учетом ваших пожеланий. Оплата товара производится только при получении.</p>
|
||
<p>При доставке и самовывозе можно оплатить наличными или QR-кодом. Безналичный расчет и “Меркурий” обсуждаются индивидуально для заказов от 30000 руб.</p>
|
||
</section>
|
||
</section>
|
||
|
||
<script>
|
||
window.addEventListener('load', () => {
|
||
const form = document.getElementById('delivery-calculator');
|
||
const result = document.getElementById('delivery-result');
|
||
const addressStatus = document.getElementById('delivery-address-status');
|
||
|
||
if (!form || !result) {
|
||
return;
|
||
}
|
||
|
||
const formatRub = (value) => window.RybStockDelivery?.formatRub
|
||
? window.RybStockDelivery.formatRub(value)
|
||
: new Intl.NumberFormat('ru-RU').format(Math.max(0, Math.round(value))) + ' руб.';
|
||
let resolvedDistance = 0;
|
||
let resolvedZone = '';
|
||
let addressTimer = null;
|
||
let addressRequestId = 0;
|
||
|
||
const setAddressStatus = (message) => {
|
||
if (!addressStatus) {
|
||
return;
|
||
}
|
||
|
||
addressStatus.hidden = message === '';
|
||
addressStatus.textContent = message;
|
||
};
|
||
|
||
const calculate = () => {
|
||
const data = new FormData(form);
|
||
const orderSum = Number(data.get('order_sum') || 0);
|
||
const zone = String(data.get('zone') || 'inside_mkad');
|
||
const lift = data.get('lift') === 'on';
|
||
const effectiveZone = resolvedZone === 'outside'
|
||
? 'outside_mkad'
|
||
: (resolvedZone === 'inside' ? 'inside_mkad' : zone);
|
||
const distance = effectiveZone === 'outside_mkad' ? resolvedDistance : 0;
|
||
const quote = window.RybStockDelivery?.quote
|
||
? window.RybStockDelivery.quote(effectiveZone, orderSum, distance, lift, resolvedZone)
|
||
: { label: 'Расчет доставки', note: 'Обновите страницу, чтобы загрузить калькулятор.', total: 0, minimumMessage: '' };
|
||
const title = quote.selected ? `${quote.label}: ${formatRub(quote.total)}` : quote.label;
|
||
const liftNote = lift && effectiveZone !== 'pickup' ? ` Подъем включен: 390 руб.` : '';
|
||
const minimumNote = quote.minimumMessage ? ` ${quote.minimumMessage}` : '';
|
||
|
||
result.innerHTML = `<strong>${title}</strong><span>${quote.note}${liftNote}${minimumNote}</span>`;
|
||
};
|
||
|
||
const resolveAddress = () => {
|
||
const address = String(new FormData(form).get('address') || '').trim();
|
||
const zone = String(new FormData(form).get('zone') || 'inside_mkad');
|
||
const requestId = ++addressRequestId;
|
||
|
||
if (zone === 'pickup') {
|
||
resolvedDistance = 0;
|
||
resolvedZone = '';
|
||
setAddressStatus('');
|
||
calculate();
|
||
return;
|
||
}
|
||
|
||
if (address.length < 6) {
|
||
resolvedDistance = 0;
|
||
resolvedZone = '';
|
||
setAddressStatus('Введите адрес и выберите вариант из подсказки, чтобы сайт рассчитал доставку автоматически.');
|
||
calculate();
|
||
return;
|
||
}
|
||
|
||
setAddressStatus('Рассчитываем расстояние по адресу...');
|
||
|
||
if (!window.RybStockDelivery?.resolveAddress) {
|
||
resolvedDistance = 0;
|
||
resolvedZone = '';
|
||
setAddressStatus('Калькулятор еще загружается. Если расчет не появился, обновите страницу.');
|
||
calculate();
|
||
return;
|
||
}
|
||
|
||
window.RybStockDelivery.resolveAddress(address)
|
||
.then((resolved) => {
|
||
if (requestId !== addressRequestId) {
|
||
return;
|
||
}
|
||
|
||
resolvedDistance = Number(resolved.distance || 0);
|
||
resolvedZone = String(resolved.zone || '');
|
||
if (resolvedZone === 'outside') {
|
||
form.querySelector('[name="zone"]').value = 'outside_mkad';
|
||
} else if (resolvedZone === 'inside') {
|
||
form.querySelector('[name="zone"]').value = 'inside_mkad';
|
||
}
|
||
setAddressStatus(resolved.status || '');
|
||
calculate();
|
||
})
|
||
.catch(() => {
|
||
if (requestId !== addressRequestId) {
|
||
return;
|
||
}
|
||
|
||
resolvedDistance = 0;
|
||
resolvedZone = '';
|
||
setAddressStatus('Не удалось автоматически рассчитать адрес. Менеджер уточнит доставку по телефону.');
|
||
calculate();
|
||
});
|
||
};
|
||
|
||
const scheduleResolveAddress = () => {
|
||
window.clearTimeout(addressTimer);
|
||
addressTimer = window.setTimeout(resolveAddress, 700);
|
||
};
|
||
|
||
form.addEventListener('input', calculate);
|
||
form.addEventListener('input', (event) => {
|
||
if (event.target.matches('[name="address"]')) {
|
||
scheduleResolveAddress();
|
||
}
|
||
});
|
||
form.addEventListener('change', () => {
|
||
resolveAddress();
|
||
calculate();
|
||
});
|
||
form.querySelector('[data-delivery-calc-button]')?.addEventListener('click', () => {
|
||
resolveAddress();
|
||
calculate();
|
||
});
|
||
window.RybStockDelivery?.setupAddressSuggestions?.();
|
||
resolveAddress();
|
||
calculate();
|
||
});
|
||
</script>
|