diff --git a/public/js/learningHub.js b/public/js/learningHub.js index 8fe7867..15e7f78 100644 --- a/public/js/learningHub.js +++ b/public/js/learningHub.js @@ -13,7 +13,7 @@ // ── Load when tab activated ──────────────────────────────── document.addEventListener('tabChanged', function(e) { if (e.detail && e.detail.tab === 'learning') { - if (!loaded) { loadFeed(); loadCategories(); loaded = true; } + if (!loaded) { loadFeed(); loadCategories(); loaded = true; wireSearch(); } } // Load CMS when Content Manager tab is opened if (e.detail && e.detail.tab === 'cms') { @@ -134,15 +134,20 @@ if (rmOpt) { var row = rmOpt.closest('.lh-option-row'); if (row) row.remove(); return; } }); - // Search - var searchTimeout = null; - var searchEl = document.getElementById('lh-search'); - if (searchEl) { + // wireSearch() called after component is in DOM + var _searchTimeout = null; + function wireSearch() { + var searchEl = document.getElementById('lh-search'); + if (!searchEl || searchEl._wired) return; + searchEl._wired = true; searchEl.addEventListener('input', function() { - clearTimeout(searchTimeout); + clearTimeout(_searchTimeout); var q = searchEl.value.trim(); if (!q) { loadFeed(); return; } - searchTimeout = setTimeout(function() { searchContent(q); }, 300); + _searchTimeout = setTimeout(function() { searchContent(q); }, 350); + }); + searchEl.addEventListener('keydown', function(e) { + if (e.key === 'Escape') { searchEl.value = ''; loadFeed(); } }); } @@ -198,13 +203,46 @@ var feedEl = document.getElementById('lh-feed'); if (!feedEl) return; showFeed(); + feedEl.innerHTML = + '
Search failed
'; return; } + var header = 'Search error
'; }); } function renderFeed(items, feedEl) { @@ -250,26 +288,28 @@ function showFeed() { currentView = 'feed'; - var feedEl = document.getElementById('lh-feed'); - var viewerEl = document.getElementById('lh-viewer'); - var catsEl = document.getElementById('lh-categories'); - var searchWrap = document.getElementById('lh-search'); - if (feedEl) feedEl.classList.remove('hidden'); - if (viewerEl) viewerEl.classList.add('hidden'); - if (catsEl) catsEl.classList.remove('hidden'); - if (searchWrap) searchWrap.closest('.card').classList.remove('hidden'); + var feedEl = document.getElementById('lh-feed'); + var viewerEl = document.getElementById('lh-viewer'); + var catsEl = document.getElementById('lh-categories'); + var searchEl = document.getElementById('lh-search'); + // Use style.display — classList.add('hidden') is overridden by .lh-feed{display:flex} + // and .lh-category-bar{display:flex} which are defined later in CSS + if (feedEl) feedEl.style.display = 'flex'; + if (viewerEl) viewerEl.style.display = 'none'; + if (catsEl) catsEl.style.display = 'flex'; + if (searchEl) { var sc = searchEl.closest('.card'); if (sc) sc.style.display = ''; } } function showViewer(item) { currentView = 'viewer'; - var feedEl = document.getElementById('lh-feed'); - var viewerEl = document.getElementById('lh-viewer'); - var catsEl = document.getElementById('lh-categories'); - var searchWrap = document.getElementById('lh-search'); - if (feedEl) feedEl.classList.add('hidden'); - if (viewerEl) viewerEl.classList.remove('hidden'); - if (catsEl) catsEl.classList.add('hidden'); - if (searchWrap) searchWrap.closest('.card').classList.add('hidden'); + var feedEl = document.getElementById('lh-feed'); + var viewerEl = document.getElementById('lh-viewer'); + var catsEl = document.getElementById('lh-categories'); + var searchEl = document.getElementById('lh-search'); + if (feedEl) feedEl.style.display = 'none'; + if (viewerEl) viewerEl.style.display = 'block'; + if (catsEl) catsEl.style.display = 'none'; + if (searchEl) { var sc = searchEl.closest('.card'); if (sc) sc.style.display = 'none'; } var titleEl = document.getElementById('lh-viewer-title'); var metaEl = document.getElementById('lh-viewer-meta');