Feature: Suchfeld in Routen, Events und Places
Alle drei Seiten haben jetzt ein debounced Suchfeld (300ms) mit Lupe-Icon über der Liste. Die Suche filtert clientseitig: - Routen: Name, Beschreibung, Username (bereits vorhandener State verbessert) - Events: Titel, Ort, Beschreibung - Places: Name, Adresse, Typ Leerer Zustand zeigt passendes UI.emptyState() mit Suchbegriff. SW by-v209, APP_VER 178.
This commit is contained in:
parent
5acfa9d8f6
commit
6581a9a88c
3 changed files with 90 additions and 18 deletions
|
|
@ -35,6 +35,7 @@ window.Page_events = (() => {
|
|||
let _events = [];
|
||||
let _filter = 'alle';
|
||||
let _quellFilter = 'alle'; // 'alle' | 'vdh' | 'nutzer'
|
||||
let _search = '';
|
||||
let _view = 'liste'; // liste | karte
|
||||
let _map = null;
|
||||
let _markers = [];
|
||||
|
|
@ -78,6 +79,12 @@ window.Page_events = (() => {
|
|||
${_state.user ? `<button class="btn btn-primary btn-sm" id="ev-new-btn">${UI.icon('plus')} Event</button>` : ''}
|
||||
</div>
|
||||
|
||||
<div class="diary-search-wrap" style="margin:var(--space-2) var(--space-3) 0" id="ev-search-wrap">
|
||||
<svg class="ph-icon diary-search-icon" aria-hidden="true"><use href="/icons/phosphor.svg#magnifying-glass"></use></svg>
|
||||
<input type="search" class="diary-search-input" id="ev-search"
|
||||
placeholder="Events durchsuchen…" autocomplete="off">
|
||||
</div>
|
||||
|
||||
<div class="events-filter-bar by-tabs" id="ev-filter-bar">
|
||||
${TYPEN.map(t => `
|
||||
<button class="by-tab ${t.id === 'alle' ? 'active' : ''}" data-ev-typ="${t.id}">
|
||||
|
|
@ -99,6 +106,16 @@ window.Page_events = (() => {
|
|||
`;
|
||||
|
||||
_container.addEventListener('click', _onClick);
|
||||
|
||||
// Suche mit Debounce
|
||||
let _searchTimer = null;
|
||||
document.getElementById('ev-search')?.addEventListener('input', e => {
|
||||
clearTimeout(_searchTimer);
|
||||
_searchTimer = setTimeout(() => {
|
||||
_search = e.target.value.trim().toLowerCase();
|
||||
if (_view === 'karte') { _renderMap(_filtered()); } else { _renderList(); }
|
||||
}, 300);
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
|
@ -124,6 +141,14 @@ window.Page_events = (() => {
|
|||
if (_quellFilter !== 'alle') {
|
||||
evs = evs.filter(e => (e.quelle || 'nutzer') === _quellFilter);
|
||||
}
|
||||
if (_search) {
|
||||
const q = _search;
|
||||
evs = evs.filter(e =>
|
||||
(e.titel || '').toLowerCase().includes(q) ||
|
||||
(e.ort_name || '').toLowerCase().includes(q) ||
|
||||
(e.beschreibung|| '').toLowerCase().includes(q)
|
||||
);
|
||||
}
|
||||
return evs;
|
||||
}
|
||||
|
||||
|
|
@ -138,8 +163,10 @@ window.Page_events = (() => {
|
|||
if (!filtered.length) {
|
||||
listEl.innerHTML = UI.emptyState({
|
||||
icon: UI.icon('calendar-blank'),
|
||||
title: 'Keine Events in der Nähe',
|
||||
text: 'Hier erscheinen Hundeveranstaltungen, Treffen und Aktivitäten in deiner Umgebung.',
|
||||
title: _search ? 'Keine Events gefunden' : 'Keine Events in der Nähe',
|
||||
text: _search
|
||||
? `Keine Events passen zu „${UI.escape(_search)}".`
|
||||
: 'Hier erscheinen Hundeveranstaltungen, Treffen und Aktivitäten in deiner Umgebung.',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue