View file test.4imas.ru/public/orders.php
<?php
require_once __DIR__ . '/../config/bootstrap.php';
require_once __DIR__ . '/../config/auth.php';
require_once __DIR__ . '/../config/functions.php';
require_login();
try {
global $pdo;
$stmt = $pdo->prepare("SELECT * FROM orders WHERE user_id = :user_id ORDER BY created_at DESC");
$stmt->execute(['user_id' => $_SESSION['user_id']]);
$orders = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
die('Ошибка базы данных: ' . $e->getMessage());
}
function order_status_badge($status) {
$colors = [
'Новый' => 'primary',
'В обработке' => 'warning',
'Готов' => 'info',
'Доставлен' => 'success',
'Отменен' => 'danger'
];
return $colors[$status] ?? 'secondary';
}
include __DIR__ . '/../includes/header.php';
?>
<div class="container py-5">
<h2 class="mb-4 fw-bold text-center animate__animated animate__fadeInDown">
<i class="bi bi-receipt"></i> Мои заказы
</h2>
<?php if (empty($orders)): ?>
<div class="alert alert-info text-center animate__animated animate__fadeInUp">
<i class="bi bi-info-circle fs-4"></i>
<p class="mb-0 mt-2">Вы еще не сделали ни одного заказа.</p>
<a href="<?= BASE_URL ?>" class="btn btn-primary mt-3">
<i class="bi bi-arrow-left"></i> Перейти к выбору фото
</a>
</div>
<?php else: ?>
<div class="accordion animate__animated animate__fadeInUp" id="ordersAccordion">
<?php foreach ($orders as $index => $order): ?>
<div class="accordion-item mb-3 shadow-sm border-0 rounded">
<h2 class="accordion-header" id="heading<?= e($order['id']) ?>">
<button class="accordion-button <?= $index !== 0 ? 'collapsed' : '' ?>"
type="button"
data-bs-toggle="collapse"
data-bs-target="#collapse<?= e($order['id']) ?>"
aria-expanded="<?= $index === 0 ? 'true' : 'false' ?>"
aria-controls="collapse<?= e($order['id']) ?>">
<div class="d-flex justify-content-between w-100 align-items-center">
<div class="me-3">
<strong>Заказ #<?= e($order['id']) ?></strong>
<div class="text-muted small">
<i class="bi bi-calendar"></i>
<?= date('d.m.Y H:i', strtotime($order['created_at'])) ?>
</div>
</div>
<div>
<span class="badge bg-<?= order_status_badge($order['status']) ?>">
<?= e($order['status']) ?>
</span>
<span class="badge bg-dark ms-2">
<?= number_format($order['total'], 2) ?> ₽
</span>
</div>
</div>
</button>
</h2>
<div id="collapse<?= e($order['id']) ?>"
class="accordion-collapse collapse <?= $index === 0 ? 'show' : '' ?>"
aria-labelledby="heading<?= e($order['id']) ?>"
data-bs-parent="#ordersAccordion">
<div class="accordion-body">
<div class="row mb-4">
<div class="col-md-6">
<h6 class="fw-bold">
<i class="bi bi-geo-alt text-primary"></i> Информация о доставке
</h6>
<div class="card">
<div class="card-body">
<p class="mb-1">
<strong>ФИО:</strong> <?= e($order['fullname']) ?>
</p>
<p class="mb-1">
<strong>Телефон:</strong>
<a href="tel:<?= e($order['phone']) ?>" class="text-decoration-none">
<?= e($order['phone']) ?>
</a>
</p>
<p class="mb-0">
<strong>Адрес:</strong> <?= e($order['address']) ?>
</p>
</div>
</div>
</div>
<div class="col-md-6">
<h6 class="fw-bold">
<i class="bi bi-receipt text-success"></i> Детали заказа
</h6>
<div class="card">
<div class="card-body">
<p class="mb-1">
<strong>Статус:</strong>
<span class="badge bg-<?= order_status_badge($order['status']) ?>">
<?= e($order['status']) ?>
</span>
</p>
<p class="mb-1">
<strong>Дата создания:</strong>
<?= date('d.m.Y H:i', strtotime($order['created_at'])) ?>
</p>
<?php if (!empty($order['discount_code'])): ?>
<p class="mb-0">
<strong>Промокод:</strong>
<span class="badge bg-warning"><?= e($order['discount_code']) ?></span>
</p>
<?php endif; ?>
</div>
</div>
</div>
</div>
<h6 class="fw-bold mb-3">
<i class="bi bi-cart-check text-info"></i> Товары в заказе
</h6>
<?php
try {
$stmtItems = $pdo->prepare("SELECT oi.*, p.filename, p.id as photo_id, f.name AS format_name, f.price as format_price
FROM order_items oi
LEFT JOIN photos p ON oi.photo_id = p.id
LEFT JOIN formats f ON oi.format_id = f.id
WHERE oi.order_id = :order_id");
$stmtItems->execute(['order_id' => $order['id']]);
$items = $stmtItems->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
echo '<div class="alert alert-danger">Ошибка при получении товаров заказа: ' . e($e->getMessage()) . '</div>';
$items = [];
}
?>
<?php if (empty($items)): ?>
<div class="alert alert-warning">
<i class="bi bi-exclamation-triangle"></i> В этом заказе нет товаров
</div>
<?php else: ?>
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th style="width: 80px;">Фото</th>
<th>Формат</th>
<th class="text-center">Количество</th>
<th class="text-end">Цена за шт.</th>
<th class="text-end">Итого</th>
</tr>
</thead>
<tbody>
<?php
$order_subtotal = 0;
foreach ($items as $item):
$item_total = $item['price'] * $item['quantity'];
$order_subtotal += $item_total;
?>
<tr>
<td>
<?php if (!empty($item['filename'])): ?>
<?php
$photo_path = UPLOAD_DIR . 'photos/' . $item['filename'];
$photo_url = BASE_URL . 'uploads/photos/' . $item['filename'];
?>
<?php if (file_exists($photo_path)): ?>
<img src="<?= e($photo_url) ?>"
alt="Фото"
class="rounded"
style="width: 60px; height: 60px; object-fit: cover;">
<?php else: ?>
<div class="bg-light rounded d-flex align-items-center justify-content-center"
style="width: 60px; height: 60px;">
<i class="bi bi-image text-muted"></i>
</div>
<?php endif; ?>
<?php else: ?>
<div class="bg-light rounded d-flex align-items-center justify-content-center"
style="width: 60px; height: 60px;">
<i class="bi bi-image text-muted"></i>
</div>
<?php endif; ?>
</td>
<td>
<div class="fw-bold"><?= e($item['format_name'] ?? 'Не указан') ?></div>
<?php if (!empty($item['photo_id'])): ?>
<small class="text-muted">ID фото: <?= e($item['photo_id']) ?></small>
<?php endif; ?>
</td>
<td class="text-center">
<span class="badge bg-primary rounded-pill fs-6">
<?= e($item['quantity']) ?> шт.
</span>
</td>
<td class="text-end">
<?= number_format($item['price'], 2) ?> ₽
</td>
<td class="text-end fw-bold">
<?= number_format($item_total, 2) ?> ₽
</td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot class="table-active">
<tr>
<td colspan="4" class="text-end fw-bold">Сумма заказа:</td>
<td class="text-end fw-bold">
<?= number_format($order_subtotal, 2) ?> ₽
</td>
</tr>
<?php if (!empty($order['discount_code'])): ?>
<tr class="table-warning">
<td colspan="4" class="text-end fw-bold">
Скидка (<?= e($order['discount_code']) ?>):
</td>
<td class="text-end fw-bold text-danger">
-<?= number_format($order_subtotal - $order['total'], 2) ?> ₽
</td>
</tr>
<?php endif; ?>
<tr class="table-success">
<td colspan="4" class="text-end fw-bold fs-5">Итого к оплате:</td>
<td class="text-end fw-bold fs-5">
<?= number_format($order['total'], 2) ?> ₽
</td>
</tr>
</tfoot>
</table>
</div>
<?php endif; ?>
<div class="mt-4 d-flex justify-content-between">
<div>
<?php if ($order['status'] === 'Новый'): ?>
<button class="btn btn-outline-danger btn-sm cancel-order-btn"
data-order-id="<?= e($order['id']) ?>">
<i class="bi bi-x-circle"></i> Отменить заказ
</button>
<?php endif; ?>
</div>
<div>
<button class="btn btn-outline-primary btn-sm print-order-btn"
data-order-id="<?= e($order['id']) ?>">
<i class="bi bi-printer"></i> Распечатать
</button>
<a href="<?= BASE_URL ?>checkout.php" class="btn btn-success btn-sm ms-2">
<i class="bi bi-cart-plus"></i> Новый заказ
</a>
</div>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="mt-4 text-center">
<small class="text-muted">
<i class="bi bi-info-circle"></i>
Всего заказов: <?= count($orders) ?>
</small>
</div>
<?php endif; ?>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Отмена заказа
document.querySelectorAll('.cancel-order-btn').forEach(btn => {
btn.addEventListener('click', function() {
const orderId = this.dataset.orderId;
if (!confirm('Вы уверены, что хотите отменить заказ #' + orderId + '?')) {
return;
}
const formData = new FormData();
formData.append('order_id', orderId);
formData.append('action', 'cancel');
formData.append('csrf', window.CSRF_TOKEN);
fetch('<?= BASE_URL ?>ajax/order_update.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('Заказ отменен!');
location.reload();
} else {
alert('Ошибка: ' + (data.error || 'Не удалось отменить заказ'));
}
})
.catch(error => {
console.error('Error:', error);
alert('Ошибка сети');
});
});
});
document.querySelectorAll('.print-order-btn').forEach(btn => {
btn.addEventListener('click', function() {
const orderId = this.dataset.orderId;
const printWindow = window.open('<?= BASE_URL ?>print_order.php?id=' + orderId, '_blank');
if (printWindow) {
printWindow.focus();
} else {
alert('Пожалуйста, разрешите всплывающие окна для печати');
}
});
});
const accordionButtons = document.querySelectorAll('.accordion-button');
accordionButtons.forEach(btn => {
btn.addEventListener('click', function() {
const targetId = this.getAttribute('data-bs-target');
const target = document.querySelector(targetId);
if (target) {
target.classList.add('animate__animated', 'animate__fadeIn');
setTimeout(() => {
target.classList.remove('animate__animated', 'animate__fadeIn');
}, 500);
}
});
});
});
</script>
<?php
include __DIR__ . '/../includes/footer.php';
?>