527 lines
19 KiB
PHP
527 lines
19 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&redirect=' . urlencode($_SERVER['REQUEST_URI']));
|
||
exit();
|
||
}
|
||
|
||
if (!isset($_GET['id'])) {
|
||
header('Location: catalog.php');
|
||
exit();
|
||
}
|
||
|
||
$product_id = intval($_GET['id']);
|
||
|
||
$db = Database::getInstance()->getConnection();
|
||
|
||
try {
|
||
|
||
$productStmt = $db->prepare("
|
||
SELECT
|
||
p.*,
|
||
c.name as category_name,
|
||
c.slug as category_slug
|
||
FROM products p
|
||
LEFT JOIN categories c ON p.category_id = c.category_id
|
||
WHERE p.product_id = ? AND p.is_available = TRUE
|
||
");
|
||
$productStmt->execute([$product_id]);
|
||
$product = $productStmt->fetch();
|
||
|
||
if (!$product) {
|
||
header('Location: catalog.php?error=product_not_found');
|
||
exit();
|
||
}
|
||
|
||
$similarStmt = $db->prepare("
|
||
SELECT * FROM products
|
||
WHERE category_id = ?
|
||
AND product_id != ?
|
||
AND is_available = TRUE
|
||
ORDER BY RANDOM()
|
||
LIMIT 3
|
||
");
|
||
$similarStmt->execute([$product['category_id'], $product_id]);
|
||
$similarProducts = $similarStmt->fetchAll();
|
||
|
||
$reviews = [];
|
||
|
||
} catch (PDOException $e) {
|
||
die("Ошибка базы данных: " . $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 - <?= htmlspecialchars($product['name']) ?></title>
|
||
<link rel="stylesheet/less" type="text/css" href="style_for_cite.less">
|
||
<script src="https://cdn.jsdelivr.net/npm/less"></script>
|
||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
|
||
<style>
|
||
.product__gallery {
|
||
width: 350px !important;
|
||
max-width: 350px !important;
|
||
flex-shrink: 0 !important;
|
||
}
|
||
|
||
.product__main-image {
|
||
width: 350px !important;
|
||
height: 350px !important;
|
||
min-width: 350px !important;
|
||
min-height: 350px !important;
|
||
max-width: 350px !important;
|
||
max-height: 350px !important;
|
||
background: #f8f9fa;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
|
||
display: flex !important;
|
||
align-items: center !important;
|
||
justify-content: center !important;
|
||
margin-bottom: 15px;
|
||
border: 1px solid #e9ecef;
|
||
flex-shrink: 0 !important;
|
||
}
|
||
|
||
.product__main-image img,
|
||
#mainImage {
|
||
width: 100% !important;
|
||
height: 100% !important;
|
||
max-width: 350px !important;
|
||
max-height: 350px !important;
|
||
object-fit: contain !important;
|
||
display: block !important;
|
||
}
|
||
|
||
.product__section {
|
||
display: grid !important;
|
||
grid-template-columns: 350px 1fr !important;
|
||
gap: 30px;
|
||
}
|
||
|
||
.similar-products .product-image {
|
||
width: 100% !important;
|
||
height: 250px !important;
|
||
max-height: 250px !important;
|
||
overflow: hidden;
|
||
background: #f5f5f5;
|
||
display: flex !important;
|
||
align-items: center !important;
|
||
justify-content: center !important;
|
||
}
|
||
|
||
.similar-products .product-image img {
|
||
width: 100% !important;
|
||
height: 100% !important;
|
||
max-width: 100% !important;
|
||
max-height: 250px !important;
|
||
object-fit: contain !important;
|
||
}
|
||
|
||
.product-attributes {
|
||
background: #f8f9fa;
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
margin: 20px 0;
|
||
}
|
||
.attribute-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding: 10px 0;
|
||
border-bottom: 1px solid #ddd;
|
||
}
|
||
.attribute-label {
|
||
font-weight: bold;
|
||
color: #453227;
|
||
}
|
||
.attribute-value {
|
||
color: #617365;
|
||
}
|
||
.stock-status {
|
||
font-weight: bold;
|
||
padding: 5px 10px;
|
||
border-radius: 4px;
|
||
display: inline-block;
|
||
}
|
||
.in-stock {
|
||
background: #d4edda;
|
||
color: #155724;
|
||
}
|
||
.low-stock {
|
||
background: #fff3cd;
|
||
color: #856404;
|
||
}
|
||
.out-of-stock {
|
||
background: #f8d7da;
|
||
color: #721c24;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<header class="header">
|
||
<div class="header__top">
|
||
<div class="container header__top-content">
|
||
<div class="logo">AETERNA</div>
|
||
|
||
<div class="search-catalog">
|
||
<div class="catalog-dropdown">
|
||
Все категории <span>▼</span>
|
||
<div class="catalog-dropdown__menu">
|
||
<ul>
|
||
<li><a href="#">Диваны</a></li>
|
||
<li><a href="#">Кровати</a></li>
|
||
<li><a href="#">Шкафы</a></li>
|
||
<li><a href="#">Стулья</a></li>
|
||
<li><a href="#">Столы</a></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="search-box">
|
||
<input type="text" placeholder="Поиск товаров">
|
||
<span class="search-icon"><i class="fas fa-search"></i></span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="header__icons--top">
|
||
|
||
<a href="checkout.php" class="icon"><i class="fas fa-shopping-cart"></i></a>
|
||
<a href="register.php" class="icon"><i class="far fa-user"></i></a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="header__bottom">
|
||
<div class="container header__bottom-content">
|
||
<div class="catalog-menu">
|
||
<a href="catalog.php" class="catalog-link active-catalog">
|
||
<div class="catalog-icon">
|
||
<span class="line"></span>
|
||
<span class="line"></span>
|
||
<span class="line"></span>
|
||
</div>
|
||
<span class="catalog-lines">☰</span>
|
||
Каталог
|
||
</a>
|
||
</div>
|
||
|
||
<nav class="nav">
|
||
<ul class="nav-list">
|
||
<li><a href="cite_mebel.php">Главная</a></li>
|
||
<li><a href="services.php">Услуги</a></li>
|
||
<li><a href="delivery.php">Доставка и оплата</a></li>
|
||
<li><a href="warranty.php">Гарантия</a></li>
|
||
<li><a href="#footer">Контакты</a></li>
|
||
</ul>
|
||
</nav>
|
||
<div class="header-phone">+7(912)999-12-23</div>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="container">
|
||
<div class="breadcrumbs">
|
||
<a href="cite_mebel.php">Главная</a> •
|
||
<a href="catalog.php">Каталог</a> •
|
||
<?php if ($product['category_name']): ?>
|
||
<a href="catalog.php?category=<?= $product['category_id'] ?>">
|
||
<?= htmlspecialchars($product['category_name']) ?>
|
||
</a> •
|
||
<?php endif; ?>
|
||
<span><?= htmlspecialchars($product['name']) ?></span>
|
||
</div>
|
||
|
||
<div class="product__section">
|
||
<div class="product__gallery">
|
||
<div class="product__main-image">
|
||
<img src="<?= htmlspecialchars($product['image_url'] ?? 'img/1.jpg') ?>"
|
||
alt="<?= htmlspecialchars($product['name']) ?>"
|
||
id="mainImage">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="product__info">
|
||
<h1><?= htmlspecialchars($product['name']) ?></h1>
|
||
|
||
<div class="product__rating">
|
||
<div class="stars">
|
||
<?php
|
||
$rating = $product['rating'] ?? 0;
|
||
$fullStars = floor($rating);
|
||
$hasHalfStar = $rating - $fullStars >= 0.5;
|
||
|
||
for ($i = 1; $i <= 5; $i++) {
|
||
if ($i <= $fullStars) {
|
||
echo '<span class="star filled">★</span>';
|
||
} elseif ($i == $fullStars + 1 && $hasHalfStar) {
|
||
echo '<span class="star half">★</span>';
|
||
} else {
|
||
echo '<span class="star">☆</span>';
|
||
}
|
||
}
|
||
?>
|
||
</div>
|
||
<span class="rating-value"><?= number_format($rating, 1) ?></span>
|
||
<span class="reviews-count">(<?= $product['review_count'] ?> отзывов)</span>
|
||
</div>
|
||
|
||
<div class="product__price">
|
||
<span class="current-price">
|
||
<?= number_format($product['price'], 0, '', ' ') ?> ₽
|
||
</span>
|
||
<?php if ($product['old_price'] && $product['old_price'] > $product['price']): ?>
|
||
<span class="old-price">
|
||
<?= number_format($product['old_price'], 0, '', ' ') ?> ₽
|
||
</span>
|
||
<span class="discount-badge">
|
||
-<?= round(($product['old_price'] - $product['price']) / $product['old_price'] * 100) ?>%
|
||
</span>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<div class="stock-status <?php
|
||
if ($product['stock_quantity'] > 10) echo 'in-stock';
|
||
elseif ($product['stock_quantity'] > 0) echo 'low-stock';
|
||
else echo 'out-of-stock';
|
||
?>">
|
||
<?php
|
||
if ($product['stock_quantity'] > 10) {
|
||
echo '<i class="fas fa-check-circle"></i> В наличии';
|
||
} elseif ($product['stock_quantity'] > 0) {
|
||
echo '<i class="fas fa-exclamation-circle"></i> Осталось мало: ' . $product['stock_quantity'] . ' шт.';
|
||
} else {
|
||
echo '<i class="fas fa-times-circle"></i> Нет в наличии';
|
||
}
|
||
?>
|
||
</div>
|
||
|
||
<div class="product-attributes">
|
||
<div class="attribute-row">
|
||
<span class="attribute-label">Артикул:</span>
|
||
<span class="attribute-value"><?= $product['sku'] ?? 'N/A' ?></span>
|
||
</div>
|
||
<div class="attribute-row">
|
||
<span class="attribute-label">Категория:</span>
|
||
<span class="attribute-value"><?= htmlspecialchars($product['category_name'] ?? 'Без категории') ?></span>
|
||
</div>
|
||
<div class="attribute-row">
|
||
<span class="attribute-label">На складе:</span>
|
||
<span class="attribute-value"><?= $product['stock_quantity'] ?> шт.</span>
|
||
</div>
|
||
</div>
|
||
|
||
<p class="product__description">
|
||
<?= nl2br(htmlspecialchars($product['description'] ?? 'Описание отсутствует')) ?>
|
||
</p>
|
||
|
||
<?php if ($product['stock_quantity'] > 0): ?>
|
||
<div class="product__purchase">
|
||
<div class="product__quantity">
|
||
<button class="product__qty-btn minus">-</button>
|
||
<input type="number" class="product__qty-value" value="1" min="1" max="<?= $product['stock_quantity'] ?>">
|
||
<button class="product__qty-btn plus">+</button>
|
||
</div>
|
||
|
||
<div class="product__actions">
|
||
<button class="btn primary-btn" onclick="addToCart(<?= $product['product_id'] ?>)">
|
||
<i class="fas fa-shopping-cart"></i> В корзину
|
||
</button>
|
||
<button class="btn secondary-btn" onclick="buyNow(<?= $product['product_id'] ?>)">
|
||
<i class="fas fa-bolt"></i> Купить сейчас
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<?php else: ?>
|
||
<div class="product__actions">
|
||
<button class="btn secondary-btn" onclick="notifyWhenAvailable(<?= $product['product_id'] ?>)">
|
||
<i class="fas fa-bell"></i> Уведомить о поступлении
|
||
</button>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (isset($_SESSION['isAdmin']) && $_SESSION['isAdmin']): ?>
|
||
<div class="admin-actions" style="margin-top: 20px;">
|
||
<a href="admin/index.php?action=edit_product&id=<?= $product['product_id'] ?>"
|
||
class="btn btn-warning">
|
||
<i class="fas fa-edit"></i> Редактировать
|
||
</a>
|
||
<button onclick="deleteProduct(<?= $product['product_id'] ?>)"
|
||
class="btn btn-danger">
|
||
<i class="fas fa-trash"></i> Удалить
|
||
</button>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<?php if (!empty($similarProducts)): ?>
|
||
<section class="similar-products">
|
||
<h2>Похожие товары</h2>
|
||
<div class="products-grid">
|
||
<?php foreach ($similarProducts as $similar): ?>
|
||
<div class="product-card">
|
||
<div class="product-image">
|
||
<img src="<?= htmlspecialchars($similar['image_url'] ?? 'img/1.jpg') ?>"
|
||
alt="<?= htmlspecialchars($similar['name']) ?>">
|
||
</div>
|
||
<div class="product-info">
|
||
<h3><?= htmlspecialchars($similar['name']) ?></h3>
|
||
<p class="product-price">
|
||
<?= number_format($similar['price'], 0, '', ' ') ?> ₽
|
||
</p>
|
||
<a href="product.php?id=<?= $similar['product_id'] ?>"
|
||
class="btn btn-primary">
|
||
Подробнее
|
||
</a>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</section>
|
||
<?php endif; ?>
|
||
</main>
|
||
|
||
<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>
|
||
|
||
<script>
|
||
$(document).ready(function() {
|
||
|
||
$('.product__qty-btn.plus').click(function() {
|
||
const $input = $('.product__qty-value');
|
||
let value = parseInt($input.val());
|
||
let max = parseInt($input.attr('max'));
|
||
if (value < max) {
|
||
$input.val(value + 1);
|
||
}
|
||
});
|
||
|
||
$('.product__qty-btn.minus').click(function() {
|
||
const $input = $('.product__qty-value');
|
||
let value = parseInt($input.val());
|
||
if (value > 1) {
|
||
$input.val(value - 1);
|
||
}
|
||
});
|
||
|
||
window.addToCart = function(productId) {
|
||
const quantity = $('.product__qty-value').val();
|
||
|
||
$.ajax({
|
||
url: 'api/add_to_cart.php',
|
||
method: 'POST',
|
||
data: {
|
||
product_id: productId,
|
||
quantity: quantity
|
||
},
|
||
success: function(response) {
|
||
try {
|
||
const result = JSON.parse(response);
|
||
if (result.success) {
|
||
alert('Товар добавлен в корзину!');
|
||
|
||
$('.cart-count').text(result.cart_count);
|
||
} else {
|
||
alert('Ошибка: ' + result.message);
|
||
}
|
||
} catch(e) {
|
||
alert('Товар добавлен в корзину!');
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
window.buyNow = function(productId) {
|
||
const quantity = $('.product__qty-value').val();
|
||
|
||
$.ajax({
|
||
url: 'api/add_to_cart.php',
|
||
method: 'POST',
|
||
data: {
|
||
product_id: productId,
|
||
quantity: quantity
|
||
},
|
||
success: function() {
|
||
window.location.href = 'checkout.php';
|
||
}
|
||
});
|
||
};
|
||
|
||
window.notifyWhenAvailable = function(productId) {
|
||
const email = prompt('Введите ваш email для уведомления:');
|
||
if (email) {
|
||
$.ajax({
|
||
url: 'notify_available.php',
|
||
method: 'POST',
|
||
data: {
|
||
product_id: productId,
|
||
email: email
|
||
},
|
||
success: function(response) {
|
||
alert('Вы будете уведомлены о поступлении товара!');
|
||
}
|
||
});
|
||
}
|
||
};
|
||
|
||
window.deleteProduct = function(productId) {
|
||
if (confirm('Вы уверены, что хотите удалить этот товар?')) {
|
||
window.location.href = 'admin/index.php?action=products';
|
||
}
|
||
};
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|