File size: 12Kb
<?php
require_once __DIR__ . '/../config/bootstrap.php';
require_once __DIR__ . '/../config/auth.php';
require_once __DIR__ . '/../config/functions.php';
if (!is_admin()) {
http_response_code(403);
die("Доступ запрещён");
}
require_once __DIR__ . '/../includes/header.php';
try {
$stmt = $pdo->query("SELECT * FROM discounts ORDER BY id DESC");
$discounts = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $e) {
die("Ошибка загрузки скидок: " . htmlspecialchars($e->getMessage()));
}
?>
<div class="container my-5">
<h1 class="mb-4">
<i class="bi bi-percent"></i> Управление скидками
</h1>
<div class="glass p-4 card-ui fade-in">
<button class="btn btn-success mb-3" onclick="showAddDiscount()">
<i class="bi bi-plus-circle"></i> Добавить скидку
</button>
<div class="table-responsive">
<table class="table table-hover table-striped align-middle">
<thead class="table-dark">
<tr>
<th>#ID</th>
<th>Код</th>
<th>Скидка</th>
<th>Активна</th>
<th>Действует до</th>
<th>Дата создания</th>
<th>Действия</th>
</tr>
</thead>
<tbody id="discounts-body">
<?php if (empty($discounts)): ?>
<tr>
<td colspan="7" class="text-center text-muted py-4">
<i class="bi bi-percent"></i> Нет скидочных кодов
</td>
</tr>
<?php else: ?>
<?php foreach ($discounts as $d): ?>
<tr id="discount-<?= e($d['id']) ?>">
<td><?= e($d['id']) ?></td>
<td>
<span class="badge bg-info text-dark fs-6"><?= e($d['code']) ?></span>
</td>
<td>
<span class="badge bg-success fs-6"><?= e($d['percent']) ?>%</span>
</td>
<td>
<?php if ($d['active']): ?>
<span class="badge bg-success"><i class="bi bi-check-circle"></i> Да</span>
<?php else: ?>
<span class="badge bg-danger"><i class="bi bi-x-circle"></i> Нет</span>
<?php endif; ?>
</td>
<td>
<?= $d['expires_at'] ? date('d.m.Y', strtotime($d['expires_at'])) : '—' ?>
</td>
<td><?= date('d.m.Y H:i', strtotime($d['created_at'])) ?></td>
<td>
<div class="btn-group btn-group-sm">
<button class="btn btn-outline-warning" onclick="editDiscount(<?= e($d['id']) ?>)">
<i class="bi bi-pencil"></i> Изменить
</button>
<button class="btn btn-outline-danger" onclick="deleteDiscount(<?= e($d['id']) ?>)">
<i class="bi bi-trash"></i> Удалить
</button>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="discountModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalTitle">
<i class="bi bi-percent"></i> <span>Добавить скидку</span>
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<input type="hidden" id="discountId">
<div class="mb-3">
<label class="form-label fw-bold">Код скидки *</label>
<input type="text" id="discountCode" class="form-control" required
placeholder="Например: SUMMER2024" maxlength="50">
<div class="form-text">Уникальный код для применения скидки</div>
</div>
<div class="mb-3">
<label class="form-label fw-bold">Размер скидки (%) *</label>
<input type="number" id="discountPercent" class="form-control"
min="1" max="100" step="1" required value="10">
<div class="form-text">От 1% до 100%</div>
</div>
<div class="mb-3">
<label class="form-label fw-bold">Действует до</label>
<input type="date" id="discountExpires" class="form-control">
<div class="form-text">Оставьте пустым для бессрочной скидки</div>
</div>
<div class="mb-3 form-check form-switch">
<input type="checkbox" id="discountActive" class="form-check-input" checked>
<label class="form-check-label fw-bold">Активна</label>
</div>
<div id="modal-feedback" class="mt-3"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
<i class="bi bi-x-circle"></i> Отмена
</button>
<button type="button" class="btn btn-primary" onclick="saveDiscount()">
<i class="bi bi-check-circle"></i> Сохранить
</button>
</div>
</div>
</div>
</div>
<script>
function showAddDiscount() {
document.getElementById('discountId').value = '';
document.getElementById('discountCode').value = '';
document.getElementById('discountPercent').value = '10';
document.getElementById('discountExpires').value = '';
document.getElementById('discountActive').checked = true;
document.querySelector('#modalTitle span').textContent = 'Добавить скидку';
const modal = new bootstrap.Modal(document.getElementById('discountModal'));
modal.show();
}
function editDiscount(id) {
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '<?= $_SESSION['csrf_token'] ?? '' ?>';
fetch('/ajax/admin/get_discount.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken
},
body: JSON.stringify({
id: id,
csrf: csrfToken
})
})
.then(res => res.json())
.then(data => {
if (data.success) {
const discount = data.discount;
document.getElementById('discountId').value = discount.id;
document.getElementById('discountCode').value = discount.code;
document.getElementById('discountPercent').value = discount.percent;
document.getElementById('discountExpires').value = discount.expires_at || '';
document.getElementById('discountActive').checked = discount.active == 1;
document.querySelector('#modalTitle span').textContent = 'Редактировать скидку';
const modal = new bootstrap.Modal(document.getElementById('discountModal'));
modal.show();
} else {
alert('Ошибка: ' + (data.error || 'Неизвестная ошибка'));
}
})
.catch(error => {
console.error('Error:', error);
alert('Ошибка соединения с сервером');
});
}
// Сохранение скидки
function saveDiscount() {
const id = document.getElementById('discountId').value;
const code = document.getElementById('discountCode').value.trim();
const percent = document.getElementById('discountPercent').value;
const expires = document.getElementById('discountExpires').value;
const active = document.getElementById('discountActive').checked ? 1 : 0;
const feedback = document.getElementById('modal-feedback');
if (!code) {
feedback.innerHTML = '<div class="alert alert-danger">Введите код скидки</div>';
return;
}
if (percent < 1 || percent > 100) {
feedback.innerHTML = '<div class="alert alert-danger">Скидка должна быть от 1% до 100%</div>';
return;
}
feedback.innerHTML = '<div class="alert alert-info">Сохранение...</div>';
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '<?= $_SESSION['csrf_token'] ?? '' ?>';
fetch('/ajax/admin/save_discount.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken
},
body: JSON.stringify({
id: id,
code: code,
percent: percent,
expires_at: expires || null,
active: active,
csrf: csrfToken
})
})
.then(res => res.json())
.then(data => {
if (data.success) {
const modal = bootstrap.Modal.getInstance(document.getElementById('discountModal'));
modal.hide();
location.reload();
} else {
feedback.innerHTML = '<div class="alert alert-danger">Ошибка: ' + (data.error || 'Неизвестная ошибка') + '</div>';
}
})
.catch(error => {
console.error('Error:', error);
feedback.innerHTML = '<div class="alert alert-danger">Ошибка соединения с сервером</div>';
});
}
function deleteDiscount(id) {
if (!confirm('Вы уверены, что хотите удалить эту скидку?')) return;
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '<?= $_SESSION['csrf_token'] ?? '' ?>';
fetch('/ajax/admin/delete_discount.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken
},
body: JSON.stringify({
id: id,
csrf: csrfToken
})
})
.then(res => res.json())
.then(data => {
if (data.success) {
document.getElementById('discount-'+id).remove();
if (!document.querySelector('#discounts-body tr:not([style*="display"])')) {
location.reload();
}
} else {
alert('Ошибка: ' + (data.error || 'Неизвестная ошибка'));
}
})
.catch(error => {
console.error('Error:', error);
alert('Ошибка соединения с сервером');
});
}
if (!document.querySelector('meta[name="csrf-token"]')) {
const meta = document.createElement('meta');
meta.name = 'csrf-token';
meta.content = '<?= $_SESSION['csrf_token'] ?? '' ?>';
document.head.appendChild(meta);
}
</script>
<?php
require_once __DIR__ . '/../includes/footer.php';
?>