Files
web_work/public/assets/js/checkout.js
kirill.khorkov f4f57bd153 fix
2025-12-17 01:24:01 +03:00

341 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
$(document).ready(function() {
let cart = {
items: [
{ id: 1, name: 'Кресло OPPORTUNITY', price: 16999, quantity: 1 },
{ id: 2, name: 'Кресло GOLDEN', price: 19999, quantity: 1 },
{ id: 3, name: 'Светильник POLET', price: 7999, quantity: 1 }
],
delivery: 2000,
discount: 0
};
function updateTotal() {
let productsTotal = 0;
let totalCount = 0;
$('.products__item').each(function() {
const $item = $(this);
const price = parseInt($item.data('price'));
const quantity = parseInt($item.find('.products__qty-value').text());
productsTotal += price * quantity;
totalCount += quantity;
});
$('.products-total').text(productsTotal + ' ₽');
$('.summary-count').text(totalCount);
$('.total-count').text(totalCount + ' шт.');
if ($('.cart-count').length) {
$('.cart-count').text(totalCount);
}
if ($('#cartCount').length) {
$('#cartCount').text(totalCount);
}
const finalTotal = productsTotal + cart.delivery - cart.discount;
$('.final-total').text(finalTotal + ' ₽');
}
function validateEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
function validateFullName(name) {
const nameRegex = /^[a-zA-Zа-яА-ЯёЁ\s\-']+$/;
const words = name.trim().split(/\s+/);
return nameRegex.test(name) && words.length >= 2;
}
function validatePhone(phone) {
const phoneRegex = /^\+7\d{10}$/;
return phoneRegex.test(phone);
}
function showMessage(messageId, duration = 5000) {
$('.message').hide();
$(messageId).fadeIn(300);
if (duration > 0) {
setTimeout(() => {
$(messageId).fadeOut(300);
}, duration);
}
}
function showPrivacyError(show) {
if (show) {
$('#privacy-error').show();
} else {
$('#privacy-error').hide();
}
}
function showFieldError(fieldId, message) {
$(fieldId).removeClass('error-input');
$(fieldId + '-error').remove();
if (message) {
$(fieldId).addClass('error-input');
$(fieldId).after('<div class="field-error" id="' + fieldId.replace('#', '') + '-error">' + message + '</div>');
}
}
$('#fullname').on('blur', function() {
const value = $(this).val().trim();
if (value) {
if (!validateFullName(value)) {
showFieldError('#fullname', 'ФИО должно содержать только буквы и состоять минимум из 2 слов');
} else {
showFieldError('#fullname', '');
}
} else {
showFieldError('#fullname', '');
}
});
$('#email').on('blur', function() {
const value = $(this).val().trim();
if (value) {
if (!validateEmail(value)) {
showFieldError('#email', 'Введите корректный email адрес (например: example@mail.ru)');
} else {
showFieldError('#email', '');
}
} else {
showFieldError('#email', '');
}
});
$('#phone').on('blur', function() {
const value = $(this).val().trim();
if (value) {
if (!validatePhone(value)) {
showFieldError('#phone', 'Введите номер в формате +7XXXXXXXXXX (10 цифр после +7)');
} else {
showFieldError('#phone', '');
}
} else {
showFieldError('#phone', '');
}
});
$('#region').on('blur', function() {
const value = $(this).val().trim();
if (!value) {
showFieldError('#region', 'Укажите регион доставки');
} else {
showFieldError('#region', '');
}
});
$('#address').on('blur', function() {
const value = $(this).val().trim();
if (!value) {
showFieldError('#address', 'Укажите адрес доставки (улица, дом, квартира)');
} else {
showFieldError('#address', '');
}
});
$('.form__input').on('input', function() {
const fieldId = '#' + $(this).attr('id');
showFieldError(fieldId, '');
});
$('.products__qty-btn.plus').click(function() {
const $qtyValue = $(this).siblings('.products__qty-value');
let quantity = parseInt($qtyValue.text());
$qtyValue.text(quantity + 1);
updateTotal();
});
$('.products__qty-btn.minus').click(function() {
const $qtyValue = $(this).siblings('.products__qty-value');
let quantity = parseInt($qtyValue.text());
if (quantity > 1) {
$qtyValue.text(quantity - 1);
updateTotal();
}
});
$('.remove-from-cart').click(function() {
const $productItem = $(this).closest('.products__item');
$productItem.fadeOut(300, function() {
$(this).remove();
updateTotal();
if ($('.products__item').length === 0) {
$('.products__list').html('<div class="empty-cart">Корзина пуста</div>');
}
});
});
$('.promo__btn').click(function() {
const promoCode = $('.promo__input').val().toUpperCase();
if (promoCode === 'SALE10') {
cart.discount = Math.round(parseInt($('.products-total').text()) * 0.1);
$('.discount-total').text(cart.discount + ' ₽');
showMessage('#form-error', 3000);
$('#form-error').text('Промокод применен! Скидка 10%').removeClass('error').addClass('success');
} else if (promoCode === 'FREE') {
cart.delivery = 0;
$('.delivery-price').text('0 ₽');
showMessage('#form-error', 3000);
$('#form-error').text('Промокод применен! Бесплатная доставка').removeClass('error').addClass('success');
} else if (promoCode) {
showMessage('#form-error', 3000);
$('#form-error').text('Промокод недействителен').removeClass('success').addClass('error');
}
updateTotal();
});
$('input[name="delivery"]').change(function() {
if ($(this).val() === 'pickup') {
cart.delivery = 0;
$('.delivery-price').text('0 ₽');
} else {
cart.delivery = 2000;
$('.delivery-price').text('2000 ₽');
}
updateTotal();
});
function validateForm() {
let isValid = true;
let errorMessages = [];
$('.field-error').remove();
$('.form__input').removeClass('error-input');
const requiredFields = [
{
id: '#fullname',
value: $('#fullname').val().trim(),
validator: validateFullName,
required: true,
message: 'ФИО должно содержать только буквы и состоять минимум из 2 слов'
},
{
id: '#phone',
value: $('#phone').val().trim(),
validator: validatePhone,
required: true,
message: 'Введите корректный номер телефона в формате +7XXXXXXXXXX'
},
{
id: '#email',
value: $('#email').val().trim(),
validator: validateEmail,
required: true,
message: 'Введите корректный email адрес'
},
{
id: '#region',
value: $('#region').val().trim(),
validator: (val) => val.length > 0,
required: true,
message: 'Поле "Регион" обязательно для заполнения'
},
{
id: '#address',
value: $('#address').val().trim(),
validator: (val) => val.length > 0,
required: true,
message: 'Поле "Адрес" обязательно для заполнения'
}
];
requiredFields.forEach(field => {
if (field.required && (!field.value || !field.validator(field.value))) {
isValid = false;
errorMessages.push(field.message);
showFieldError(field.id, field.message);
}
});
if (!$('#privacy-checkbox').is(':checked')) {
isValid = false;
showPrivacyError(true);
errorMessages.push('Необходимо согласие на обработку персональных данных');
} else {
showPrivacyError(false);
}
if (!isValid && errorMessages.length > 0) {
showMessage('#form-error', 5000);
$('#form-error').text('Исправьте следующие ошибки: ' + errorMessages.join('; ')).removeClass('success').addClass('error');
$('html, body').animate({
scrollTop: $('.error-input').first().offset().top - 100
}, 500);
}
return isValid;
}
$('#submit-order').click(function() {
if (!validateForm()) {
return;
}
const $btn = $(this);
$btn.prop('disabled', true).text('ОБРАБОТКА...');
// Собрать данные заказа
const orderData = {
full_name: $('#fullname').val().trim(),
phone: $('#phone').val().trim(),
email: $('#email').val().trim(),
region: $('#region').val().trim(),
address: $('#address').val().trim(),
delivery_method: $('input[name="delivery"]:checked').val(),
comment: $('#comment').val().trim()
};
// Отправить на сервер
$.ajax({
url: 'api/process_order.php',
method: 'POST',
data: orderData,
dataType: 'json',
success: function(response) {
if (response.success) {
showMessage('#order-success', 5000);
$('#order-success').text('Заказ успешно оформлен! Номер заказа: ' + (response.order_id || ''));
// Очистить корзину и форму
setTimeout(() => {
window.location.href = 'catalog.php';
}, 2000);
} else {
showMessage('#form-error', 5000);
$('#form-error').text(response.message || 'Ошибка оформления заказа').removeClass('success').addClass('error');
$btn.prop('disabled', false).text('ОФОРМИТЬ ЗАКАЗ');
}
},
error: function(xhr, status, error) {
showMessage('#form-error', 5000);
$('#form-error').text('Ошибка сервера. Попробуйте позже.').removeClass('success').addClass('error');
$btn.prop('disabled', false).text('ОФОРМИТЬ ЗАКАЗ');
}
});
});
$('#phone').on('input', function() {
let phone = $(this).val().replace(/\D/g, '');
if (phone.length > 0) {
if (phone[0] !== '7' && phone[0] !== '8') {
phone = '7' + phone;
}
phone = '+7' + phone.substring(1, 11);
$(this).val(phone);
}
});
updateTotal();
});