Files
web_work/public/checkout.php
kirill.khorkov 07289608e5 Fix
2025-12-17 20:42:54 +03:00

501 lines
20 KiB
PHP
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.
<?php
session_start();
require_once __DIR__ . '/config/database.php';
if (!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] !== true) {
header('Location: login.php?error=auth_required');
exit();
}
$user_id = $_SESSION['user_id'] ?? 0;
$db = Database::getInstance()->getConnection();
$cart_items = [];
$total_amount = 0;
$total_quantity = 0;
try {
$stmt = $db->prepare("
SELECT
c.cart_id,
c.product_id,
c.quantity,
p.name,
p.price,
p.image_url,
p.stock_quantity
FROM cart c
JOIN products p ON c.product_id = p.product_id
WHERE c.user_id = ? AND p.is_available = TRUE
ORDER BY c.created_at DESC
");
$stmt->execute([$user_id]);
$cart_items = $stmt->fetchAll();
foreach ($cart_items as $item) {
$total_amount += $item['price'] * $item['quantity'];
$total_quantity += $item['quantity'];
}
} catch (PDOException $e) {
$error = "Ошибка загрузки корзины: " . $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<base href="/cite_practica/">
<title>AETERNA - Оформление заказа</title>
<link rel="stylesheet/less" type="text/css" href="style_for_cite.less">
<script src="https://cdn.jsdelivr.net/npm/less"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<style>
.empty-cart {
text-align: center;
padding: 40px;
font-size: 18px;
color: #666;
}
.cart-error {
background: #f8d7da;
color: #721c24;
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
}
.continue-shopping {
text-align: center;
margin-top: 30px;
}
.continue-shopping .btn {
background: #453227;
color: white;
padding: 12px 30px;
border-radius: 4px;
text-decoration: none;
display: inline-block;
}
</style>
</head>
<body>
<?php include 'header_common.php'; ?>
<main class="container">
<div class="main__content">
<section class="products">
<div class="breadcrumbs">
<a href="cite_mebel.php">Главная</a> • <span class="current-page">Корзина</span>
</div>
<h2 class="products__title">Товары в корзине</h2>
<?php if (empty($cart_items)): ?>
<div class="empty-cart">
<i class="fas fa-shopping-cart" style="font-size: 48px; color: #ccc; margin-bottom: 20px;"></i>
<p>Ваша корзина пуста</p>
<div class="continue-shopping">
<a href="catalog.php" class="btn">Продолжить покупки</a>
</div>
</div>
<?php else: ?>
<div class="products__list" id="cartItems">
<?php foreach ($cart_items as $item): ?>
<div class="products__item" data-product-id="<?= $item['product_id'] ?>" data-price="<?= $item['price'] ?>">
<div class="products__image">
<img src="<?= htmlspecialchars($item['image_url'] ?? 'img/1.jpg') ?>"
alt="<?= htmlspecialchars($item['name']) ?>"
class="product-img">
</div>
<div class="products__details">
<div class="products__name"><?= htmlspecialchars($item['name']) ?></div>
<div class="products__price"><?= number_format($item['price'], 0, '', ' ') ?> ₽</div>
<div class="products__controls">
<div class="products__quantity">
<button class="products__qty-btn minus" data-id="<?= $item['product_id'] ?>">-</button>
<span class="products__qty-value"><?= $item['quantity'] ?></span>
<button class="products__qty-btn plus" data-id="<?= $item['product_id'] ?>">+</button>
</div>
<button class="products__cart-icon remove-from-cart" data-id="<?= $item['product_id'] ?>">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</section>
<?php if (!empty($cart_items)): ?>
<section class="order">
<form method="POST" action="api/process_order.php" id="orderForm">
<div class="order__header">
<h2 class="order__title">Оформление заказа</h2>
<div class="order__total">Товары, <span class="total-count"><?= $total_quantity ?></span></div>
</div>
<div class="order__section">
<h3 class="order__section-title">СПОСОБ ДОСТАВКИ</h3>
<div class="form__radio-group">
<label class="form__radio-label">
<input type="radio" name="delivery" class="form__radio-input" value="courier" checked>
<span class="form__custom-radio"></span>
Курьерская доставка
</label>
<label class="form__radio-label">
<input type="radio" name="delivery" class="form__radio-input" value="pickup">
<span class="form__custom-radio"></span>
Самовывоз
</label>
</div>
<div class="form__group">
<label for="fullname" class="form__label">КОНТАКТЫ</label>
<input type="text" id="fullname" name="full_name" class="form__input"
placeholder="ФИО..."
value="<?= htmlspecialchars($_SESSION['full_name'] ?? '') ?>"
required>
</div>
<div class="form__group form__row">
<div style="position: relative; width: 48%;">
<input type="tel" id="phone" name="phone" class="form__input form__input--half"
placeholder="Телефон..."
value="<?= htmlspecialchars($_SESSION['user_phone'] ?? '') ?>"
required>
</div>
<div style="position: relative; width: 48%;">
<input type="email" id="email" name="email" class="form__input form__input--half"
placeholder="E-mail..."
value="<?= htmlspecialchars($_SESSION['user_email'] ?? '') ?>"
required>
</div>
</div>
</div>
<div class="order__section">
<h3 class="order__section-title">СПОСОБ ОПЛАТЫ</h3>
<div class="form__radio-group">
<label class="form__radio-label">
<input type="radio" name="payment" class="form__radio-input" value="card" checked>
<span class="form__custom-radio"></span>
Банковская карта
</label>
<label class="form__radio-label">
<input type="radio" name="payment" class="form__radio-input" value="cash">
<span class="form__custom-radio"></span>
Наличные
</label>
</div>
<div class="form__group form__row">
<div style="position: relative; width: 48%;">
<input type="text" id="region" name="region" class="form__input form__input--half"
placeholder="Регион..." required>
</div>
<div style="position: relative; width: 48%;">
<input type="text" id="index" name="postal_code" class="form__input form__input--half"
placeholder="Индекс (необязательно)...">
</div>
</div>
<div class="form__group">
<input type="text" id="address" name="address" class="form__input"
placeholder="Улица, дом, квартира..." required>
</div>
</div>
<div class="divider"></div>
<div class="promo">
<input type="text" id="promo_code" name="promo_code" class="promo__input" placeholder="Промокод">
<button type="button" class="promo__btn" id="applyPromo">ПРИМЕНИТЬ</button>
</div>
<div class="summary">
<div class="summary__item">
<span>Товары, <span class="summary-count"><?= $total_quantity ?></span> шт.</span>
<span class="products-total"><?= number_format($total_amount, 0, '', ' ') ?> ₽</span>
</div>
<div class="summary__item">
<span>Скидка</span>
<span class="discount-total">0 ₽</span>
<input type="hidden" name="discount" value="0">
</div>
<div class="summary__item">
<span>Доставка</span>
<span class="delivery-price">2000 ₽</span>
<input type="hidden" name="delivery_price" value="2000">
</div>
<div class="summary__item total">
<span>ИТОГО:</span>
<span class="final-total"><?= number_format($total_amount + 2000, 0, '', ' ') ?> ₽</span>
</div>
</div>
<button type="submit" class="order-btn" id="submit-order">ОФОРМИТЬ ЗАКАЗ</button>
<label class="privacy">
<input type="checkbox" id="privacy-checkbox" required>
Даю согласие на обработку персональных данных
</label>
<div class="privacy-error" id="privacy-error" style="display: none; color: #dc3545; font-size: 14px; margin-top: 10px;">
Необходимо согласие на обработку персональных данных
</div>
<div class="services">
<h3 class="services__title">УСЛУГИ</h3>
<div class="services__item">
<span>Доставка</span>
<span>2000 ₽</span>
</div>
<div class="services__item">
<span>Сборка</span>
<span>1000 ₽</span>
</div>
</div>
</form>
</section>
<?php endif; ?>
</div>
</main>
<div class="page-messages">
<div class="message error" id="form-error" style="display: none;"></div>
<div class="message success" id="order-success" style="display: none;"></div>
</div>
<?php
if (file_exists('footer.php')) {
include 'footer.php';
} else {
?>
<footer class="footer" id="footer">
<div class="container footer__content">
<div class="footer__col footer--logo">
<div class="logo">AETERNA</div>
</div>
<div class="footer__col">
<h5>ПОКУПАТЕЛЮ</h5>
<ul>
<li><a href="catalog.php">Каталог</a></li>
<li><a href="services.php">Услуги</a></li>
</ul>
</div>
<div class="footer__col">
<h5>ПОМОЩЬ</h5>
<ul>
<li><a href="delivery.php">Доставка и оплата</a></li>
<li><a href="warranty.php">Гарантия и возврат</a></li>
<li><a href="cite_mebel.php#faq">Ответы на вопросы</a></li>
<li><a href="#footer">Контакты</a></li>
</ul>
</div>
<div class="footer__col">
<h5>КОНТАКТЫ</h5>
<p>aeterna@mail.ru</p>
<p>+7(912)999-12-23</p>
<div class="social-icons">
<span class="icon"><i class="fab fa-telegram"></i></span>
<span class="icon"><i class="fab fa-instagram"></i></span>
<span class="icon"><i class="fab fa-vk"></i></span>
</div>
</div>
<div class="footer__col">
<h5>ПРИНИМАЕМ К ОПЛАТЕ</h5>
<div class="payment-icons">
<span class="pay-icon"><i class="fab fa-cc-visa"></i></span>
<span class="pay-icon"><i class="fab fa-cc-mastercard"></i></span>
</div>
</div>
</div>
<div class="copyright">
<p>© 2025 AETERNA. Все права защищены.</p>
</div>
</footer>
<?php
}
?>
<script>
$(document).ready(function() {
$('.products__qty-btn').on('click', function(e) {
e.preventDefault();
e.stopPropagation();
const $btn = $(this);
const productId = $btn.data('id');
const isPlus = $btn.hasClass('plus');
const $qtyValue = $btn.siblings('.products__qty-value');
let quantity = parseInt($qtyValue.text());
if (isPlus) {
quantity++;
} else if (quantity > 1) {
quantity--;
} else {
return;
}
$qtyValue.text(quantity);
$.ajax({
url: 'api/cart.php',
method: 'POST',
data: {
action: 'update',
product_id: productId,
quantity: quantity
},
dataType: 'json',
success: function(result) {
if (result.success) {
updateTotals();
} else {
$qtyValue.text(isPlus ? quantity - 1 : quantity + 1);
alert('Ошибка: ' + result.message);
}
},
error: function(xhr, status, error) {
console.error('AJAX ошибка:', status, error);
$qtyValue.text(isPlus ? quantity - 1 : quantity + 1);
alert('Ошибка сервера');
}
});
});
$('.remove-from-cart').on('click', function(e) {
e.preventDefault();
const productId = $(this).data('id');
const $item = $(this).closest('.products__item');
if (!confirm('Удалить товар из корзины?')) {
return;
}
$.ajax({
url: 'api/cart.php',
method: 'POST',
data: {
action: 'remove',
product_id: productId
},
dataType: 'json',
success: function(result) {
if (result.success) {
$item.fadeOut(300, function() {
$(this).remove();
updateTotals();
if ($('#cartItems .products__item').length === 0) {
$('#cartItems').html('<div class="empty-cart"><i class="fas fa-shopping-cart" style="font-size: 48px; color: #ccc; margin-bottom: 20px;"></i><p>Ваша корзина пуста</p></div>');
$('.order').hide();
}
});
} else {
alert('Ошибка: ' + result.message);
}
},
error: function(xhr, status, error) {
console.error('AJAX ошибка:', status, error);
alert('Ошибка сервера');
}
});
});
function updateTotals() {
let productsTotal = 0;
let totalCount = 0;
$('.products__item').each(function() {
const price = parseInt($(this).data('price'));
const quantity = parseInt($(this).find('.products__qty-value').text());
productsTotal += price * quantity;
totalCount += quantity;
});
const delivery = parseFloat($('input[name="delivery_price"]').val());
const discount = parseFloat($('input[name="discount"]').val());
const finalTotal = productsTotal + delivery - discount;
$('.products-total').text(productsTotal.toLocaleString('ru-RU') + ' ₽');
$('.summary-count').text(totalCount);
$('.total-count').text(totalCount + ' шт.');
$('.final-total').text(finalTotal.toLocaleString('ru-RU') + ' ₽');
}
$('#applyPromo').click(function() {
const promoCode = $('#promo_code').val().toUpperCase();
if (promoCode === 'SALE10') {
const productsTotal = parseFloat($('.products-total').text().replace(/[^0-9]/g, ''));
const discount = Math.round(productsTotal * 0.1);
$('input[name="discount"]').val(discount);
$('.discount-total').text(discount.toLocaleString('ru-RU') + ' ₽');
showMessage('Промокод применен! Скидка 10%', 'success');
updateTotals();
} else if (promoCode === 'FREE') {
$('input[name="delivery_price"]').val(0);
$('.delivery-price').text('0 ₽');
showMessage('Промокод применен! Бесплатная доставка', 'success');
updateTotals();
} else if (promoCode) {
showMessage('Промокод недействителен', 'error');
}
});
$('#orderForm').submit(function(e) {
e.preventDefault();
if (!$('#privacy-checkbox').is(':checked')) {
$('#privacy-error').show();
return;
}
$('#privacy-error').hide();
$('#submit-order').prop('disabled', true).text('ОБРАБОТКА...');
$.ajax({
url: 'api/process_order.php',
method: 'POST',
data: $(this).serialize(),
dataType: 'json',
success: function(result) {
if (result.success) {
showMessage('Заказ успешно оформлен!', 'success');
setTimeout(function() {
window.location.href = 'cite_mebel.php';
}, 1500);
} else {
showMessage('Ошибка: ' + result.message, 'error');
$('#submit-order').prop('disabled', false).text('ОФОРМИТЬ ЗАКАЗ');
}
},
error: function(xhr, status, error) {
console.error('AJAX error:', status, error);
console.log('Response:', xhr.responseText);
showMessage('Ошибка сервера при обработке заказа', 'error');
$('#submit-order').prop('disabled', false).text('ОФОРМИТЬ ЗАКАЗ');
}
});
});
function showMessage(message, type) {
const $msg = type === 'success' ? $('#order-success') : $('#form-error');
$msg.text(message).fadeIn(300);
setTimeout(() => $msg.fadeOut(300), 5000);
}
});
</script>
</body>
</html>