Add HTMX migration for server-rendered tables and lazy loading

- Add HTMX CDN to layout
- Replace client-side table rendering (displayRatings, displayCourses)
  with server-rendered EJS partials via hx-get
- Add server-side course search with debounced hx-trigger
- Lazy-load player history and course layouts via htmx.ajax()
- Render rating chart via htmx:afterSwap with data attributes
- Add partial routes: ratings-table, course-table, player-history,
  course-layouts
This commit is contained in:
Samuel Enocsson
2026-02-19 08:29:56 +01:00
parent 20bbdbbfcf
commit 7e5fa6cbf1
12 changed files with 468 additions and 527 deletions
+30
View File
@@ -8,6 +8,36 @@ const { layoutEventCache, scrapeCourseDirectory, scrapeCourseLayouts, scrapeEven
// Request locking to prevent concurrent scrapes of the same resource
const activeScrapes = new Map();
router.get('/partials/course-table', async (req, res) => {
try {
const allCourses = await getAllCoursesFromDB();
const query = req.query.q || '';
let courses = allCourses;
if (query) {
const q = query.toLowerCase();
courses = allCourses.filter(c =>
c.name.toLowerCase().includes(q) || c.city.toLowerCase().includes(q)
);
}
res.render('../partials/course-table', { courses, query, total: allCourses.length });
} catch (error) {
res.status(500).send('<p>Error loading courses. Please try again.</p>');
}
});
router.get('/partials/course-layouts/:courseId', async (req, res) => {
try {
const { courseId } = req.params;
const layouts = await getLayoutsForCourse(courseId);
res.render('../partials/course-layouts', { layouts, courseId });
} catch (error) {
console.error('Error loading course layouts:', error.message);
res.status(500).send('<div class="no-layouts">Error loading layouts</div>');
}
});
router.get('/api/courses', async (req, res) => {
try {
const courses = await getAllCoursesFromDB();