File: /var/www/nebonutyye/js/script.js
const frontData = {
certificates: false,
certificatesSpeed: false,
pilot: false,
modifiers: [],
name: '',
number: '',
phone: '',
email: '',
place: 1,
address: '',
addressSpeed: '',
text: '',
summ: 0,
summCommission: 0,
updateCertificates() {
this.certificates = !this.certificates;
},
updateCertificatesSpeed() {
this.certificatesSpeed = !this.certificatesSpeed;
},
updatePilot() {
this.pilot = !this.pilot;
},
updateName(text) {
this.name = text;
},
updateNumber(text) {
this.number = text;
},
updatePhone(text) {
this.phone = text;
},
updateEmail(text) {
this.email = text;
},
updatePlace(number) {
this.place = number;
},
updateAddress(text) {
this.address = text;
},
updateAddressSpeed(text) {
this.addressSpeed = text;
},
updateModifiers(id, add) {
if (add) {
this.modifiers.push(id);
} else {
this.modifiers = this.modifiers.filter((item) => item !== id);
}
},
recalculateSumm() {
const buttonP = document.querySelector('[data-tour-price]');
const headerP = document.querySelector('[data-tour-header-price]');
this.summ = this.config?.tour * this.place;
if (this.pilot && this.place !== 3) {
this.summ += this.config?.pilot;
}
if (this.certificates) {
this.summ += this.config?.delivery;
}
if (this.modifiers && this.modifiers?.length && this.config?.modifiers && this.config?.modifiers?.length) {
this.config.modifiers.forEach((item) => {
if (this.modifiers.includes(item.number)) {
this.summ += item.price;
}
});
}
if (this.config?.commission) {
this.summCommission = ((this.summ / (100 - this.config?.commission)) * this.config?.commission);
this.summ += this.summCommission;
}
if (buttonP) {
buttonP.innerHTML = `${generatePrice(this.summ.toFixed(2))} ₽ | Оформить`;
}
if (headerP) {
headerP.innerHTML = `${generatePrice(this.summ.toFixed(2))} ₽`;
}
this.rerenderTotal();
},
rerenderTotal() {
const total = document.querySelector('[data-tour-total]');
if (!total) {
return;
}
const list = total.querySelector('.tourFormTotal__list');
if (!list) {
return;
}
list.innerHTML = `
<div class="tourFormTotal__listItem">
<p>${this.config?.type} ${this.config?.allPlaces ? this.config?.allPlacesText : this.place + ' ' + declOfNum(this.place, [' место', ' места', ' мест'])}<br /> на путешествие ${this.config?.title}</p>
<p>1 шт.</p>
<p>${generatePrice(this.config?.tour * this.place)} ₽</p>
</div>
`;
if (this.modifiers && this.modifiers?.length && this.config?.modifiers && this.config?.modifiers?.length) {
this.config.modifiers.forEach((item) => {
if (this.modifiers.includes(item.number)) {
list.innerHTML += `
<div class="tourFormTotal__listItem">
<p>ViewPoint #${item.number} ${item.name}</p>
<p>1 шт.</p>
<p>${generatePrice(item.price)} ₽</p>
</div>
`;
}
});
}
if (this.pilot && this.place !== 3) {
list.innerHTML += `
<div class="tourFormTotal__listItem">
<p>Лететь на Месте пилота</p>
<p>1 шт.</p>
<p>${generatePrice(this.config?.pilot)} ₽</p>
</div>
`;
}
if (this.certificates) {
list.innerHTML += `
<div class="tourFormTotal__listItem">
<p>Доставка сертификата</p>
<p>1 шт.</p>
<p>${generatePrice(this.config?.delivery)} ₽</p>
</div>
`;
}
if (this.config?.commission) {
list.innerHTML += `
<div class="tourFormTotal__listItem">
<p>Комиссия платежной системы Platron ${this.config?.commission}%</p>
<p>—</p>
<p>${generatePrice(this.summCommission.toFixed(2))} ₽</p>
</div>
`;
}
}
};
window.addEventListener('load', async () => {
const config = await fetchConfig();
if (config) {
frontData.config = {
...config
}
}
frontData.recalculateSumm();
renderConfig(frontData.config);
document.body.removeAttribute('data-loader');
const name = document.getElementById('name');
const number = document.getElementById('number');
const phone = document.getElementById('phone');
const email = document.getElementById('email');
const address = document.getElementById('address');
const addressSpeed = document.getElementById('address-speed');
const certificate = document.querySelector('.tourCertificate__checkbox');
const certificateSpeed = document.querySelector('.tourCertificateSpeed__checkbox');
const certificateForm = document.querySelector('.tourCertificateForm');
const certificateFormSpeed = document.querySelector('.tourCertificateFormSpeed');
const pilotCheckbox = document.querySelector('.tourPilot__checkbox');
const elCertificate = document.querySelector('[data-tour-delivery]');
const elCertificateSpeed = document.querySelector('[data-tour-delivery-speed]');
const elCertificateFormSpeed = document.querySelector('[data-tour-delivery-form-speed]');
const elCertificateForm = document.querySelector('[data-tour-delivery-form]');
const modifiers = document.querySelector('[data-tour-modifiers]');
const places = document.querySelectorAll('.tourPlace__listItem');
const modifiersItems = document.querySelectorAll('.tourModifiers__listItemContentButton');
const textSpoiler = document.querySelector('.tourPoster__text');
const button = document.querySelector('.tourForm__button');
if (certificate) {
certificate.addEventListener('click', () => {
frontData.updateCertificates();
if (certificate.classList.contains('active')) {
certificate.classList.remove('active');
} else {
certificate.classList.add('active');
}
if (frontData.certificates) {
elCertificateSpeed.classList.add('hide');
elCertificateFormSpeed.classList.add('hide');
certificateForm.classList.add('active');
} else {
elCertificateSpeed.classList.remove('hide');
elCertificateFormSpeed.classList.remove('hide');
certificateForm.classList.remove('active');
}
frontData.recalculateSumm();
});
}
if (certificateSpeed) {
certificateSpeed.addEventListener('click', () => {
frontData.updateCertificatesSpeed();
if (certificateSpeed.classList.contains('active')) {
certificateSpeed.classList.remove('active');
} else {
certificateSpeed.classList.add('active');
}
if (frontData.certificatesSpeed) {
elCertificate.classList.add('hide');
elCertificateForm.classList.add('hide');
certificateFormSpeed.classList.add('active');
} else {
certificateFormSpeed.classList.remove('active');
elCertificate.classList.remove('hide');
elCertificateForm.classList.remove('hide');
}
frontData.recalculateSumm();
});
}
if (pilotCheckbox) {
pilotCheckbox.addEventListener('click', () => {
frontData.updatePilot();
if (pilotCheckbox.classList.contains('active')) {
pilotCheckbox.classList.remove('active');
} else {
pilotCheckbox.classList.add('active');
}
frontData.recalculateSumm();
});
}
if (textSpoiler) {
textSpoiler.addEventListener('click', () => {
if (textSpoiler.classList.contains('active')) {
textSpoiler.classList.remove('active');
} else {
textSpoiler.classList.add('active');
}
});
}
if (number) {
const maskOptions = {
mask: '0000-000',
};
IMask(number, maskOptions);
number.addEventListener('input', (e) => {
frontData.updateNumber(e.target.value);
})
}
if (name) {
name.addEventListener('input', (e) => {
frontData.updateName(e.target.value);
})
}
if (phone) {
const maskOptions = {
mask: '+{7}(000) 000-00-00'
};
IMask(phone, maskOptions);
phone.addEventListener('input', (e) => {
frontData.updatePhone(e.target.value);
})
}
if (email) {
email.addEventListener('input', (e) => {
frontData.updateEmail(e.target.value);
})
}
if (address) {
address.addEventListener('input', (e) => {
frontData.updateAddress(e.target.value);
})
}
if (addressSpeed) {
addressSpeed.addEventListener('input', (e) => {
frontData.updateAddressSpeed(e.target.value);
})
}
if (places && places?.length) {
places.forEach((item, index) => {
item.addEventListener('click', () => {
frontData.updatePlace(Number(item.dataset.value));
places.forEach((item, index) => {
if (index + 1 <= frontData.place) {
item.classList.add('active');
} else {
item.classList.remove('active');
}
});
const placeAllText = document.querySelector('.tourPlace__all');
const pilot = document.querySelector('[data-tour-pilot]');
if (placeAllText && Number(item.dataset.value) === 3) {
placeAllText.classList.add('active');
} else {
placeAllText.classList.remove('active');
}
if (pilot) {
if (frontData.place === 3) {
pilot.classList.add('disabled');
frontData.pilot = false;
pilotCheckbox.classList.remove('active');
} else {
pilot.classList.remove('disabled');
}
}
if (modifiers) {
if (frontData.place === 3) {
modifiers.classList.remove('disabled');
} else {
modifiers.classList.add('disabled');
}
}
frontData.recalculateSumm();
});
if (index + 1 <= frontData.place) {
item.classList.add('active');
} else {
item.classList.remove('active');
}
});
} else {
if (frontData.config.allPlaces && modifiers) {
modifiers.classList.remove('disabled');
}
}
if (modifiersItems && modifiersItems?.length) {
modifiersItems.forEach((item) => {
item.addEventListener('click', () => {
if (item.classList.contains('active')) {
frontData.updateModifiers(Number(item.dataset.number), false)
item.classList.remove('active');
} else {
item.classList.add('active');
frontData.updateModifiers(Number(item.dataset.number), true)
}
frontData.recalculateSumm();
});
});
}
if (button) {
button.addEventListener('click', () => {
frontData.recalculateSumm();
console.log(frontData)
const error = [];
const name = document.getElementById('name');
const number = document.getElementById('number');
const phone = document.getElementById('phone');
const email = document.getElementById('email');
if (frontData.config.numberOrder) {
if (!frontData.number) {
error.push(true);
number.classList.add('error');
} else {
number.classList.remove('error');
}
}
if (!frontData.name) {
error.push(true);
name.classList.add('error');
} else {
name.classList.remove('error');
}
if (!frontData.phone) {
error.push(true);
phone.classList.add('error')
} else {
phone.classList.remove('error');
}
if (!frontData.email) {
error.push(true);
email.classList.add('error')
} else {
email.classList.remove('error');
}
const formData = new FormData();
formData.append('name', frontData.name);
formData.append('email', frontData.email);
formData.append('phone', frontData.phone);
formData.append('price', frontData.summ.toFixed(2));
formData.append('wishes', frontData.text);
formData.append('positon', frontData.config?.title);
if (frontData.config.numberOrder) {
formData.append('number', frontData.number);
}
if (frontData.certificatesSpeed) {
formData.append('address', frontData.addressSpeed);
}
if (frontData.certificates) {
formData.append('address', frontData.address);
}
if (!error.includes(true)) {
fetch('https://overheadcitytour.ru/api/platron.php', {
method: 'POST',
body: formData,
}).then((res) => {
return res.json();
}).then((resultData) => {
console.log(resultData);
let form = '<form action="https:/' + '/www.platron.ru/payment.php" method="post">';
for (let key in resultData) {
if (resultData.hasOwnProperty(key)) {
form += '<input type="hidden" name="' + key + '" value="' + resultData[key] + '" />';
}
}
form += '</form>';
const div = document.createElement('div');
div.innerHTML = form.trim();
const formElement = div.firstChild;
document.body.appendChild(div);
formElement.submit();
});
}
});
}
});
const renderConfig = (config) => {
const titles = document.querySelectorAll('[data-tour-title]');
const type = document.querySelector('[data-tour-type]');
const image = document.querySelector('[data-tour-image]');
const desc = document.querySelector('[data-tour-desc]');
const text = document.querySelector('[data-tour-text]');
const list = document.querySelector('[data-tour-list]');
const allPlace = document.querySelector('[data-tour-allPlace]');
const place = document.querySelector('[data-tour-place]');
const places = document.querySelectorAll('[data-tour-places]');
const pilot = document.querySelector('[data-tour-pilot]');
const delivery = document.querySelector('[data-tour-delivery]');
const deliveryForm = document.querySelector('[data-tour-delivery-form]');
const modifiers = document.querySelector('[data-tour-modifiers]');
const modifiersList = document.querySelector('[data-tour-modifiers-list]');
const number = document.getElementById('number');
console.log(config);
if (titles.length) {
titles.forEach((item) => {
item.innerHTML = config?.title;
});
}
if (type) {
type.innerHTML = config?.type;
}
if (config?.typeText) {
tippy('#why-tooltip', {
content: config?.typeText,
theme: 'nebo',
placement: 'bottom',
});
}
if (image && config?.image) {
image.src = config.image.includes('http') ? config.image : `./images/${config.image}`;
} else {
image.remove();
}
if (!config?.desc || !config?.text) {
desc.remove();
text.remove();
} else {
desc.innerHTML = config.desc;
text.innerHTML = config.text;
}
if (list && config?.list?.length) {
list.innerHTML = '';
config.list.forEach((item) => {
list.innerHTML += `
<div class="tourPoster__listItem">
<p>${item.name}</p><span>${item.value}</span>
</div>
`;
});
} else {
list.remove();
}
if (config?.allPlaces) {
if (place) {
place.remove();
}
if (pilot) {
pilot.remove();
}
if (allPlace) {
const title = allPlace.querySelector('.tourAllPlace__headerTitle');
const subtitle = allPlace.querySelector('.tourAllPlace__headerSubTitle');
if (title && config?.allPlacesText) {
title.innerHTML = config.allPlacesText;
}
if (subtitle && config?.allPlacesDesc) {
subtitle.innerHTML = config.allPlacesDesc;
}
}
} else {
if (allPlace) {
allPlace.remove()
}
}
if (places.length) {
places.forEach((item, index) => {
const price = item.querySelector('.tourPlace__listItemPrice');
if (price) {
if (index + 1 === 1) {
price.innerHTML = `${generateIntegerPrice(config?.tour)} ₽`;
} else {
price.innerHTML = `+ ${generateIntegerPrice(config?.tour * (index))} ₽`;
}
}
});
}
if (pilot && config?.pilot) {
const price = pilot.querySelector('.tourPilot__price');
price.innerHTML = `+ ${config?.pilot} ₽`;
} else {
pilot.remove();
}
if (delivery && config?.delivery) {
const price = delivery.querySelector('.tourCertificate__price');
price.innerHTML = `+ ${config.delivery} ₽`;
} else {
delivery.remove();
if (deliveryForm) {
deliveryForm.remove();
}
}
if (!config.numberOrder && number) {
number.remove();
}
if (config.modifiers && config.modifiers?.length && modifiersList) {
modifiersList.innerHTML = '';
config.modifiers.forEach((item) => {
modifiersList.innerHTML += `
<div class="tourModifiers__listItem">
<div class="tourModifiers__listItemInformation">
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_b_1079_865)">
<circle cx="20" cy="20" r="20" fill="white" fill-opacity="0.1"/>
<circle cx="20" cy="20" r="19" stroke="white" stroke-opacity="0.2" stroke-width="2"/>
</g>
<path opacity="0.5" d="M21.1816 27H18.8086V16.4336H21.1816V27ZM18.6621 13.6895C18.6621 13.3249 18.776 13.0221 19.0039 12.7812C19.2383 12.5404 19.5703 12.4199 20 12.4199C20.4297 12.4199 20.7617 12.5404 20.9961 12.7812C21.2305 13.0221 21.3477 13.3249 21.3477 13.6895C21.3477 14.0475 21.2305 14.347 20.9961 14.5879C20.7617 14.8223 20.4297 14.9395 20 14.9395C19.5703 14.9395 19.2383 14.8223 19.0039 14.5879C18.776 14.347 18.6621 14.0475 18.6621 13.6895Z" fill="white"/>
<defs>
<filter id="filter0_b_1079_865" x="-10" y="-10" width="60" height="60" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feGaussianBlur in="BackgroundImageFix" stdDeviation="5"/>
<feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur_1079_865"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur_1079_865" result="shape"/>
</filter>
</defs>
</svg>
</div>
<img src="${item.img.includes('http') ? item.img : './images/' + item.img}" alt="">
<div class="tourModifiers__listItemContent">
<div class="tourModifiers__listItemContentItem">
<div class="tourModifiers__listItemContentTitle"><span>#${item.number}</span> ${item.name}</div>
<div class="tourModifiers__listItemContentPrice">+ ${generateIntegerPrice(item.price)} ₽</div>
</div>
<div class="tourModifiers__listItemContentItem">
<div class="tourModifiers__listItemContentButton" data-number="${item.number}">
<span>+ Добавить</span>
<p>
<svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.25 19.25L16.25 24.25L26.25 14.25" stroke="white" stroke-width="3"/>
</svg>
</p>
</div>
</div>
</div>
</div>
`;
});
} else {
if (modifiers) {
modifiers.remove();
}
}
};
window.addEventListener('scroll', function () {
const back = document.querySelector('.tourBack svg');
if (window.scrollY > 0) {
back.style.display = 'none';
back.style.pointerEvents = 'none';
} else {
back.style.display = 'block';
back.style.pointerEvents = 'all';
}
});
const declOfNum = (number, titles) => {
const cases = [2, 0, 1, 1, 1, 2];
return titles[
number % 100 > 4 && number % 100 < 20 ? 2 : cases[number % 10 < 5 ? number % 10 : 5]
];
};
const generateIntegerPrice = (str) => {
let [_, num, suffix] = str.toString().match(/^(.*?)((?:[,.]\d+)?|)$/);
return `${num.replace(/\B(?=(?:\d{3})*$)/g, '.')}`;
}
const generatePrice = (str) => {
let [_, num, suffix] = str.toString().match(/^(.*?)((?:[,.]\d+)?|)$/);
return `${num.replace(/\B(?=(?:\d{3})*$)/g, '.')}<span style="opacity: 0.6;">${suffix.replace('.', ',')}</span>`;
}
const fetchConfig = async () => {
let configName = window.location.pathname.substring(1).length ? window.location.pathname.substring(1) + '.json' : 'config.json';
return await fetch('./' + configName).then((response) => response.json()).catch(() => {
return fetch('./polet-15-helicopter-sertificate-12.json').then((response) => response.json()).catch((error) => {
throw Error('Конфиг для данной страницы не найден!' + error)
})
});
};