Files
2026-09-14 22:38:47 -04:00

50 lines
2.6 KiB
JavaScript

import { filterUnits, subjectsFor, teacherGuidesFor } from './src/library.mjs';
const filters = document.querySelector('#subject-filters');
const grid = document.querySelector('#unit-grid');
const status = document.querySelector('#library-status');
let units = [];
let selectedSubject = 'All';
function resourceLink(material) {
return `<a class="resource-link" href="/api/pdf/${material.id}" target="_blank" rel="noopener">Open ${material.role}<span aria-hidden="true"> ↗</span></a>`;
}
function renderFilters() {
filters.innerHTML = subjectsFor(units).map((subject) => `<button class="filter ${subject === selectedSubject ? 'selected' : ''}" type="button" data-subject="${subject}">${subject}</button>`).join('');
filters.querySelectorAll('button').forEach((button) => button.addEventListener('click', () => {
selectedSubject = button.dataset.subject;
renderFilters();
renderUnits();
}));
}
function renderUnits() {
const filtered = filterUnits(units, selectedSubject);
status.textContent = `${filtered.length} ${selectedSubject === 'All' ? 'units' : selectedSubject + ' units'} shown`;
grid.innerHTML = filtered.map((unit) => {
const guides = teacherGuidesFor(unit);
const student = unit.materials.filter((material) => material.role === 'Student Reader');
const resources = [...guides, ...student].slice(0, 3).map(resourceLink).join('');
return `<article class="unit-card"><p class="unit-subject">${unit.subject}</p><h3>${unit.title.replace(/^Grade 3\s*/, '')}</h3><p class="material-count">${guides.length ? `${guides.length} teacher plan${guides.length === 1 ? '' : 's'}` : 'Teacher plan not identified'} · ${student.length} student resource${student.length === 1 ? '' : 's'}</p>${resources ? `<div class="resource-links">${resources}</div>` : '<p class="small">Open the original archive source for supporting materials.</p>'}<a class="source-link" href="${unit.source_url}" target="_blank" rel="noopener">Core Knowledge source ↗</a></article>`;
}).join('');
}
async function loadLibrary() {
try {
const response = await fetch('/api/catalog', { cache: 'no-store' });
if (!response.ok) throw new Error('catalog unavailable');
const catalog = await response.json();
units = catalog.units;
document.querySelector('#unit-count').textContent = catalog.unit_count;
document.querySelector('#guide-count').textContent = catalog.teacher_guide_count;
document.querySelector('#student-count').textContent = catalog.student_material_count;
renderFilters();
renderUnits();
} catch {
status.textContent = 'The local catalog could not load. Start the private Grade 3 demo server.';
}
}
loadLibrary();