make form buy-by-phone

This commit is contained in:
Roman Pyrih
2026-01-13 16:01:05 +01:00
parent 5aa89eb4a4
commit 0751588e2e
8 changed files with 892 additions and 357 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -4537,3 +4537,217 @@ section#checkout-payment-step {
}
}
}
#buy-by-phone-popup {
position: fixed;
inset: 0;
z-index: 999999;
opacity: 0;
visibility: hidden;
display: flex;
align-items: center;
justify-content: center;
transition: opacity 250ms ease, visibility 250ms ease;
overflow: auto;
&.active {
opacity: 1;
visibility: visible;
}
&::before {
content: '';
position: fixed;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.2);
backdrop-filter: blur(2px);
}
.buy-by-phone-popup--wrapper {
position: relative;
width: 100%;
max-width: 700px;
padding: 30px;
background: #fff;
border: 1px solid #e5e5e5;
border-radius: 5px;
z-index: 1;
.popup-header {
position: relative;
&--close {
position: absolute;
top: -25px;
right: -20px;
.close-popup {
font-size: 16px;
}
}
}
.popup-body {
display: grid;
grid-template-columns: 1fr 1fr;
max-height: calc(100vh - 130px);
overflow-y: auto;
padding: 10px 10px 10px 0;
column-gap: 20px;
.popup-body--left {
display: flex;
align-items: center;
.popup-img {
.product-cover {
width: 100%;
max-width: fit-content;
margin-left: auto;
margin-right: auto;
}
}
}
.popup-body--right {
display: flex;
justify-content: center;
flex-direction: column;
p {
color: #000;
font-size: 14px;
font-weight: 600;
}
.form-group {
margin-bottom: 5px;
.form-control {
border-radius: 3px;
&.form-control-name,
&.form-control-phone {
&::placeholder {
color: #000;
}
}
}
&.form-group-radio {
display: flex;
flex-direction: row;
align-items: center;
gap: 15px;
.radio-inline {
display: flex;
align-items: center;
gap: 5px;
input[type='radio'] {
width: 20px;
height: 20px;
}
}
}
&.form-group-polityka {
display: flex;
flex-direction: row;
gap: 10px;
align-items: baseline;
input#polityka {
width: fit-content;
}
label {
text-align: left;
font-size: 10px;
margin-bottom: 0;
}
}
}
.form-cols {
display: grid;
grid-template-columns: 1fr 1fr;
column-gap: 5px;
font-size: 16px;
}
.popup-body-top {
> p {
color: #e79332;
> a {
color: #e79332;
text-decoration: underline;
}
}
}
.popup-input-alert {
color: #ff0000;
}
}
@media (max-width: 700px) {
grid-template-columns: 1fr;
.popup-body--left {
display: none;
}
}
}
.popup-alert {
display: none;
position: absolute;
inset: 0;
&.active {
display: block;
}
&::after {
content: '';
position: absolute;
inset: -1px;
background: rgba(0, 0, 0, 0.3);
border-radius: 5px;
backdrop-filter: blur(2px);
}
.popup-alert-wrapper {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
padding: 30px;
background: #fff;
border: 1px solid #e5e5e5;
border-radius: 5px;
z-index: 1;
width: 100%;
max-width: 300px;
.popup-alert-close {
position: absolute;
top: 5px;
right: 10px;
font-size: 16px;
}
.popup-alert-data {
p {
margin: 10px 0 0 0;
}
}
}
}
}
}

View File

@@ -295,202 +295,337 @@ jQuery(document).ready(function ($) {
$btnBox.removeClass('active')
}
})
});
})
/* custom.js — LEKKIE przeniesienie sekcji .custom-buttons
Góra: klony top-level bloków (dzieci #category-description) z WYŁĄCZNIE .custom-buttons
Dół: oryginał bez sekcji .custom-buttons
NIE DZIAŁA podczas edycji w Elementor/Creative Elements.
*/
(function () {
'use strict';
;(function () {
'use strict'
// --- GUARD: nie uruchamiaj w trybie edycji (Elementor / Creative Elements) ---
function isEditing() {
var href = String(location.href || '');
var ref = String(document.referrer || '');
var topHref = '';
try { topHref = String(window.top.location.href || ''); } catch (e) { /* cross-origin fallback */ }
// --- GUARD: nie uruchamiaj w trybie edycji (Elementor / Creative Elements) ---
function isEditing() {
var href = String(location.href || '')
var ref = String(document.referrer || '')
var topHref = ''
try {
topHref = String(window.top.location.href || '')
} catch (e) {
/* cross-origin fallback */
}
// Zbiorcza „słomka” do przeszukania (ramka, referrer, parent)
var haystack = (href + ' ' + ref + ' ' + topHref).toLowerCase();
// Zbiorcza „słomka” do przeszukania (ramka, referrer, parent)
var haystack = (href + ' ' + ref + ' ' + topHref).toLowerCase()
// 1) Najpewniejsze: kontroler zaplecza CE
if (haystack.indexOf('controller=adminceeditor') !== -1) return true;
// 1) Najpewniejsze: kontroler zaplecza CE
if (haystack.indexOf('controller=adminceeditor') !== -1) return true
// 2) Podgląd/edycja elementora/CE
if (haystack.indexOf('elementor-preview') !== -1) return true;
// 2) Podgląd/edycja elementora/CE
if (haystack.indexOf('elementor-preview') !== -1) return true
// 3) Klasy/markery edytora na body w tej ramce
var body = document.body;
if (body && /\b(elementor-editor-active|ce-editor-active|ce-editing)\b/i.test(body.className)) return true;
// 3) Klasy/markery edytora na body w tej ramce
var body = document.body
if (
body &&
/\b(elementor-editor-active|ce-editor-active|ce-editing)\b/i.test(
body.className
)
)
return true
// 4) Panele edytora w oknie nadrzędnym (gdy front leci w iframe)
if (window.self !== window.top) {
try {
if (window.top.document.querySelector('#elementor-panel, .elementor-panel, #ce-editor, .ce-editor, .ce-panel')) {
return true;
}
} catch (e) { /* ignoruj brak dostępu */ }
}
// 4) Panele edytora w oknie nadrzędnym (gdy front leci w iframe)
if (window.self !== window.top) {
try {
if (
window.top.document.querySelector(
'#elementor-panel, .elementor-panel, #ce-editor, .ce-editor, .ce-panel'
)
) {
return true
}
} catch (e) {
/* ignoruj brak dostępu */
}
}
// 5) Ręczny wyłącznik
if (window.__CE_DISABLE_MOVE === true) return true;
// 5) Ręczny wyłącznik
if (window.__CE_DISABLE_MOVE === true) return true
return false;
}
return false
}
// Wstaw ZARAZ po definicji isEditing()
if (isEditing()) return;
// Wstaw ZARAZ po definicji isEditing()
if (isEditing()) return
var SOURCE_SEL = '#category-description';
var TARGET_SEL = '.row.\\31 11'; // .row.111 (esc)
var WRAP_ID = 'moved-category-structure';
var BUTTON_SEC = 'section.custom-buttons, section.custom-buttons1';
var ANY_SEC = 'section'; // lub 'section.elementor-top-section' jeśli chcesz zawęzić
var SOURCE_SEL = '#category-description'
var TARGET_SEL = '.row.\\31 11' // .row.111 (esc)
var WRAP_ID = 'moved-category-structure'
var BUTTON_SEC = 'section.custom-buttons, section.custom-buttons1'
var ANY_SEC = 'section' // lub 'section.elementor-top-section' jeśli chcesz zawęzić
var didFinish = false;
var obs = null;
var debounceId = null;
var didFinish = false
var obs = null
var debounceId = null
function ensureWrapper(target) {
var wrap = document.getElementById(WRAP_ID);
if (!wrap) {
wrap = document.createElement('div');
wrap.id = WRAP_ID;
wrap.className = 'moved-category-structure';
target.parentNode.insertBefore(wrap, target);
}
return wrap;
}
function ensureWrapper(target) {
var wrap = document.getElementById(WRAP_ID)
if (!wrap) {
wrap = document.createElement('div')
wrap.id = WRAP_ID
wrap.className = 'moved-category-structure'
target.parentNode.insertBefore(wrap, target)
}
return wrap
}
function topLevelBlocks(src) {
var out = [];
for (var i = 0; i < src.children.length; i++) {
var el = src.children[i];
if (el.nodeType === 1) out.push(el);
}
return out;
}
function topLevelBlocks(src) {
var out = []
for (var i = 0; i < src.children.length; i++) {
var el = src.children[i]
if (el.nodeType === 1) out.push(el)
}
return out
}
function cloneBlockWithOnlyButtons(block) {
var clone = block.cloneNode(true);
clone.querySelectorAll(ANY_SEC + ':not(.custom-buttons):not(.custom-buttons1)').forEach(function (sec) {
sec.remove();
});
clone.querySelectorAll('.ce-edit-btn, .ce-edit-outline').forEach(function (n) { n.remove(); });
if (!clone.querySelector(BUTTON_SEC)) return null;
return clone;
}
function cloneBlockWithOnlyButtons(block) {
var clone = block.cloneNode(true)
clone
.querySelectorAll(ANY_SEC + ':not(.custom-buttons):not(.custom-buttons1)')
.forEach(function (sec) {
sec.remove()
})
clone
.querySelectorAll('.ce-edit-btn, .ce-edit-outline')
.forEach(function (n) {
n.remove()
})
if (!clone.querySelector(BUTTON_SEC)) return null
return clone
}
function syncOnce() {
if (didFinish) return true;
function syncOnce() {
if (didFinish) return true
var src = document.querySelector(SOURCE_SEL);
var target = document.querySelector(TARGET_SEL);
if (!src || !target) return false;
var src = document.querySelector(SOURCE_SEL)
var target = document.querySelector(TARGET_SEL)
if (!src || !target) return false
var blocks = topLevelBlocks(src);
var blocksWithButtons = blocks.filter(function (b) { return !!b.querySelector(BUTTON_SEC); });
if (!blocksWithButtons.length) return false;
var blocks = topLevelBlocks(src)
var blocksWithButtons = blocks.filter(function (b) {
return !!b.querySelector(BUTTON_SEC)
})
if (!blocksWithButtons.length) return false
var wrap = ensureWrapper(target);
var wrap = ensureWrapper(target)
var frag = document.createDocumentFragment();
blocksWithButtons.forEach(function (b) {
var prunedClone = cloneBlockWithOnlyButtons(b);
if (prunedClone) frag.appendChild(prunedClone);
});
var frag = document.createDocumentFragment()
blocksWithButtons.forEach(function (b) {
var prunedClone = cloneBlockWithOnlyButtons(b)
if (prunedClone) frag.appendChild(prunedClone)
})
if (!frag.firstChild) return false;
if (!frag.firstChild) return false
while (wrap.firstChild) wrap.removeChild(wrap.firstChild);
wrap.appendChild(frag);
while (wrap.firstChild) wrap.removeChild(wrap.firstChild)
wrap.appendChild(frag)
src.querySelectorAll(BUTTON_SEC).forEach(function (sec) {
if (sec && sec.parentNode) sec.parentNode.removeChild(sec);
});
src.querySelectorAll(BUTTON_SEC).forEach(function (sec) {
if (sec && sec.parentNode) sec.parentNode.removeChild(sec)
})
didFinish = true;
if (obs) obs.disconnect();
return true;
}
didFinish = true
if (obs) obs.disconnect()
return true
}
function trySyncDebounced() {
if (debounceId) return;
debounceId = setTimeout(function () {
debounceId = null;
if (syncOnce() && obs) obs.disconnect();
}, 50);
}
function trySyncDebounced() {
if (debounceId) return
debounceId = setTimeout(function () {
debounceId = null
if (syncOnce() && obs) obs.disconnect()
}, 50)
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', trySyncDebounced, { once: true });
} else {
trySyncDebounced();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', trySyncDebounced, {
once: true,
})
} else {
trySyncDebounced()
}
obs = new MutationObserver(trySyncDebounced);
obs.observe(document.body || document.documentElement, { childList: true, subtree: true });
obs = new MutationObserver(trySyncDebounced)
obs.observe(document.body || document.documentElement, {
childList: true,
subtree: true,
})
if (window.prestashop && typeof window.prestashop.on === 'function') {
['updateProductList', 'updatedCart', 'updatedProduct'].forEach(function (ev) {
window.prestashop.on(ev, trySyncDebounced);
});
}
if (window.prestashop && typeof window.prestashop.on === 'function') {
;['updateProductList', 'updatedCart', 'updatedProduct'].forEach(function (
ev
) {
window.prestashop.on(ev, trySyncDebounced)
})
}
(function hookHistory() {
var _ps = history.pushState, _rs = history.replaceState;
function onNav() { trySyncDebounced(); }
history.pushState = function () { _ps.apply(this, arguments); onNav(); };
history.replaceState = function () { _rs.apply(this, arguments); onNav(); };
window.addEventListener('popstate', onNav);
})();
})();
;(function hookHistory() {
var _ps = history.pushState,
_rs = history.replaceState
function onNav() {
trySyncDebounced()
}
history.pushState = function () {
_ps.apply(this, arguments)
onNav()
}
history.replaceState = function () {
_rs.apply(this, arguments)
onNav()
}
window.addEventListener('popstate', onNav)
})()
})()
$(document).ready(function () {
function toggleChatWidget(isOpen) {
var $widget = $('div[data-testid="widgetButtonFrame"]')
var $scrollBox = $('.scroll-brn-box')
function toggleChatWidget(isOpen) {
var $widget = $('div[data-testid="widgetButtonFrame"]');
var $scrollBox = $('.scroll-brn-box')
if ($widget.length) {
if (isOpen) {
$widget.hide()
$scrollBox.hide()
} else {
$widget.show()
$scrollBox.show()
}
}
}
if ($widget.length) {
if (isOpen) {
$widget.hide();
$scrollBox.hide();
} else {
$widget.show();
$scrollBox.show();
}
}
}
function checkCartState() {
var $cart = $('.elementor-cart__container')
var isOpen = $cart.hasClass('elementor-cart--shown')
toggleChatWidget(isOpen)
}
function checkCartState() {
var $cart = $('.elementor-cart__container');
var isOpen = $cart.hasClass('elementor-cart--shown');
toggleChatWidget(isOpen);
}
$('a[href*="koszyk"][class*="elementor-button"]').on('click', function () {
setTimeout(checkCartState, 300)
})
$('a[href*="koszyk"][class*="elementor-button"]').on('click', function () {
setTimeout(checkCartState, 300);
});
$(document).on('click', '.elementor-cart__close-button', function () {
setTimeout(checkCartState, 300)
})
$(document).on('click', '.elementor-cart__close-button', function () {
setTimeout(checkCartState, 300);
});
$(document).on(
'click',
'.elementor-cart__container.elementor-lightbox.elementor-cart--shown',
function (e) {
if (e.target === this) {
setTimeout(checkCartState, 300)
}
}
)
$(document).on('click', '.elementor-cart__container.elementor-lightbox.elementor-cart--shown', function (e) {
if (e.target === this) {
setTimeout(checkCartState, 300);
}
});
const cartContainer = document.querySelector('.elementor-cart__container')
if (cartContainer) {
const observer = new MutationObserver(() => checkCartState())
observer.observe(cartContainer, {
attributes: true,
attributeFilter: ['class'],
})
}
const cartContainer = document.querySelector('.elementor-cart__container');
if (cartContainer) {
const observer = new MutationObserver(() => checkCartState());
observer.observe(cartContainer, { attributes: true, attributeFilter: ['class'] });
}
checkCartState();
});
checkCartState()
})
$(document).ready(function () {
if ($('#buy-by-phone-popup').length) {
var buyByPhonePopup = $('#buy-by-phone-popup')
$('#buy_by_phone_btn').on('click', function (e) {
$('#buy-by-phone-popup').find('input[name="buy-by-phone-name"]').val('')
$('#buy-by-phone-popup').find('input[name="buy-by-phone-phone"]').val('')
$('#buy-by-phone-popup').find('input[name="contact-time"]').val('')
$('#buy-by-phone-popup').find('input[name="product-name"]').val('')
$('#buy-by-phone-popup').find('input[name="shipping-address"]').val('')
$('#buy-by-phone-popup').find('input[name="phone-for-courier"]').val('')
$('#buy-by-phone-popup').find('input[name="email"]').val('')
$('#buy-by-phone-popup').find('input[name="comments-to-order"]').val('')
$('#buy-by-phone-popup .popup-footer').empty()
$('#buy-by-phone-popup')
.find('input[name="polityka"]')
.prop('checked', false)
buyByPhonePopup.addClass('active')
})
$('.close-popup', buyByPhonePopup).on('click', function (e) {
e.preventDefault()
buyByPhonePopup.removeClass('active')
})
$('.close-popup-alert', buyByPhonePopup).on('click', function (e) {
e.preventDefault()
$('.popup-alert', buyByPhonePopup).removeClass('active')
})
$('#buy-by-phone-form-btn').on('click', function (e) {
e.preventDefault()
$('#buy-by-phone-popup .popup-footer').empty()
var name = $('#buy-by-phone-popup')
.find('input[name="buy-by-phone-name"]')
.val()
var phone = $('#buy-by-phone-popup')
.find('input[name="buy-by-phone-phone"]')
.val()
var contact_time = $('#buy-by-phone-popup')
.find('input[name="contact-time"]')
.val()
var politics = $('#buy-by-phone-popup')
.find('input[name="polityka"]')
.prop('checked')
if (!phone) {
popupAlert('<p>Proszę wypełnić wymagane pola formularza</p>')
return
}
if (!politics) {
popupAlert('<p>Proszę wypełnić wymagane pola formularza</p>')
return
}
$(this).prop('disabled', true)
var formData = $('#buy-by-phone-form').serialize()
$.ajax({
type: 'POST',
url: '/buy-by-phone.php',
data: formData,
success: function (response) {
popupAlert(response)
$('#buy-by-phone-form-btn').prop('disabled', false)
setTimeout(function () {
buyByPhonePopup.removeClass('active')
}, 5000)
},
error: function () {
popupAlert('<p>Wystąpił błąd podczas wysyłania danych</p>')
$('#buy-by-phone-form-btn').prop('disabled', false)
},
})
})
function popupAlert(text) {
$('.popup-alert', buyByPhonePopup).addClass('active')
$('.popup-alert .popup-alert-data', buyByPhonePopup).empty()
$('.popup-alert .popup-alert-data', buyByPhonePopup).append(text)
setTimeout(function () {
$('.popup-alert', buyByPhonePopup).removeClass('active')
}, 3000)
}
}
})

View File

@@ -0,0 +1,102 @@
<div id="buy-by-phone-popup">
<div class="buy-by-phone-popup--wrapper">
<div class="popup-header">
<div class="popup-header--close">
<a href="#" title="close" class="close-popup">
<i class="fa fa-times" aria-hidden="true"></i>
</a>
</div>
</div>
<div class="popup-body">
<div class="popup-body--left">
<div class="popup-img">
<img class="product-cover" src="{$product.cover.bySize.large_default.url}" alt="{$product.cover.legend}"
title="{$product.cover.legend}" itemprop="image">
</div>
</div>
<div class="popup-body--right">
<div class="popup-body-top">
<p>ZADZWOŃ <a href="tel:172000035">172000035</a> lub uzupełnij i wyślij poniższy formularz, wówczas to my skontaktujemy się z Tobą.</p>
<form id="buy-by-phone-form" action="/buy-by-phone.php" method="post">
<input type="hidden" name="buy-by-phone-mail-from" value="masimmo">
<input type="hidden" name="buy-by-phone-product-name" value="{$product.name}">
<input type="hidden" name="buy-by-phone-product-uri" value="{$product.link}">
<div class="form-cols">
<div class="form-group lql-form-content-element">
<input type="text" class="form-control form-control-name" name="buy-by-phone-name" placeholder="Twoje imię">
</div>
<div class="form-group lql-form-content-element">
<input type="text" class="form-control form-control-phone" name="buy-by-phone-phone" required="required" placeholder="Numer telefonu *">
</div>
</div>
<span class="popup-input-alert">* pole jest wymagane</span>
<br/><br/>
<p>Potrzebuję porady odnośnie doboru produktu:</p>
<div class="form-group lql-form-content-element form-group-radio">
<label class="radio-inline">
<input type="radio" name="buy-by-phone-need-advice" value="tak"> Tak
</label>
<label class="radio-inline">
<input type="radio" name="buy-by-phone-need-advice" value="nie"> Nie
</label>
</div>
<div class="form-group lql-form-content-element">
<input type="text" class="form-control" name="contact-time" placeholder="Preferowana data/godzina kontaktu">
</div>
<div class="form-group lql-form-content-element">
<input type="text" class="form-control" name="product-to-buy" placeholder="Produkt jaki chcę kupić">
</div>
<div class="form-group lql-form-content-element">
<input type="text" class="form-control" name="shipping-address" placeholder="Adres do wysyłki">
</div>
<div class="form-group lql-form-content-element">
<input type="text" class="form-control" name="phone-for-courier"
placeholder="Numer telefonu dla kuriera">
</div>
<div class="form-group lql-form-content-element">
<input type="text" class="form-control" name="email" placeholder="Adres e-mail">
</div>
<div class="form-group lql-form-content-element">
<input type="text" class="form-control" name="comments-to-order" placeholder="Uwagi do zamówienia">
</div>
<div class="form-group lql-form-content-element form-group-polityka">
<input type="checkbox" class="form-control" name="polityka" id="polityka" required="">
<label for="polityka">
* Wyrażam zgodę na przetwarzanie przez Dr Materac sp. z o.o. mojego adresu e-mail oraz innych danych osobowych, które dobrowolnie podaję w treści wiadomości w celu udzielenia na nią odpowiedzi i kontaktu. Zapoznałem się z <a href="/content/92-regulamin-sprzedazy-telefonicznej" target="_blank">Regulaminem</a> i <a href="/content/12-polityka-prywatnosci" target="_blank">Polityką prywatności</a>
</label>
</div>
<br/>
<div class="g-recaptcha" data-sitekey="6LeJAUUsAAAAAB9l4SYYqmjAS6RwHwoyfUgTJQ5e"></div>
<br/>
<button type="submit" class="form-control-submit lql-form-bt lql-register-bt btn btn-primary"
id="buy-by-phone-form-btn">
<span class="lql-bt-txt">
Wyślij
</span>
</button>
</form>
</div>
<div class="popup-alert">
<div class="popup-alert-wrapper">
<div class="popup-alert-close">
<a href="#" title="close" class="close-popup-alert">
<i class="fa fa-times" aria-hidden="true"></i>
</a>
</div>
<div class="popup-alert-data">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{literal}
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
{/literal}

View File

@@ -65,6 +65,19 @@
</div>
{/block}
{block name='product_buy_by_phone'}
{if $product_manufacturer->id == 3}
<div class="buy_by_phone" id="buy_by_phone_btn">
<button class="btn btn-primary add-to-cart" {if !$product.add_to_cart_url} disabled {/if}>
{l s='Buy by phone' d='Shop.Theme.Actions'}
</button>
</div>
{include file='catalog/_partials/buy-by-phone-popup.tpl' product=$product}
{/if}
{/block}
{block name='product_availability'}
<span id="product-availability" class="js-product-availability">
{if $product.show_availability && $product.availability_message}