Files
pdga-rating/views/partials/course-table.ejs
T
Samuel Enocsson 4bbf6d9728 feat: redesign Courses page with tabs + restore Tjing import (#8)
- Restore src/scrapers/tjing.js with AbortController timeout (8s),
  error-object returns, and verbatim GraphQL queries
- Add getOrCreateLayout() to src/models/course.js
- New /api/tjing/search and /api/tjing/import/:tjingId routes;
  course-table route now includes layoutCount/activeLayoutCount via
  LEFT JOIN aggregation
- Rewrite courses.ejs: action-card with Find/Import tabs, results bar,
  HTMX course-table-region with body:refresh trigger
- Rewrite course-table.ejs: CSS-grid div structure replacing <table>,
  lazy-load expanded layouts via JS htmx.ajax
- Rewrite course-layouts.ejs: layout-card chips with rating tier colouring,
  collapsible inactive layouts section
- Rewrite courses.js: tab switching, live client-side filter, count display,
  Tjing search/import using DOM API (no innerHTML with untrusted data)
- Rewrite courses.css: full new design system using project tokens
2026-05-25 09:39:44 +02:00

40 lines
2.0 KiB
Plaintext

<% if (!courses || courses.length === 0) { %>
<p style="text-align: center; color: var(--ink-3); padding: 40px 0;">No courses found. Use "Import from Tjing" or scrape courses from PDGA.</p>
<% } else { %>
<div class="course-grid" data-total-count="<%= courses.length %>">
<% courses.forEach(function(course) {
var layoutCount = course.layoutCount || 0;
var activeLayoutCount = course.activeLayoutCount || 0;
%>
<div class="course-row expandable-row" data-course-id="<%= course.id %>" data-course-name="<%= (course.name || '').toLowerCase().replace(/"/g, '&quot;') %>" data-course-city="<%= (course.city || '').toLowerCase().replace(/"/g, '&quot;') %>" onclick="toggleCourseLayouts(<%= course.id %>)">
<div class="course-cell">
<span class="course-name"><%= course.name %></span>
<span class="course-meta">
<% if (layoutCount > 0) { %>
<% if (activeLayoutCount !== layoutCount) { %>
<%= layoutCount %> layouts &middot; <%= activeLayoutCount %> active
<% } else { %>
<%= layoutCount %> layouts
<% } %>
<% } else { %>
No layouts
<% } %>
</span>
</div>
<div class="course-city"><%= course.city || '—' %></div>
<div class="course-updated"><%= course.last_updated ? new Date(course.last_updated).toISOString().slice(0,10) : '—' %></div>
<div class="course-actions">
<button class="icon-btn" onclick="event.stopPropagation(); scrapeLayouts(<%= course.id %>, this)" title="Refresh layouts">&#x21BB;</button>
<button class="icon-btn icon-chev" onclick="event.stopPropagation(); toggleCourseLayouts(<%= course.id %>)" title="Expand"><i>&#9662;</i></button>
</div>
</div>
<div class="expanded-content" id="course-layouts-<%= course.id %>">
<div class="expanded-cell">
<div class="loading">Loading layouts…</div>
</div>
</div>
<% }); %>
</div>
<%- include('course-cards', { courses: courses }) %>
<% } %>