- Introduced a new WordPress theme "BackPRO News" with a lightweight magazine-style design. - Added columns for tracking retry attempts and timestamps for unpublished/generated articles in the articles table. - Included remote service metadata fields in the sites table for better management. - Created log files for image replacements, installer actions, OpenAI article generation, and publishing processes. - Implemented a dashboard template for site management, including permalink settings and theme installation options.
232 lines
12 KiB
PHP
232 lines
12 KiB
PHP
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h2>Biblioteka tematów</h2>
|
|
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addCategoryModal">
|
|
<i class="bi bi-plus-lg me-1"></i>Dodaj kategorię
|
|
</button>
|
|
</div>
|
|
|
|
<?php if (empty($categories)): ?>
|
|
<div class="alert alert-info">Brak tematów. Dodaj pierwszą kategorię.</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="accordion" id="topicsAccordion">
|
|
<?php foreach ($categories as $cat): ?>
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#cat-<?= $cat['id'] ?>">
|
|
<strong><?= htmlspecialchars($cat['name']) ?></strong>
|
|
<span class="badge bg-secondary ms-2"><?= count($cat['children']) ?></span>
|
|
<?php if ($cat['description']): ?>
|
|
<small class="text-muted ms-3"><?= htmlspecialchars(mb_strimwidth($cat['description'], 0, 60, '...')) ?></small>
|
|
<?php endif; ?>
|
|
</button>
|
|
</h2>
|
|
<div id="cat-<?= $cat['id'] ?>" class="accordion-collapse collapse" data-bs-parent="#topicsAccordion">
|
|
<div class="accordion-body p-0">
|
|
<div class="p-3 bg-light border-bottom d-flex justify-content-between align-items-center">
|
|
<div class="d-flex gap-2">
|
|
<button class="btn btn-sm btn-outline-primary btn-edit-global"
|
|
data-id="<?= $cat['id'] ?>"
|
|
data-name="<?= htmlspecialchars($cat['name']) ?>"
|
|
data-description="<?= htmlspecialchars($cat['description'] ?? '') ?>">
|
|
<i class="bi bi-pencil me-1"></i>Edytuj kategorię
|
|
</button>
|
|
<button class="btn btn-sm btn-outline-danger btn-delete-global" data-id="<?= $cat['id'] ?>" data-type="category">
|
|
<i class="bi bi-trash me-1"></i>Usuń
|
|
</button>
|
|
</div>
|
|
<button class="btn btn-sm btn-success btn-add-subtopic" data-parent-id="<?= $cat['id'] ?>" data-parent-name="<?= htmlspecialchars($cat['name']) ?>">
|
|
<i class="bi bi-plus-lg me-1"></i>Dodaj temat
|
|
</button>
|
|
</div>
|
|
|
|
<?php if (!empty($cat['children'])): ?>
|
|
<table class="table table-hover mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>Temat</th>
|
|
<th>Opis</th>
|
|
<th style="width:120px">Akcje</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($cat['children'] as $child): ?>
|
|
<tr>
|
|
<td><?= htmlspecialchars($child['name']) ?></td>
|
|
<td class="text-muted small"><?= htmlspecialchars(mb_strimwidth($child['description'] ?? '', 0, 80, '...')) ?></td>
|
|
<td>
|
|
<div class="btn-group btn-group-sm">
|
|
<button class="btn btn-outline-primary btn-edit-global"
|
|
data-id="<?= $child['id'] ?>"
|
|
data-name="<?= htmlspecialchars($child['name']) ?>"
|
|
data-description="<?= htmlspecialchars($child['description'] ?? '') ?>">
|
|
<i class="bi bi-pencil"></i>
|
|
</button>
|
|
<button class="btn btn-outline-danger btn-delete-global" data-id="<?= $child['id'] ?>" data-type="topic">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
<?php else: ?>
|
|
<div class="p-3 text-muted text-center">Brak tematów w tej kategorii</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<!-- Modal: Dodaj kategorię -->
|
|
<div class="modal fade" id="addCategoryModal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<form method="post" action="/global-topics/categories">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Dodaj kategorię</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label class="form-label">Nazwa kategorii</label>
|
|
<input type="text" class="form-control" name="name" required placeholder="np. Sport">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Opis</label>
|
|
<textarea class="form-control" name="description" rows="2" placeholder="Krótki opis kategorii..."></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Anuluj</button>
|
|
<button type="submit" class="btn btn-primary">Dodaj</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal: Dodaj temat (subtopic) -->
|
|
<div class="modal fade" id="addSubtopicModal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<form method="post" id="subtopicForm" action="">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Dodaj temat do: <span id="subtopicParentName"></span></h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label class="form-label">Nazwa tematu</label>
|
|
<input type="text" class="form-control" name="name" required placeholder="np. Piłka nożna">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Opis / wytyczne dla AI</label>
|
|
<textarea class="form-control" name="description" rows="3" placeholder="Opisz zakres tematyczny, styl pisania..."></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Anuluj</button>
|
|
<button type="submit" class="btn btn-success">Dodaj temat</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal: Edytuj -->
|
|
<div class="modal fade" id="editGlobalModal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<form method="post" id="editGlobalForm" action="">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Edytuj</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label class="form-label">Nazwa</label>
|
|
<input type="text" class="form-control" name="name" id="editGlobalName" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Opis</label>
|
|
<textarea class="form-control" name="description" id="editGlobalDesc" rows="3"></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Anuluj</button>
|
|
<button type="submit" class="btn btn-primary">Zapisz</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
document.querySelectorAll('.btn-add-subtopic').forEach(function (btn) {
|
|
btn.addEventListener('click', function () {
|
|
document.getElementById('subtopicForm').action = '/global-topics/' + this.dataset.parentId + '/subtopics';
|
|
document.getElementById('subtopicParentName').textContent = this.dataset.parentName;
|
|
new bootstrap.Modal(document.getElementById('addSubtopicModal')).show();
|
|
});
|
|
});
|
|
|
|
document.querySelectorAll('.btn-edit-global').forEach(function (btn) {
|
|
btn.addEventListener('click', function () {
|
|
document.getElementById('editGlobalForm').action = '/global-topics/' + this.dataset.id + '/update';
|
|
document.getElementById('editGlobalName').value = this.dataset.name;
|
|
document.getElementById('editGlobalDesc').value = this.dataset.description;
|
|
new bootstrap.Modal(document.getElementById('editGlobalModal')).show();
|
|
});
|
|
});
|
|
|
|
document.querySelectorAll('.btn-delete-global').forEach(function (btn) {
|
|
btn.addEventListener('click', async function () {
|
|
var id = this.dataset.id;
|
|
var isCategory = this.dataset.type === 'category';
|
|
var msg = isCategory ? 'Usunac kategorie i wszystkie jej tematy?' : 'Usunac ten temat?';
|
|
var ok = await backproConfirm(msg, {
|
|
title: 'Potwierdzenie usuniecia',
|
|
confirmText: 'Usun',
|
|
cancelText: 'Anuluj',
|
|
confirmClass: 'btn-danger'
|
|
});
|
|
if (!ok) return;
|
|
|
|
var el = isCategory ? this.closest('.accordion-item') : this.closest('tr');
|
|
var origHtml = btn.innerHTML;
|
|
btn.disabled = true;
|
|
btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span>';
|
|
|
|
fetch('/global-topics/' + id + '/delete', {
|
|
method: 'POST',
|
|
headers: { 'X-Requested-With': 'XMLHttpRequest' }
|
|
})
|
|
.then(function (r) { return r.json(); })
|
|
.then(function (data) {
|
|
if (data.success) {
|
|
el.style.transition = 'opacity .3s';
|
|
el.style.opacity = '0';
|
|
setTimeout(function () {
|
|
el.remove();
|
|
}, 300);
|
|
backproNotify('Element zostal usuniety.', 'success', { delay: 2500 });
|
|
} else {
|
|
backproNotify(data.message || 'Blad usuwania', 'danger');
|
|
btn.disabled = false;
|
|
btn.innerHTML = origHtml;
|
|
}
|
|
})
|
|
.catch(function () {
|
|
backproNotify('Blad polaczenia', 'danger');
|
|
btn.disabled = false;
|
|
btn.innerHTML = origHtml;
|
|
});
|
|
});
|
|
});
|
|
});
|
|
</script>
|