openvibers/openvibe.shoes Commits

Page links: the ends are muted text, not faded links (#35)

OP OpenVibers committed 11 days ago · 13ad6aa24d · 3 files, +12 −2

Changes

ddiff --git a/public/css/shoes.css b/public/css/shoes.css
iindex b296b3d..ceda1ee 100644
---- a/public/css/shoes.css
++++ b/public/css/shoes.css
@@@ -90,7 +90,8 @@
.sh-list { padding-left: 20px; line-height: 1.65; color: var(--text-secondary, #96a7c2); }
.sh-code { overflow-x: auto; padding: 12px 14px; border-radius: 12px; background: var(--bg-secondary, #101828); border: 1px solid var(--border, rgba(255,255,255,.1)); }
.sh-page-nav { display: flex; gap: 14px; align-items: center; justify-content: center; margin: 24px 0; }
--.sh-page-nav .is-off { opacity: .4; pointer-events: none; }
++/* The end of the list is plain text in the muted colour (AA on every theme), not a faded link to no page. */
++.sh-page-nav .is-off { color: var(--text-muted, #7386a3); }
.crumbs { font-size: 13px; color: var(--text-muted, #7386a3); margin: 10px 0 0; }
.crumbs a { color: inherit; }
@media (max-width: 900px) { .sh-search { grid-template-columns: 1fr 1fr; } }
ddiff --git a/server/views/index.js b/server/views/index.js
iindex 9b4dc46..b632742 100644
---- a/server/views/index.js
++++ b/server/views/index.js
@@@ -307,7 +307,7 @@ function shoesIndex({ models = [], facets = {}, query = {}, page = 1, total = 0,
<header class="sh-page-h"><p class="sh-kicker">Every shoe</p><h1>Search the catalogue</h1><p class="sh-lede">${total} model${total === 1 ? '' : 's'}${query.q ? ` for “${esc(query.q)}”` : ''}, each with every store's all-in price, the time it was checked and a stale flag.${facets.checked_at ? ` The catalogue was last read ${esc(checked(facets.checked_at, now))}.` : ''}</p></header>
${searchForm({ q: query.q || '', facets, values: query })}
${models.length ? `<ul class="sh-grid">${models.map((m) => `<li>${modelCard(m)}</li>`).join('')}</ul>` : `<div class="sh-empty"><h2>No shoe matches yet</h2><p>Try a brand, a model or a shorter word. The catalogue is filled by the Deals job; a model appears the first time a source names it.</p><p><a class="sh-btn" href="/shoes">Clear the filters</a></p></div>`}
--${pages > 1 ? `<nav class="sh-page-nav" aria-label="Pages"><a${page <= 1 ? ' class="is-off"' : ''} href="/shoes?${esc(qs(page - 1))}">← Previous</a><span>Page ${page} of ${pages}</span><a${page >= pages ? ' class="is-off"' : ''} href="/shoes?${esc(qs(page + 1))}">Next →</a></nav>` : ''}
++${pages > 1 ? `<nav class="sh-page-nav" aria-label="Pages">${page <= 1 ? '<span class="is-off" aria-disabled="true">← Previous</span>' : `<a href="/shoes?${esc(qs(page - 1))}" rel="prev">← Previous</a>`}<span>Page ${page} of ${pages}</span>${page >= pages ? '<span class="is-off" aria-disabled="true">Next →</span>' : `<a href="/shoes?${esc(qs(page + 1))}" rel="next">Next →</a>`}</nav>` : ''}
<p class="sh-fine">A model with no price says so; a price that has not been checked in ${esc(facets.stale_hours || 48)} hours is marked stale. No affiliate links, ever.</p></div>`;
return body;
}
ddiff --git a/test/views.test.js b/test/views.test.js
iindex 202f452..4fa5ed9 100644
---- a/test/views.test.js
++++ b/test/views.test.js
@@@ -44,5 +44,14 @@ const views = require('../server/views');
assert(bars.includes('−5.0%'), 'the comparison');
});
++ await check('the list\'s page links: the ends are plain text, not links to no page', () => {
++ const first = views.shoesIndex({ page: 1, total: 60 });
++ assert(first.includes('<span class="is-off" aria-disabled="true">← Previous</span>'), 'page 1 has no previous link');
++ assert(/<a href="\/shoes\?[^"]*page=2[^"]*" rel="next">Next →<\/a>/.test(first), 'page 1 links to page 2');
++ const last = views.shoesIndex({ page: 3, total: 60 });
++ assert(last.includes('<span class="is-off" aria-disabled="true">Next →</span>'), 'the last page has no next link');
++ assert(last.includes('rel="prev">← Previous</a>'), 'the last page links back');
++ });
++
done();
})();