доставка в плавающем
This commit is contained in:
@@ -6,6 +6,9 @@
|
||||
<div class="cart-weight-notice">
|
||||
Весовые позиции пересчитываются при сборке по фактическому весу. Если Вам нужна итоговая сумма до получения товара, отметьте это в форме заказа: после сборки менеджер перезвонит и сообщит сумму.
|
||||
</div>
|
||||
<div class="cart-weight-notice cart-live-notice">
|
||||
При каждом открытии корзины сайт сверяет наличие, актуальные цены и фасовки. Если позиция закончилась, она не попадет в сумму заказа; если изменилась фасовка, мы покажем это рядом с товаром.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cart-layout cart-layout-checkout">
|
||||
|
||||
@@ -45,7 +45,10 @@
|
||||
<p class="eyebrow">Как пройти</p>
|
||||
<h2>Маршрут к пункту самовывоза</h2>
|
||||
</div>
|
||||
<a class="subtle-link" href="https://yandex.ru/maps/?text=Москва%2C%20улица%20Привольная%2C%2013%D0%BA1" target="_blank" rel="noopener">Открыть в Яндекс.Картах</a>
|
||||
<div class="route-actions">
|
||||
<a class="subtle-link" href="https://yandex.ru/maps/?text=Москва%2C%20улица%20Привольная%2C%2013%D0%BA1" target="_blank" rel="noopener">Открыть в Яндекс.Картах</a>
|
||||
<a class="secondary-button" href="https://yandex.ru/maps/?rtext=%D0%BC%D0%B5%D1%82%D1%80%D0%BE%20%D0%9B%D0%B5%D1%80%D0%BC%D0%BE%D0%BD%D1%82%D0%BE%D0%B2%D1%81%D0%BA%D0%B8%D0%B9%20%D0%BF%D1%80%D0%BE%D1%81%D0%BF%D0%B5%D0%BA%D1%82~%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0%2C%20%D1%83%D0%BB.%20%D0%9F%D1%80%D0%B8%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F%2C%2013%D0%BA1&rtt=pd" target="_blank" rel="noopener">Маршрут от метро</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="route-layout">
|
||||
@@ -60,7 +63,7 @@
|
||||
<div class="route-steps">
|
||||
<ol>
|
||||
<li>Доезжайте до станции метро “Лермонтовский проспект”.</li>
|
||||
<li>Идите к адресу: ул. Привольная, д. 13к1.</li>
|
||||
<li>Выходите в сторону ул. Привольная и идите к дому 13к1.</li>
|
||||
<li>Зайдите во двор дома.</li>
|
||||
<li>Ориентир - крыльцо Wildberries, вход со двора.</li>
|
||||
<li>Перед самовывозом дождитесь подтверждения заказа по телефону.</li>
|
||||
|
||||
+117
-41
@@ -25,6 +25,7 @@
|
||||
<label>
|
||||
Адрес доставки
|
||||
<input type="text" name="address" placeholder="Например: Москва, ул. Привольная, 13к1">
|
||||
<small class="cart-address-status" id="delivery-address-status" hidden></small>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
@@ -35,21 +36,18 @@
|
||||
<label>
|
||||
Способ получения
|
||||
<select name="zone">
|
||||
<option value="inside">Доставка внутри МКАД</option>
|
||||
<option value="outside">Доставка за МКАД</option>
|
||||
<option value="inside_mkad">Доставка внутри МКАД</option>
|
||||
<option value="outside_mkad">Доставка за МКАД</option>
|
||||
<option value="pickup">Самовывоз</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label class="km-field">
|
||||
Км от МКАД
|
||||
<input type="number" name="km" min="0" step="1" value="0">
|
||||
</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">
|
||||
@@ -60,7 +58,9 @@
|
||||
|
||||
<div class="info-grid">
|
||||
<section class="info-card">
|
||||
<div class="info-card-visual delivery-city"></div>
|
||||
<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>
|
||||
@@ -72,7 +72,9 @@
|
||||
</section>
|
||||
|
||||
<section class="info-card">
|
||||
<div class="info-card-visual delivery-region"></div>
|
||||
<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>
|
||||
@@ -113,57 +115,131 @@
|
||||
</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) => new Intl.NumberFormat('ru-RU').format(Math.max(0, Math.round(value))) + ' руб.';
|
||||
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');
|
||||
const km = Math.max(0, Number(data.get('km') || 0));
|
||||
const zone = String(data.get('zone') || 'inside_mkad');
|
||||
const lift = data.get('lift') === 'on';
|
||||
const liftPrice = lift ? 390 : 0;
|
||||
let delivery = 0;
|
||||
let title = '';
|
||||
let note = '';
|
||||
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}` : '';
|
||||
|
||||
form.querySelector('.km-field').style.display = zone === 'outside' ? 'grid' : 'none';
|
||||
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') {
|
||||
delivery = 0;
|
||||
title = 'Самовывоз: бесплатно';
|
||||
note = orderSum < 1
|
||||
? 'Минимальная сумма заказа на самовывоз - 1 руб.'
|
||||
: 'Самовывоз возможен после подтверждения заказа.';
|
||||
} else if (zone === 'inside') {
|
||||
delivery = orderSum >= 5000 ? 0 : 599;
|
||||
title = delivery === 0 ? 'Доставка внутри МКАД: бесплатно' : 'Доставка внутри МКАД: ' + formatRub(delivery);
|
||||
note = orderSum < 2000
|
||||
? 'Минимальная сумма заказа на доставку внутри МКАД - 2000 руб.'
|
||||
: 'Бесплатная доставка внутри МКАД от 5000 руб.';
|
||||
} else {
|
||||
const freeThreshold = km <= 10 ? 10000 : Math.ceil(km) * 1000;
|
||||
delivery = orderSum >= freeThreshold ? 0 : 199 + km * 60;
|
||||
title = delivery === 0 ? 'Доставка за МКАД: бесплатно' : 'Доставка за МКАД: ' + formatRub(delivery);
|
||||
note = 'Порог бесплатной доставки для этого расстояния: ' + formatRub(freeThreshold) + '. Платная доставка: 199 руб. + 60 руб./км.';
|
||||
if (orderSum < 5000) {
|
||||
note += ' Минимальная сумма заказа за МКАД - 5000 руб.';
|
||||
}
|
||||
resolvedDistance = 0;
|
||||
resolvedZone = '';
|
||||
setAddressStatus('');
|
||||
calculate();
|
||||
return;
|
||||
}
|
||||
|
||||
const total = delivery + liftPrice;
|
||||
result.innerHTML = '<strong>' + title + '</strong><span>' + note + (lift ? ' Подъем: 390 руб. Итого с подъемом: ' + formatRub(total) + '.' : '') + '</span>';
|
||||
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('change', 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>
|
||||
|
||||
@@ -295,6 +295,68 @@ $arrivalDate = $lastArrival->format('j') . ' ' . $months[(int) $lastArrival->for
|
||||
});
|
||||
</script>
|
||||
|
||||
<section class="wishlist-request-panel" id="wishlist-request">
|
||||
<div class="wishlist-request-copy">
|
||||
<p class="eyebrow">Запрос позиции</p>
|
||||
<h2>Одна голова хорошо, две лучше</h2>
|
||||
<p>Нужна позиция, но нигде не можете ее найти? Отправьте нам наименование и объем. Если сможем помочь с поиском, менеджер свяжется с Вами.</p>
|
||||
<span>Для частных покупателей и бизнеса</span>
|
||||
</div>
|
||||
<div class="wishlist-request-card">
|
||||
<form class="wishlist-request-form" action="/wishlist-request" method="post" enctype="multipart/form-data">
|
||||
<label>
|
||||
<span>Имя</span>
|
||||
<input type="text" name="customer_name" placeholder="Как к Вам обращаться" required>
|
||||
</label>
|
||||
<label>
|
||||
<span>Телефон</span>
|
||||
<input type="tel" name="phone" placeholder="+7 ___ ___-__-__">
|
||||
</label>
|
||||
<label>
|
||||
<span>Email</span>
|
||||
<input type="email" name="email" placeholder="mail@example.ru">
|
||||
</label>
|
||||
<label class="wide">
|
||||
<span>Что нужно найти</span>
|
||||
<textarea name="request_text" rows="5" placeholder="Например: филе судака 10 кг, икра в стеклянной банке, креветки нужного размера" required></textarea>
|
||||
</label>
|
||||
<label class="file-field wide">
|
||||
<span>Прикрепить файлы</span>
|
||||
<input type="file" name="wishlist_files[]" multiple>
|
||||
<small>Можно приложить фото, список или пример товара.</small>
|
||||
</label>
|
||||
<p class="form-hint wide">Телефон или email - достаточно одного контакта.</p>
|
||||
<button class="primary-button wide" type="submit">Отправить запрос</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="home-delivery-summary" aria-label="Доставка и выгода Рыбсток">
|
||||
<div>
|
||||
<p class="eyebrow">Перед оформлением заказа</p>
|
||||
<h2>Доставка, оплата при получении и подарок за наличный расчет</h2>
|
||||
<p>Мы привозим заказы после подтверждения по телефону, а оплату принимаем только при получении. При оплате наличными сайт сам пересчитает выгоду в корзине: считать вручную ничего не нужно.</p>
|
||||
</div>
|
||||
<div class="home-delivery-benefits">
|
||||
<article>
|
||||
<span>от 7 000 руб.</span>
|
||||
<strong>-300 руб.</strong>
|
||||
<p>Подарок при оплате наличными.</p>
|
||||
</article>
|
||||
<article>
|
||||
<span>внутри МКАД</span>
|
||||
<strong>0 руб.</strong>
|
||||
<p>Бесплатно от 5000 руб., иначе 599 руб.</p>
|
||||
</article>
|
||||
<article>
|
||||
<span>за МКАД</span>
|
||||
<strong>по адресу</strong>
|
||||
<p>Сайт рассчитает предварительную стоимость доставки.</p>
|
||||
</article>
|
||||
</div>
|
||||
<a class="primary-button" href="/delivery">Посмотреть условия доставки</a>
|
||||
</section>
|
||||
|
||||
<?php if (false): ?>
|
||||
<div class="content-grid">
|
||||
<section class="panel">
|
||||
|
||||
Reference in New Issue
Block a user