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:
@@ -1054,6 +1054,85 @@ body[data-lang="en"] .hide-de { display: none !important; }
|
|||||||
.rank-badge.rank-expert { background: #fff3e0; color: #e65100; }
|
.rank-badge.rank-expert { background: #fff3e0; color: #e65100; }
|
||||||
.rank-badge.rank-legend { background: #fce4ec; color: #c62828; }
|
.rank-badge.rank-legend { background: #fce4ec; color: #c62828; }
|
||||||
|
|
||||||
|
/* ========================================
|
||||||
|
WIKI TOPICS — filter pills
|
||||||
|
======================================== */
|
||||||
|
.wiki-topics {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 6px;
|
||||||
|
margin: 12px 0 20px;
|
||||||
|
}
|
||||||
|
.wiki-topic-filter {
|
||||||
|
background: #f0f2f5;
|
||||||
|
border: none;
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 5px 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #1c1e21;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s, color 0.2s;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.wiki-topic-filter:hover {
|
||||||
|
background: #e4e6eb;
|
||||||
|
}
|
||||||
|
.wiki-topic-filter.active {
|
||||||
|
background: #1877f2;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.wiki-filter-count {
|
||||||
|
font-size: 11px;
|
||||||
|
opacity: 0.7;
|
||||||
|
margin-left: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================================
|
||||||
|
WIKI FOOTER — counter + pagination
|
||||||
|
======================================== */
|
||||||
|
.wiki-footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 16px;
|
||||||
|
margin-top: 24px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.wiki-counter {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #65676b;
|
||||||
|
}
|
||||||
|
.wiki-pagination {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.wiki-page-btn {
|
||||||
|
background: #f0f2f5;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 6px 14px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #1c1e21;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
.wiki-page-btn:hover:not(:disabled) {
|
||||||
|
background: #e4e6eb;
|
||||||
|
}
|
||||||
|
.wiki-page-btn:disabled {
|
||||||
|
opacity: 0.4;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.wiki-page-info {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #65676b;
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================================
|
/* ========================================
|
||||||
WIKI CARDS
|
WIKI CARDS
|
||||||
======================================== */
|
======================================== */
|
||||||
|
|||||||
@@ -436,12 +436,17 @@
|
|||||||
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
<svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
||||||
<input type="text" id="wiki-search" class="search-input" placeholder="Wiki durchsuchen..." />
|
<input type="text" id="wiki-search" class="search-input" placeholder="Wiki durchsuchen..." />
|
||||||
</div>
|
</div>
|
||||||
|
<div class="wiki-topics" id="wiki-topics"></div>
|
||||||
<div class="wiki-grid" id="wiki-grid">
|
<div class="wiki-grid" id="wiki-grid">
|
||||||
<p class="loading-text">
|
<p class="loading-text">
|
||||||
<span class="hide-de">Lade Wiki...</span>
|
<span class="hide-de">Lade Wiki...</span>
|
||||||
<span class="hide-en">Loading wiki...</span>
|
<span class="hide-en">Loading wiki...</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="wiki-footer" id="wiki-footer">
|
||||||
|
<div class="wiki-counter" id="wiki-counter"></div>
|
||||||
|
<div class="wiki-pagination" id="wiki-pagination"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
+114
-20
@@ -273,6 +273,10 @@ function setLanguage(lang) {
|
|||||||
b.classList.toggle('active', b.dataset.lang === lang);
|
b.classList.toggle('active', b.dataset.lang === lang);
|
||||||
});
|
});
|
||||||
renderCalendar();
|
renderCalendar();
|
||||||
|
if (wikiData.length) {
|
||||||
|
renderWikiTopics();
|
||||||
|
renderWikiPage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDE() {
|
function isDE() {
|
||||||
@@ -730,6 +734,20 @@ function getTopicColor(topic) {
|
|||||||
|
|
||||||
// ========================================
|
// ========================================
|
||||||
let wikiData = [];
|
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() {
|
async function loadWiki() {
|
||||||
try {
|
try {
|
||||||
@@ -739,17 +757,94 @@ async function loadWiki() {
|
|||||||
|
|
||||||
if (result.data && Array.isArray(result.data)) {
|
if (result.data && Array.isArray(result.data)) {
|
||||||
wikiData = result.data;
|
wikiData = result.data;
|
||||||
renderWikiCards(wikiData);
|
wikiFilteredData = [...result.data].sort((a, b) => new Date(b.updatedAt || b.createdAt) - new Date(a.updatedAt || a.createdAt));
|
||||||
|
wikiCurrentPage = 1;
|
||||||
// Wiki count will be loaded from community webhook
|
wikiActiveTopic = '';
|
||||||
|
renderWikiTopics();
|
||||||
|
renderWikiPage();
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Keine Wiki-Daten' : 'No wiki data') + '</p>';
|
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) {
|
} catch (error) {
|
||||||
document.getElementById('wiki-grid').innerHTML = '<p class="loading-text">' + (isDE() ? 'Fehler beim Laden' : 'Error loading') + '</p>';
|
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) {
|
function renderWikiCards(data) {
|
||||||
const grid = document.getElementById('wiki-grid');
|
const grid = document.getElementById('wiki-grid');
|
||||||
grid.innerHTML = '';
|
grid.innerHTML = '';
|
||||||
@@ -759,9 +854,7 @@ function renderWikiCards(data) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sorted = [...data].sort((a, b) => new Date(b.updatedAt || b.createdAt) - new Date(a.updatedAt || a.createdAt));
|
data.forEach((item, idx) => {
|
||||||
|
|
||||||
sorted.forEach((item, idx) => {
|
|
||||||
const card = document.createElement('div');
|
const card = document.createElement('div');
|
||||||
card.className = 'wiki-card-new stagger-' + (idx % 4 + 1);
|
card.className = 'wiki-card-new stagger-' + (idx % 4 + 1);
|
||||||
card.setAttribute('role', 'button');
|
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 topic = currentLang === 'en' && item.topic_en ? item.topic_en : (item.topic || 'Unknown');
|
||||||
const topicColor = getTopicColor(topic);
|
const topicColor = getTopicColor(topic);
|
||||||
// Feed topic accent into CSS custom properties (top bar + hover border)
|
|
||||||
card.style.setProperty('--topic-accent', topicColor.border);
|
card.style.setProperty('--topic-accent', topicColor.border);
|
||||||
|
|
||||||
const subtopic = currentLang === 'en' && item.subtopic_en ? item.subtopic_en : (item.subtopic || '');
|
const subtopic = currentLang === 'en' && item.subtopic_en ? item.subtopic_en : (item.subtopic || '');
|
||||||
@@ -839,20 +931,22 @@ function openWikiModalSingle(item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function searchWiki(term) {
|
function searchWiki(term) {
|
||||||
if (!term.trim()) {
|
const t = term.toLowerCase().trim();
|
||||||
renderWikiCards(wikiData);
|
if (!t) {
|
||||||
return;
|
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));
|
||||||
}
|
}
|
||||||
|
renderWikiTopics();
|
||||||
const t = term.toLowerCase();
|
wikiCurrentPage = 1;
|
||||||
const filtered = wikiData.filter(item => {
|
renderWikiPage();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTopicColor(topic) {
|
function getTopicColor(topic) {
|
||||||
|
|||||||
Reference in New Issue
Block a user