Kategorieseitenpaginator #50

Merged
niklas.ortmann merged 16 commits from KategorieseitenPaginator into dev 2026-07-17 17:36:10 +02:00
3 changed files with 186 additions and 92 deletions
Showing only changes of commit bb2c368b1f - Show all commits
+99 -72
View File
@@ -1,83 +1,110 @@
<?php <?php
include_once "php/controller/showCategory-controller.php"; include_once "php/controller/showCategory-controller.php";
$currentSort = isset($sortStyle) ? $sortStyle : 'alphabet';
$currentPage = isset($page) ? $page : 1;
?> ?>
<div class="cat-view-container"> <!-- Das Formular umschließt jetzt das gesamte Layout -->
<div class="cat-view-header"> <form id="search-form-id" action="index.php" method="GET" style="display: contents;">
<!-- Kategorie-Titel sicher ausgeben --> <input type="hidden" name="pfad" value="showCategory">
<h1 class="cat-view-title">Kategorie: <?php echo (isset($category) && !empty($category)) ? htmlspecialchars($category) : 'Unbekannt'; ?></h1> <input type="hidden" name="category" value="<?php echo (isset($category) && !empty($category)) ? htmlspecialchars($category) : ''; ?>">
<p class="cat-view-meta-text">Beiträge in dieser Kategorie</p> <input type="hidden" id="s-res-page-input" name="page" value="<?php echo $currentPage; ?>">
</div>
<!-- Die Artikel-Liste --> <div class="cat-view-container">
<div class="cat-view-list">
<?php if (isset($articles) && !empty($articles)): ?>
<?php foreach ($articles as $article): ?>
<div class="cat-view-item">
<div class="cat-view-content">
<!-- Titel als klickbarer Link -->
<h2 class="cat-view-item-title">
<a href="#" class="cat-view-link">
<?php echo (isset($article) && !empty($article->getTitle())) ? htmlspecialchars($article->getTitle()) : 'Kein Titel'; ?>
</a>
</h2>
<!-- Meta-Zeile für Autor und Likes --> <!-- LINKE SPALTE: SEITENLEISTE FÜR SORTIERUNG -->
<div class="cat-view-meta-row"> <aside class="cat-sidebar">
<p class="cat-view-author"> <div class="cat-sidebar-box">
von <span class="cat-view-author-name"><?php echo (isset($article) && !empty($article->getAuthor())) ? htmlspecialchars($article->getAuthor()) : 'Anonym'; ?></span> <h3 class="cat-sidebar-title">Sortierung</h3>
</p> <div class="cat-filter-group">
<span class="cat-view-likes"> <label class="cat-filter-option">
❤️ <?php echo (isset($article) && !empty($article->getLikes())) ? htmlspecialchars($article->getLikes()) : '0'; ?> <input type="radio" name="sort" value="alphabet" <?php echo ($currentSort === 'alphabet') ? 'checked' : ''; ?> onchange="this.form.submit();">
</span> Alphabetisch
</label>
<label class="cat-filter-option">
<input type="radio" name="sort" value="likes" <?php echo ($currentSort === 'likes') ? 'checked' : ''; ?> onchange="this.form.submit();">
Beliebtheit (Likes)
</label>
<label class="cat-filter-option">
<input type="radio" name="sort" value="newest" <?php echo ($currentSort === 'newest') ? 'checked' : ''; ?> onchange="this.form.submit();">
Neueste Beiträge
</label>
<label class="cat-filter-option">
<input type="radio" name="sort" value="oldest" <?php echo ($currentSort === 'oldest') ? 'checked' : ''; ?> onchange="this.form.submit();">
Älteste Beiträge
</label>
</div>
</div>
</aside>
<!-- RECHTE SPALTE: INHALT & PAGINATOR -->
<main class="cat-view-main">
<div class="cat-view-header">
<h1 class="cat-view-title">Kategorie: <?php echo (isset($category) && !empty($category)) ? htmlspecialchars($category) : 'Unbekannt'; ?></h1>
<p class="cat-view-meta-text">
<?php echo (isset($totalArticles)) ? $totalArticles : 0; ?> Treffer in dieser Kategorie
</p>
</div>
<!-- Beiträge -->
<div class="cat-view-list">
<?php if (isset($articles) && !empty($articles)): ?>
<?php foreach ($articles as $article): ?>
<div class="cat-view-item">
<div class="cat-view-content">
<h2 class="cat-view-item-title">
<a href="#" class="cat-view-link">
<?php echo (isset($article) && !empty($article->getTitle())) ? htmlspecialchars($article->getTitle()) : 'Kein Titel'; ?>
</a>
</h2>
<div class="cat-view-meta-row">
<p class="cat-view-author">
von <span class="cat-view-author-name"><?php echo (isset($article) && !empty($article->getAuthor())) ? htmlspecialchars($article->getAuthor()) : 'Anonym'; ?></span>
</p>
<span class="cat-view-likes">
❤️ <?php echo (isset($article) && !empty($article->getLikes())) ? htmlspecialchars($article->getLikes()) : '0'; ?>
</span>
</div>
<p style="margin: 0; color: #4a5568;">
<?php echo (isset($article) && !empty($article->getContent())) ? htmlspecialchars($article->getContent()) : 'Kein Inhalt'; ?>
</p>
</div>
<div class="cat-view-arrow">&rarr;</div>
</div> </div>
<?php endforeach; ?>
<?php else: ?>
<p class="cat-view-meta-text">Keine Artikel in dieser Kategorie gefunden.</p>
<?php endif; ?>
</div>
</div> <!-- Footer Paginator -->
<!-- Interaktiver Pfeil rechts --> <?php if (isset($totalPages) && $totalPages > 1): ?>
<div class="cat-view-arrow">&rarr;</div> <div class="cat-view-pagination-footer">
</div> <div></div>
<?php endforeach; ?> <div class="s-res-page-navigation">
<?php else: ?> <button type="button" class="s-res-page-btn" data-page="<?php echo $currentPage - 1; ?>" <?php echo ($currentPage <= 1) ? 'disabled' : ''; ?>>
<p class="cat-view-meta-text">Keine Artikel in dieser Kategorie gefunden.</p> &laquo;
<?php endif; ?>
</div>
<!-- Der Paginator -->
<?php if (isset($totalPages) && $totalPages > 1): ?>
<div class="cat-view-pagination-footer">
<div></div> <!-- Hält die Buttons auf der rechten Seite -->
<form id="search-form-id" action="index.php" method="GET" style="display: inline;">
<input type="hidden" name="pfad" value="showCategory">
<input type="hidden" name="category" value="<?php echo (isset($category) && !empty($category)) ? htmlspecialchars($category) : ''; ?>">
<input type="hidden" id="s-res-page-input" name="page" value="<?php echo (isset($page) && !empty($page)) ? $page : 1; ?>">
<!-- JS benötigt die Klasse 's-res-page-navigation' -->
<div class="s-res-page-navigation">
<?php $currentPage = $page ?? 1; ?>
<!-- Zurück-Button (Nutzt JS-Klasse 's-res-page-btn') -->
<button type="button" class="s-res-page-btn" data-page="<?php echo $currentPage - 1; ?>" <?php echo ($currentPage <= 1) ? 'disabled' : ''; ?>>
&laquo;
</button>
<!-- Seitenzahlen generieren -->
<?php for ($i = 1; $i <= $totalPages; $i++): ?>
<!-- Der aktive Button erhält zusätzlich die neue Klasse 'cat-active-btn' -->
<button type="button"
class="s-res-page-btn <?php echo ($i === $currentPage) ? 'cat-active-btn' : ''; ?>"
data-page="<?php echo $i; ?>"
<?php echo ($i === $currentPage) ? 'disabled' : ''; ?>>
<?php echo $i; ?>
</button> </button>
<?php endfor; ?>
<!-- Vor-Button --> <?php for ($i = 1; $i <= $totalPages; $i++): ?>
<button type="button" class="s-res-page-btn" data-page="<?php echo $currentPage + 1; ?>" <?php echo ($currentPage >= $totalPages) ? 'disabled' : ''; ?>> <button type="button"
&raquo; class="s-res-page-btn <?php echo ($i === $currentPage) ? 'cat-active-btn' : ''; ?>"
</button> data-page="<?php echo $i; ?>"
<?php echo ($i === $currentPage) ? 'disabled' : ''; ?>>
<?php echo $i; ?>
</button>
<?php endfor; ?>
<button type="button" class="s-res-page-btn" data-page="<?php echo $currentPage + 1; ?>" <?php echo ($currentPage >= $totalPages) ? 'disabled' : ''; ?>>
&raquo;
</button>
</div>
</div> </div>
</form> <?php endif; ?>
</div> </main>
<?php endif; ?>
</div> </div>
</form>
+61 -15
View File
@@ -1,21 +1,72 @@
/* --- NEUES LAYOUT FÜR KATEGORIEN --- */ /* --- ZWEISPALTIIGES GRID-LAYOUT --- */
.cat-view-container { .cat-view-container {
box-sizing: border-box; box-sizing: border-box;
max-width: 95%; max-width: 95%; /* 95% Monitorbreite wie das Original */
width: 95%; width: 95%;
margin: 2rem auto; margin: 2rem auto;
padding: 0 1rem; padding: 0 1rem;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
color: #212529; color: #212529;
line-height: 1.5; line-height: 1.5;
min-width: 0;
/* Grid für die Zweispaltigkeit */
display: grid;
grid-template-columns: 320px 1fr; /* 320px Sidebar, Rest für Content */
gap: 2.5rem;
} }
/* Verhindert Verzerren durch globale Styles im inneren Bereich */
.cat-view-container * { .cat-view-container * {
box-sizing: border-box; box-sizing: border-box;
} }
/* --- SEITENLEISTE (SORTIERUNG) --- */
.cat-sidebar {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.cat-sidebar-box {
background-color: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 8px;
padding: 1.25rem;
}
.cat-sidebar-title {
font-size: 1rem;
font-weight: 700;
color: #1a202c;
margin: 0 0 1rem 0;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.cat-filter-group {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.cat-filter-option {
display: flex;
align-items: center;
gap: 0.5rem;
cursor: pointer;
font-size: 0.95rem;
color: #4a5568;
}
.cat-filter-option input[type="radio"] {
margin: 0;
accent-color: #3182ce;
}
/* --- HAUPTINHALT --- */
.cat-view-main {
min-width: 0;
}
.cat-view-header { .cat-view-header {
margin-bottom: 2rem; margin-bottom: 2rem;
border-bottom: 2px solid #dee2e6; border-bottom: 2px solid #dee2e6;
@@ -35,14 +86,13 @@
margin: 0; margin: 0;
} }
/* --- LISTE DER BEITRÄGE --- */ /* --- BEITRÄGE LISTE --- */
.cat-view-list { .cat-view-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 1rem; gap: 1rem;
} }
/* Einzelne Beitrags-Box */
.cat-view-item { .cat-view-item {
background-color: #ffffff; background-color: #ffffff;
border: 1px solid #e2e8f0; border: 1px solid #e2e8f0;
@@ -73,7 +123,6 @@
.cat-view-link { .cat-view-link {
color: #3182ce; color: #3182ce;
text-decoration: none; text-decoration: none;
transition: color 0.2s ease;
} }
.cat-view-link:hover { .cat-view-link:hover {
@@ -81,7 +130,6 @@
color: #2b6cb0; color: #2b6cb0;
} }
/* Meta-Zeile für Autor & Likes */
.cat-view-meta-row { .cat-view-meta-row {
display: flex; display: flex;
gap: 15px; gap: 15px;
@@ -117,7 +165,7 @@
transform: translateX(3px); transform: translateX(3px);
} }
/* --- PAGINATOR FOOTER --- */ /* --- FOOTER PAGINATION --- */
.cat-view-pagination-footer { .cat-view-pagination-footer {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@@ -127,7 +175,6 @@
border-top: 1px solid #e2e8f0; border-top: 1px solid #e2e8f0;
} }
/* Styling der Buttons (Zugeordnet zu den JS-Klassen) */
.cat-view-pagination-footer .s-res-page-navigation { .cat-view-pagination-footer .s-res-page-navigation {
display: flex; display: flex;
gap: 0.25rem; gap: 0.25rem;
@@ -151,7 +198,6 @@
color: #2d3748; color: #2d3748;
} }
/* Aktiver Button-Zustand */
.cat-view-pagination-footer .cat-active-btn { .cat-view-pagination-footer .cat-active-btn {
background-color: #3182ce; background-color: #3182ce;
border-color: #3182ce; border-color: #3182ce;
@@ -166,12 +212,12 @@
cursor: not-allowed; cursor: not-allowed;
} }
/* Responsive Anpassungen unter 768px (Smartphones) */ /* RESPONSIVE ANPASSUNG (Unter 768px) */
@media (max-width: 768px) { @media (max-width: 768px) {
.cat-view-container { .cat-view-container {
grid-template-columns: 1fr; /* Stapelt Sidebar und Inhalt untereinander */
gap: 1.5rem;
margin: 1rem auto; margin: 1rem auto;
width: 100%;
max-width: 100%;
} }
.cat-view-pagination-footer { .cat-view-pagination-footer {
flex-direction: column; flex-direction: column;
+26 -5
View File
@@ -10,19 +10,40 @@ require_once 'php/validator/article-validator.php';
if (isset($_GET["category"]) && !empty($_GET["category"]) && articleCategoryValidator($_GET["category"])){ if (isset($_GET["category"]) && !empty($_GET["category"]) && articleCategoryValidator($_GET["category"])){
$category = $_GET["category"]; $category = $_GET["category"];
// Sortierung auslesen (Standard: alphabet)
$sortStyle = isset($_GET['sort']) ? trim($_GET['sort']) : 'alphabet';
// Aktuelle Seite auslesen
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1; $page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
if ($page < 1) { $page = 1; } if ($page < 1) { $page = 1; }
try { try {
$articleManager = ArticleManager::getInstance(); $articleManager = ArticleManager::getInstance();
$allArticles = $articleManager->getArticlesByCategory($category); $allArticles = $articleManager->getArticlesByCategory($category);
$totalArticles = count($allArticles);
// --- SORTIERUNG LOGIK ---
if ($sortStyle === 'alphabet') {
usort($allArticles, function($a, $b) {
return strcasecmp($a->getTitle(), $b->getTitle());
});
} elseif ($sortStyle === 'likes') {
usort($allArticles, function($a, $b) {
return $b->getLikes() <=> $a->getLikes(); // Absteigend nach Likes
});
} elseif ($sortStyle === 'newest') {
usort($allArticles, function($a, $b) {
return strtotime($b->getCreationDate()) <=> strtotime($a->getCreationDate()); // Neueste zuerst
});
} elseif ($sortStyle === 'oldest') {
usort($allArticles, function($a, $b) {
return strtotime($a->getCreationDate()) <=> strtotime($b->getCreationDate()); // Älteste zuerst
});
}
// Paginierung konfigurieren // Paginierung konfigurieren
$limit = 10; // Wie viele Artikel pro Seite? $limit = 10;
$totalArticles = count($allArticles);
$totalPages = ceil($totalArticles / $limit); $totalPages = ceil($totalArticles / $limit);
if ($page > $totalPages && $totalPages > 0) { $page = $totalPages; } if ($page > $totalPages && $totalPages > 0) { $page = $totalPages; }
$offset = ($page - 1) * $limit; $offset = ($page - 1) * $limit;
@@ -38,4 +59,4 @@ if (isset($_GET["category"]) && !empty($_GET["category"]) && articleCategoryVali
include_once "content/404.php"; include_once "content/404.php";
exit(); exit();
} }
?> ?>