Wiki pagination — 9 cards/page (3 rows), counter X/27, topic filter pills, prev/next

- wikiPerPage = 9 (3 masonry rows × 3 cols), wikiCurrentPage state
- wikiFilteredData holds sorted/filtered list; renderWikiPage slices it
- Topic filter pills below search bar, rendered from unique topics in data
- searchWiki now works with pagination/filters, resets to page 1
- Counter shows '9/27' style, pagination shows Zurück/Weiter with page info
- Language toggle re-renders wiki topics + page
- New CSS: .wiki-topics, .wiki-topic-filter (pill style), .wiki-footer, .wiki-page-btn
This commit is contained in:
Kato
2026-09-05 19:51:06 +00:00
parent 34d9b0b1e2
commit 113ca75502
3 changed files with 198 additions and 20 deletions
+114 -20
View File
@@ -273,6 +273,10 @@ function setLanguage(lang) {
b.classList.toggle('active', b.dataset.lang === lang);
});
renderCalendar();
if (wikiData.length) {
renderWikiTopics();
renderWikiPage();
}
}
function isDE() {
@@ -730,6 +734,20 @@ function getTopicColor(topic) {
// ========================================
let wikiData = [];
let wikiCurrentPage = 1;
let wikiPerPage = 9;
let wikiFilteredData = [];
let wikiActiveTopic = '';
// Get unique topics with counts from the full wiki data
function getWikiTopics(data) {
const map = {};
data.forEach(item => {
const t = currentLang === 'en' && item.topic_en ? item.topic_en : (item.topic || 'Unknown');
map[t] = (map[t] || 0) + 1;
});
return Object.entries(map).sort();
}
async function loadWiki() {
try {
@@ -739,17 +757,94 @@ async function loadWiki() {
if (result.data && Array.isArray(result.data)) {
wikiData = result.data;
renderWikiCards(wikiData);
// Wiki count will be loaded from community webhook
wikiFilteredData = [...result.data].sort((a, b) => new Date(b.updatedAt || b.createdAt) - new Date(a.updatedAt || a.createdAt));
wikiCurrentPage = 1;
wikiActiveTopic = '';
renderWikiTopics();
renderWikiPage();
} else {
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Keine Wiki-Daten' : 'No wiki data') + '</p>';
const c = document.getElementById('wiki-counter'); if (c) c.innerHTML = '';
const p = document.getElementById('wiki-pagination'); if (p) p.innerHTML = '';
}
} catch (error) {
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Fehler beim Laden' : 'Error loading') + '</p>';
}
}
function renderWikiTopics() {
const container = document.getElementById('wiki-topics');
if (!container) return;
const topics = getWikiTopics(wikiData);
let html = '<button class="wiki-topic-filter' + (wikiActiveTopic === '' ? ' active' : '') + '" onclick="filterWikiByTopic(\'\')">' +
(isDE() ? 'Alle' : 'All') + ' <span class="wiki-filter-count">' + wikiData.length + '</span></button>';
topics.forEach(([topic, count]) => {
const esc = escapeHtml(topic).replace(/'/g, "\\'");
html += '<button class="wiki-topic-filter' + (topic === wikiActiveTopic ? ' active' : '') + '" onclick="filterWikiByTopic(\'' + esc + '\')">' +
escapeHtml(topic) + ' <span class="wiki-filter-count">' + count + '</span></button>';
});
container.innerHTML = html;
}
function filterWikiByTopic(topic) {
wikiActiveTopic = topic;
if (!topic) {
wikiFilteredData = [...wikiData].sort((a, b) => new Date(b.updatedAt || b.createdAt) - new Date(a.updatedAt || a.createdAt));
} else {
wikiFilteredData = [...wikiData].filter(item => {
const t = currentLang === 'en' && item.topic_en ? item.topic_en : (item.topic || '');
return t === topic;
}).sort((a, b) => new Date(b.updatedAt || b.createdAt) - new Date(a.updatedAt || a.createdAt));
}
wikiCurrentPage = 1;
renderWikiTopics();
renderWikiPage();
}
function renderWikiPage() {
const total = wikiFilteredData.length;
const totalPages = Math.max(1, Math.ceil(total / wikiPerPage));
if (wikiCurrentPage > totalPages) wikiCurrentPage = totalPages;
const start = (wikiCurrentPage - 1) * wikiPerPage;
const pageData = wikiFilteredData.slice(start, start + wikiPerPage);
renderWikiCards(pageData);
renderWikiCounter(start, total);
renderWikiPagination(totalPages);
}
function renderWikiCounter(start, total) {
const el = document.getElementById('wiki-counter');
if (!el) return;
if (total === 0 || start >= total) { el.innerHTML = ''; return; }
const shown = Math.min(wikiPerPage, total - start);
el.textContent = start + shown + '/' + total;
}
function renderWikiPagination(totalPages) {
const el = document.getElementById('wiki-pagination');
if (!el) return;
if (totalPages <= 1) { el.innerHTML = ''; return; }
el.innerHTML =
'<button class="wiki-page-btn" onclick="wikiGoPage(' + (wikiCurrentPage - 1) + ')"' + (wikiCurrentPage <= 1 ? ' disabled' : '') + '>' +
'<span class="hide-de">Zurück</span><span class="hide-en">Previous</span></button>' +
'<span class="wiki-page-info">' + wikiCurrentPage + '/' + totalPages + '</span>' +
'<button class="wiki-page-btn" onclick="wikiGoPage(' + (wikiCurrentPage + 1) + ')"' + (wikiCurrentPage >= totalPages ? ' disabled' : '') + '>' +
'<span class="hide-de">Weiter</span><span class="hide-en">Next</span></button>';
}
function wikiGoPage(page) {
const total = wikiFilteredData.length;
const totalPages = Math.max(1, Math.ceil(total / wikiPerPage));
if (page < 1 || page > totalPages) return;
wikiCurrentPage = page;
const start = (wikiCurrentPage - 1) * wikiPerPage;
renderWikiCards(wikiFilteredData.slice(start, start + wikiPerPage));
renderWikiCounter(start, total);
renderWikiPagination(totalPages);
const section = document.querySelector('#wiki');
if (section) section.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
function renderWikiCards(data) {
const grid = document.getElementById('wiki-grid');
grid.innerHTML = '';
@@ -759,9 +854,7 @@ function renderWikiCards(data) {
return;
}
const sorted = [...data].sort((a, b) => new Date(b.updatedAt || b.createdAt) - new Date(a.updatedAt || a.createdAt));
sorted.forEach((item, idx) => {
data.forEach((item, idx) => {
const card = document.createElement('div');
card.className = 'wiki-card-new stagger-' + (idx % 4 + 1);
card.setAttribute('role', 'button');
@@ -769,7 +862,6 @@ function renderWikiCards(data) {
const topic = currentLang === 'en' && item.topic_en ? item.topic_en : (item.topic || 'Unknown');
const topicColor = getTopicColor(topic);
// Feed topic accent into CSS custom properties (top bar + hover border)
card.style.setProperty('--topic-accent', topicColor.border);
const subtopic = currentLang === 'en' && item.subtopic_en ? item.subtopic_en : (item.subtopic || '');
@@ -839,20 +931,22 @@ function openWikiModalSingle(item) {
}
function searchWiki(term) {
if (!term.trim()) {
renderWikiCards(wikiData);
return;
const t = term.toLowerCase().trim();
if (!t) {
wikiActiveTopic = '';
wikiFilteredData = [...wikiData].sort((a, b) => new Date(b.updatedAt || b.createdAt) - new Date(a.updatedAt || a.createdAt));
} else {
wikiActiveTopic = '';
wikiFilteredData = wikiData.filter(item => {
const text = ((item.topic_en && currentLang === 'en') ? item.topic_en : (item.topic || '')) + ' ' +
((item.subtopic_en && currentLang === 'en') ? item.subtopic_en : (item.subtopic || '')) + ' ' +
((item.wiki_en && currentLang === 'en') ? item.wiki_en : (item.wiki || ''));
return text.toLowerCase().includes(t);
}).sort((a, b) => new Date(b.updatedAt || b.createdAt) - new Date(a.updatedAt || a.createdAt));
}
const t = term.toLowerCase();
const filtered = wikiData.filter(item => {
const topic = ((item.topic_en && currentLang === 'en') ? item.topic_en : (item.topic || '')) +
' ' + ((item.subtopic_en && currentLang === 'en') ? item.subtopic_en : (item.subtopic || '')) +
' ' + ((item.wiki_en && currentLang === 'en') ? item.wiki_en : (item.wiki || ''));
return topic.toLowerCase().includes(t);
});
renderWikiCards(filtered);
renderWikiTopics();
wikiCurrentPage = 1;
renderWikiPage();
}
function getTopicColor(topic) {