fix: address mobile UI review findings (#16)

- Hide desktop .card-section on mobile, add .m-search-input with same
  HTMX attrs for mobile course search (fixes horizontal overflow)
- Remove dead layoutCount var and .m-layouts-pill block in course-cards
- Remove dead 768px breakpoints from players.css (table hidden at 880px)
- Move .mobile-section-head inside else-block for empty state in both
  ratings-cards and course-cards (fixes section head showing on empty)
- Add tabindex, role=button, aria-expanded, onkeydown to .m-card and
  .m-course-card; toggle aria-expanded in JS toggle functions
- Fix data-history attribute to use <%=  (HTML-escaped) instead of <%-
- Convert var to const/let in all new/changed JS blocks
This commit is contained in:
Samuel Enocsson
2026-05-22 21:27:05 +02:00
parent cc9d8eb4cd
commit b51c47dc4c
7 changed files with 88 additions and 57 deletions
+7 -9
View File
@@ -3,27 +3,25 @@ var _query = (typeof query !== 'undefined') ? query : null;
var _total = (typeof total !== 'undefined') ? total : courses.length;
%>
<% if (courses.length === 0) { %>
<p style="text-align: center; color: var(--ink-3); padding: 40px 0;">No courses found.</p>
<% } else { %>
<div class="mobile-section-head">
<span class="kicker">Showing <%= courses.length %> of <%= _total %></span>
<a href="/courses">View all &rarr;</a>
</div>
<% if (courses.length === 0) { %>
<p style="text-align: center; color: var(--ink-3); padding: 40px 0;">No courses found.</p>
<% } else { %>
<div class="mobile-list">
<% courses.forEach(function(course) {
var lastUpdated = new Date(course.last_updated).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' });
var layoutCount = course.layoutCount || 0;
%>
<div class="m-course-card" id="m-course-<%= course.id %>" onclick="toggleMobileCourseLayouts(<%= course.id %>)">
<div class="m-course-card" id="m-course-<%= course.id %>"
tabindex="0" role="button" aria-expanded="false" aria-label="Expand course details"
onclick="toggleMobileCourseLayouts(<%= course.id %>)"
onkeydown="if(event.key==='Enter'||event.key===' '){event.preventDefault();toggleMobileCourseLayouts(<%= course.id %>);}">
<div class="m-course-card__head">
<div class="m-course-card__name-stack">
<div class="m-course-name-row">
<span class="m-course-name"><%= course.name %></span>
<% if (layoutCount > 0) { %>
<span class="m-layouts-pill"><%= layoutCount %> layout<%= layoutCount !== 1 ? 's' : '' %></span>
<% } %>
</div>
<div class="m-course-card__meta"><%= course.city %> &middot; <%= lastUpdated %></div>
</div>
+8 -6
View File
@@ -32,14 +32,13 @@ function renderSparkline(values, opts) {
}
%>
<% if (ratings.length === 0) { %>
<p style="text-align: center; color: var(--ink-3); padding: 40px 0;">No players tracked yet.</p>
<% } else { %>
<div class="mobile-section-head">
<span class="kicker">TRACKED PLAYERS &middot; <%= ratings.length %></span>
<button id="trendchart-toggle-mobile" class="pill-button" type="button" aria-pressed="false">Trend chart</button>
</div>
<% if (ratings.length === 0) { %>
<p style="text-align: center; color: var(--ink-3); padding: 40px 0;">No players tracked yet.</p>
<% } else { %>
<div class="mobile-list">
<% ratings.forEach(function(player, index) {
var sparkSvg = renderSparkline(player.monthlyHistory || [], { w: 70, h: 26 });
@@ -56,7 +55,10 @@ function renderSparkline(values, opts) {
var predGlyph = (predIsNull || player.deltaPredicted === 0) ? '' : (player.deltaPredicted > 0 ? '▲' : '▼');
var predNum = predIsNull ? '—' : (player.deltaPredicted > 0 ? '+' + player.deltaPredicted : String(player.deltaPredicted));
%>
<div class="m-card" id="m-card-<%= player.pdgaNumber %>" onclick="toggleMobilePlayerCard(<%= player.pdgaNumber %>)">
<div class="m-card" id="m-card-<%= player.pdgaNumber %>"
tabindex="0" role="button" aria-expanded="false" aria-label="Expand player details"
onclick="toggleMobilePlayerCard(<%= player.pdgaNumber %>)"
onkeydown="if(event.key==='Enter'||event.key===' '){event.preventDefault();toggleMobilePlayerCard(<%= player.pdgaNumber %>);}">
<div class="m-card__head">
<div class="m-rank-chip<%= isFirst ? ' m-rank-chip--first' : '' %>"><%= rank %></div>
<div class="m-card__name-stack">
@@ -88,7 +90,7 @@ function renderSparkline(values, opts) {
<% if (player.ratingHistory && player.ratingHistory.length > 0) { %>
<div class="player-chart m-chart"
data-variant="mobile"
data-history='<%- JSON.stringify(player.ratingHistory) %>'>
data-history="<%= JSON.stringify(player.ratingHistory) %>">
</div>
<% } %>
<dl class="m-detail-grid">