<?php
require_once __DIR__ . '/../config/bootstrap.php';
require_once __DIR__ . '/../config/auth.php';
require_once __DIR__ . '/../config/functions.php';
require_login();
if (!isset($_SESSION['cart'])) {
$_SESSION['cart'] = [];
}
error_log('Cart contents: ' . print_r($_SESSION['cart'], true));
include __DIR__ . '/../includes/header.php';
?>
<div class="container py-5">
<h2 class="mb-4 fw-bold text-center animate__animated animate__fadeInDown">Ваша корзина</h2>
<?php if (empty($_SESSION['cart'])): ?>
<div class="alert alert-info text-center animate__animated animate__fadeInUp">
В корзине пока нет товаров.
<a href="<?= BASE_URL ?>" class="alert-link">Перейти к выбору фото и форматов</a>
</div>
<?php else: ?>
<div class="table-responsive animate__animated animate__fadeInUp">
<table class="table table-hover align-middle">
<thead class="table-light">
<tr>
<th style="width: 100px;">Фото</th>
<th>Формат</th>
<th>Цена за шт.</th>
<th style="width: 150px;">Количество</th>
<th>Итого</th>
<th style="width: 120px;">Действия</th>
</tr>
</thead>
<tbody id="cart-items">
<?php
$total_price = 0;
foreach ($_SESSION['cart'] as $id => $item):
$item_total = ($item['price'] ?? 0) * ($item['quantity'] ?? 1);
$total_price += $item_total;
$photo_display = '';
$photo_title = 'Фото не указано';
if (!empty($item['filename'])) {
$photo_path = UPLOAD_DIR . 'photos/' . $item['filename'];
$photo_url = BASE_URL . 'uploads/photos/' . $item['filename'];
if (file_exists($photo_path)) {
$photo_display = '<img src="' . e($photo_url) . '"
alt="Фото"
class="rounded"
style="width: 80px; height: 80px; object-fit: cover;">';
$photo_title = 'Загруженное фото';
} else {
try {
if (!empty($item['photo_id'])) {
$stmt = $pdo->prepare("SELECT filename FROM photos WHERE id = ?");
$stmt->execute([$item['photo_id']]);
$db_photo = $stmt->fetch();
if ($db_photo && !empty($db_photo['filename'])) {
$photo_path = UPLOAD_DIR . 'photos/' . $db_photo['filename'];
$photo_url = BASE_URL . 'uploads/photos/' . $db_photo['filename'];
if (file_exists($photo_path)) {
$photo_display = '<img src="' . e($photo_url) . '"
alt="Фото"
class="rounded"
style="width: 80px; height: 80px; object-fit: cover;">';
$photo_title = 'Фото из базы';
}
}
}
} catch (Exception $e) {
error_log('Error getting photo from DB: ' . $e->getMessage());
}
}
}
if (empty($photo_display)) {
$photo_display = '<div class="bg-light rounded d-flex align-items-center justify-content-center"
style="width: 80px; height: 80px;"
title="' . $photo_title . '">
<i class="bi bi-image text-muted fs-4"></i>
</div>';
}
?>
<tr data-id="<?= e($id) ?>">
<td>
<?= $photo_display ?>
<?php if (!empty($item['photo_id'])): ?>
<small class="d-block text-muted mt-1">ID: <?= e($item['photo_id']) ?></small>
<?php endif; ?>
</td>
<td>
<div class="fw-bold"><?= e($item['format_name'] ?? 'Не указан') ?></div>
<?php if (!empty($item['format_id'])): ?>
<small class="text-muted">Формат ID: <?= e($item['format_id']) ?></small>
<?php endif; ?>
</td>
<td class="fw-bold"><?= number_format($item['price'] ?? 0, 2) ?> ₽</td>
<td>
<div class="input-group input-group-sm" style="width: 120px;">
<input type="number"
min="1"
class="form-control cart-quantity"
value="<?= e($item['quantity'] ?? 1) ?>"
data-id="<?= e($id) ?>"
style="text-align: center;">
</div>
</td>
<td class="cart-total-item fw-bold fs-5 text-primary">
<?= number_format($item_total, 2) ?> ₽
</td>
<td>
<button class="btn btn-sm btn-outline-danger btn-remove-cart"
data-id="<?= e($id) ?>"
title="Удалить из корзины">
<i class="bi bi-trash"></i>
</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot>
<tr class="table-active">
<td colspan="4" class="text-end fw-bold fs-5">Общая сумма:</td>
<td colspan="2" class="fw-bold fs-4 text-success" id="cart-total">
<?= number_format($total_price, 2) ?> ₽
</td>
</tr>
<?php if (!empty($_SESSION['discount'])): ?>
<tr class="table-warning">
<td colspan="4" class="text-end fw-bold">Скидка:</td>
<td colspan="2" class="fw-bold text-danger">
-<?= number_format($_SESSION['discount']['amount'] ?? 0, 2) ?> ₽
</td>
</tr>
<tr class="table-success">
<td colspan="4" class="text-end fw-bold">Итого со скидкой:</td>
<td colspan="2" class="fw-bold fs-4">
<?= number_format($total_price - ($_SESSION['discount']['amount'] ?? 0), 2) ?> ₽
</td>
</tr>
<?php endif; ?>
</tfoot>
</table>
</div>
<div class="row mt-4">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5 class="mb-0"><i class="bi bi-percent"></i> Применить скидку</h5>
</div>
<div class="card-body">
<form id="discount-form" class="input-group">
<input type="text"
class="form-control"
placeholder="Введите промокод"
name="discount_code">
<button class="btn btn-warning" type="submit">
<i class="bi bi-tag"></i> Применить
</button>
</form>
<?php if (!empty($_SESSION['discount'])): ?>
<div class="alert alert-success mt-3">
<i class="bi bi-check-circle"></i>
Активна скидка: <strong><?= e($_SESSION['discount']['code']) ?></strong>
(<?= e($_SESSION['discount']['percent'] ?? 0) ?>%)
<a href="#" class="float-end text-danger remove-discount">
<i class="bi bi-x-circle"></i> Удалить
</a>
</div>
<?php endif; ?>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5 class="mb-0"><i class="bi bi-info-circle"></i> Информация</h5>
</div>
<div class="card-body">
<ul class="list-unstyled mb-0">
<li><i class="bi bi-check text-success"></i> Бесплатная доставка от 1000 ₽</li>
<li><i class="bi bi-check text-success"></i> Срок изготовления: 1-3 дня</li>
<li><i class="bi bi-check text-success"></i> Гарантия качества</li>
<li><i class="bi bi-check text-success"></i> Поддержка 24/7</li>
</ul>
</div>
</div>
</div>
</div>
<!-- Кнопки действий -->
<div class="d-flex justify-content-between align-items-center mt-4 animate__animated animate__fadeInUp animate__delay-1s">
<div>
<a href="<?= BASE_URL ?>" class="btn btn-outline-primary">
<i class="bi bi-arrow-left"></i> Продолжить покупки
</a>
<a href="<?= BASE_URL ?>profile.php" class="btn btn-outline-secondary ms-2">
<i class="bi bi-images"></i> Мои фото
</a>
</div>
<div>
<button class="btn btn-outline-danger me-2" id="btn-clear-cart">
<i class="bi bi-trash"></i> Очистить корзину
</button>
<a href="<?= BASE_URL ?>checkout.php" class="btn btn-success btn-lg">
<i class="bi bi-bag-check"></i> Оформить заказ
</a>
</div>
</div>
<?php endif; ?>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
console.log('Cart page loaded');
function showAlert(message, type = 'success', timeout = 5000) {
const alertContainer = document.querySelector('#alert-container');
if (!alertContainer) return;
alertContainer.innerHTML = '';
const alert = document.createElement('div');
alert.className = `alert alert-${type} alert-dismissible fade show`;
alert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi ${type === 'success' ? 'bi-check-circle' : 'bi-exclamation-circle'} me-2 fs-5"></i>
<div>${message}</div>
</div>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
`;
alertContainer.appendChild(alert);
setTimeout(() => {
if (alert.parentNode && alert.classList.contains('show')) {
alert.classList.remove('show');
setTimeout(() => alert.remove(), 300);
}
}, timeout);
}
function updateTotal() {
let total = 0;
document.querySelectorAll('.cart-total-item').forEach(cell => {
const text = cell.textContent.replace(/[^\d.,]/g, '').replace(',', '.');
const value = parseFloat(text);
if (!isNaN(value)) {
total += value;
}
});
const totalElement = document.querySelector('#cart-total');
if (totalElement) {
totalElement.textContent = total.toFixed(2) + ' ₽';
}
return total;
}
document.querySelectorAll('.btn-remove-cart').forEach(btn => {
btn.addEventListener('click', function() {
const itemId = this.dataset.id;
const row = document.querySelector(`tr[data-id="${itemId}"]`);
if (!row || !confirm('Удалить этот товар из корзины?')) {
return;
}
const formData = new FormData();
formData.append('item_id', itemId);
formData.append('csrf', window.CSRF_TOKEN);
const originalHtml = this.innerHTML;
this.innerHTML = '<i class="bi bi-hourglass"></i>';
this.disabled = true;
fetch('<?= BASE_URL ?>ajax/cart_remove.php', {
method: 'POST',
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error('Ошибка сети: ' + response.status);
}
return response.json();
})
.then(data => {
console.log('Remove response:', data);
if (data.success) {
row.style.opacity = '0';
row.style.transition = 'opacity 0.3s';
setTimeout(() => {
row.remove();
updateTotal();
showAlert(data.message || 'Товар удален из корзины', 'success');
if (document.querySelectorAll('#cart-items tr').length === 0) {
setTimeout(() => location.reload(), 1000);
}
}, 300);
} else {
showAlert('Ошибка: ' + (data.error || 'Не удалось удалить товар'), 'danger');
this.innerHTML = originalHtml;
this.disabled = false;
}
})
.catch(error => {
console.error('Error:', error);
showAlert('Ошибка сети: ' + error.message, 'danger');
this.innerHTML = originalHtml;
this.disabled = false;
});
});
});
document.querySelectorAll('.cart-quantity').forEach(input => {
let timeout = null;
let originalValue = input.value;
const updateQuantity = function() {
const itemId = this.dataset.id;
let quantity = parseInt(this.value);
if (isNaN(quantity) || quantity < 1) {
this.value = originalValue;
quantity = originalValue;
}
if (quantity === parseInt(originalValue)) {
return;
}
const formData = new FormData();
formData.append('item_id', itemId);
formData.append('quantity', quantity);
formData.append('csrf', window.CSRF_TOKEN);
const row = document.querySelector(`tr[data-id="${itemId}"]`);
if (row) {
row.style.opacity = '0.7';
}
fetch('<?= BASE_URL ?>ajax/cart_update.php', {
method: 'POST',
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error('Ошибка сети: ' + response.status);
}
return response.json();
})
.then(data => {
console.log('Update response:', data);
if (row) {
row.style.opacity = '1';
}
if (data.success) {
const totalCell = row ? row.querySelector('.cart-total-item') : null;
if (totalCell) {
const priceCell = row.querySelector('td:nth-child(3)');
if (priceCell) {
const priceText = priceCell.textContent.replace(/[^\d.,]/g, '').replace(',', '.');
const price = parseFloat(priceText);
const total = price * quantity;
totalCell.textContent = total.toFixed(2) + ' ₽';
totalCell.classList.add('animate__animated', 'animate__pulse');
setTimeout(() => {
totalCell.classList.remove('animate__animated', 'animate__pulse');
}, 1000);
updateTotal();
}
}
originalValue = quantity;
showAlert('Количество обновлено', 'success');
} else {
this.value = originalValue;
showAlert('Ошибка: ' + data.error, 'danger');
}
})
.catch(error => {
console.error('Error:', error);
if (row) row.style.opacity = '1';
this.value = originalValue;
showAlert('Ошибка сети', 'danger');
});
};
input.addEventListener('change', updateQuantity);
input.addEventListener('input', function() {
clearTimeout(timeout);
timeout = setTimeout(() => {
if (this.value !== originalValue) {
this.dispatchEvent(new Event('change'));
}
}, 1000);
});
input.addEventListener('focus', function() {
originalValue = this.value;
});
});
const clearCartBtn = document.querySelector('#btn-clear-cart');
if (clearCartBtn) {
clearCartBtn.addEventListener('click', function() {
if (!confirm('Вы уверены, что хотите очистить всю корзину? Это действие нельзя отменить.')) {
return;
}
const formData = new FormData();
formData.append('csrf', window.CSRF_TOKEN);
const originalHtml = this.innerHTML;
this.innerHTML = '<i class="bi bi-hourglass"></i> Очистка...';
this.disabled = true;
fetch('<?= BASE_URL ?>ajax/cart_clear.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
showAlert('Корзина очищена', 'success');
setTimeout(() => location.reload(), 1000);
} else {
showAlert('Ошибка: ' + data.error, 'danger');
this.innerHTML = originalHtml;
this.disabled = false;
}
})
.catch(error => {
console.error('Error:', error);
showAlert('Ошибка сети', 'danger');
this.innerHTML = originalHtml;
this.disabled = false;
});
});
}
const discountForm = document.querySelector('#discount-form');
if (discountForm) {
discountForm.addEventListener('submit', function(e) {
e.preventDefault();
const codeInput = this.querySelector('input[name="discount_code"]');
const code = codeInput.value.trim();
if (!code) {
showAlert('Введите промокод', 'warning');
return;
}
const formData = new FormData();
formData.append('discount_code', code);
formData.append('csrf', window.CSRF_TOKEN);
fetch('<?= BASE_URL ?>ajax/apply_discount.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
showAlert('Скидка применена!', 'success');
setTimeout(() => location.reload(), 1500);
} else {
showAlert(data.error || 'Неверный промокод', 'danger');
}
})
.catch(error => {
console.error('Error:', error);
showAlert('Ошибка сети', 'danger');
});
});
}
const removeDiscountBtn = document.querySelector('.remove-discount');
if (removeDiscountBtn) {
removeDiscountBtn.addEventListener('click', function(e) {
e.preventDefault();
if (!confirm('Удалить примененную скидку?')) {
return;
}
const formData = new FormData();
formData.append('remove_discount', '1');
formData.append('csrf', window.CSRF_TOKEN);
fetch('<?= BASE_URL ?>ajax/apply_discount.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
showAlert('Скидка удалена', 'success');
setTimeout(() => location.reload(), 1000);
} else {
showAlert('Ошибка при удалении скидки', 'danger');
}
})
.catch(error => {
console.error('Error:', error);
showAlert('Ошибка сети', 'danger');
});
});
}
});
</script>
<?php
include __DIR__ . '/../includes/footer.php';
?>