diff --git a/public/admin.html b/public/admin.html index 7c554cf..4e34b1a 100644 --- a/public/admin.html +++ b/public/admin.html @@ -300,6 +300,10 @@

This week's list per kid

Word lists

+
+ + +

Test results

@@ -347,6 +351,9 @@

Flashcard Decks

+
+ +
@@ -437,6 +444,12 @@
+ + + diff --git a/public/admin.js b/public/admin.js index 013f5eb..2a27b08 100644 --- a/public/admin.js +++ b/public/admin.js @@ -1274,9 +1274,11 @@ async function renderGradebook(courseId) { // Spelling (word lists + weekly assignment + results) // ============================================================ +let cachedStudents = []; async function loadSpelling() { const [overview, lists] = await Promise.all([api('/api/overview'), api('/api/lists')]); cachedLists = lists; + cachedStudents = overview.students; renderAssignRows(overview.students); renderLists(lists); renderResults(overview.students); @@ -1287,16 +1289,20 @@ function renderAssignRows(students) { `` + cachedLists.map((l) => ``).join(''); $('#assign-rows').innerHTML = students.length - ? students - .map( - (s) => `
- ${esc(s.emoji)} - ${esc(s.name)} - 🌟 ${s.mastered} mastered - -
` - ) - .join('') + ? students.map((s) => { + const lp = s.listProgress; + const progressHtml = lp + ? `${lp.mastered}/${lp.total} mastered + + ` + : `No list assigned`; + return `
+ ${esc(s.emoji)} + ${esc(s.name)} + ${progressHtml} + +
`; + }).join('') : `

No kids yet.

`; document.querySelectorAll('[data-assign]').forEach((sel) => @@ -1334,28 +1340,51 @@ function renderGroupSections(groups, renderItem) { return html || '

None yet.

'; } -function renderLists(lists) { - const groups = groupByName(lists); +const hiddenLists = new Set(JSON.parse(localStorage.getItem('hiddenLists') || '[]')); +function saveHiddenLists() { localStorage.setItem('hiddenLists', JSON.stringify([...hiddenLists])); } + +function renderLists(lists, filterText = '') { + const q = filterText.toLowerCase(); + const visible = lists.filter((l) => !hiddenLists.has(l.id) && (!q || l.name.toLowerCase().includes(q))); + const hidden = lists.filter((l) => hiddenLists.has(l.id) && (!q || l.name.toLowerCase().includes(q))); + + const showHiddenBtn = $('#list-show-hidden'); + showHiddenBtn.hidden = hidden.length === 0; + showHiddenBtn.textContent = showHiddenBtn.dataset.showing === '1' + ? `Hide hidden (${hidden.length})` + : `Show hidden (${hidden.length})`; + + const displayList = showHiddenBtn.dataset.showing === '1' ? [...visible, ...hidden] : visible; + + const groups = groupByName(displayList); const groupNames = Object.keys(groups).filter((k) => k).sort(); $('#list-groups-datalist').innerHTML = groupNames.map((g) => `