496 lines
20 KiB
PHP
496 lines
20 KiB
PHP
<?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">
|
||
<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'] ?? 'img1/default.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(),
|
||
success: function(response) {
|
||
try {
|
||
const result = JSON.parse(response);
|
||
if (result.success) {
|
||
window.location.href = 'order_success.php?id=' + result.order_id;
|
||
} else {
|
||
showMessage('Ошибка: ' + result.message, 'error');
|
||
$('#submit-order').prop('disabled', false).text('ОФОРМИТЬ ЗАКАЗ');
|
||
}
|
||
} catch(e) {
|
||
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>
|