fix: address code review for visual layer + topbar (#4)

This commit is contained in:
Samuel Enocsson
2026-05-21 12:50:31 +02:00
parent 8c977d6624
commit de99d4ede7
8 changed files with 71 additions and 62 deletions
+6 -2
View File
@@ -72,6 +72,9 @@
--shadow-overlay: 0 20px 60px rgba(15, 23, 42, 0.15), 0 4px 12px rgba(15, 23, 42, 0.08);
--transition: 150ms cubic-bezier(0.4, 0, 0.2, 1);
/* Topbar dimensions (used by sticky thead) */
--topbar-height: 64px;
}
/* ── Reset & Base ─────────────────────────────── */
@@ -279,6 +282,7 @@ body {
}
@media (max-width: 880px) {
:root { --topbar-height: 56px; }
.topbar__inner { padding: 10px 16px; gap: 10px; }
.topbar__meta-item, .topbar__divider { display: none; }
.topbar__refresh-label { display: none; }
@@ -322,7 +326,7 @@ table {
thead {
position: sticky;
top: 56px;
top: var(--topbar-height);
z-index: 10;
}
@@ -547,7 +551,7 @@ a:hover {
}
thead {
top: 56px;
top: var(--topbar-height);
}
}
+1
View File
@@ -14,6 +14,7 @@ app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views/pages'));
app.use(express.static('public'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(playerRoutes);
app.use(courseRoutes);
+5 -3
View File
@@ -185,15 +185,17 @@ function savePredictedRatingToDB(pdgaNumber, predictedRating, stdDev = null) {
});
}
function getLastRefresh(callback) {
function getLastRefresh() {
return new Promise((resolve, reject) => {
db.get(
'SELECT MAX(last_updated) AS lastRefresh FROM players',
[],
(err, row) => {
if (err) return callback(err);
callback(null, row ? row.lastRefresh : null);
if (err) reject(err);
else resolve(row ? row.lastRefresh : null);
}
);
});
}
module.exports = {
+8 -3
View File
@@ -12,21 +12,26 @@ const logger = require('../logger');
let refreshInProgress = false;
router.post('/api/refresh-all', async (req, res) => {
router.post('/api/refresh-all', async (req, res, next) => {
if (refreshInProgress) {
logger.info('refresh-all already in progress, rejecting');
return res.status(409).json({ error: 'Refresh already in progress' });
}
refreshInProgress = true;
try {
try {
await refreshAllPlayersInDB();
} catch (err) {
logger.error({ err }, 'refresh-all failed');
}
const page = req.body?.page === 'courses' ? 'courses' : 'players';
const locals = await getTopbarLocals();
res.render('../partials/topbar', { activePage: page, ...locals });
} catch (err) {
next(err);
} finally {
refreshInProgress = false;
}
const locals = await getTopbarLocals();
res.render('../partials/topbar', { activePage: req.query.page || 'players', ...locals });
});
router.get('/partials/ratings-table', async (req, res) => {
+2 -4
View File
@@ -32,9 +32,7 @@ function computeNextUpdate(now = new Date()) {
async function getTopbarLocals() {
try {
const lastIso = await new Promise((resolve, reject) => {
getLastRefresh((err, val) => (err ? reject(err) : resolve(val)));
});
const lastIso = await getLastRefresh();
return { lastRefresh: formatRelative(lastIso), nextUpdate: computeNextUpdate() };
} catch (err) {
logger.warn({ err }, 'topbar locals fallback');
@@ -42,4 +40,4 @@ async function getTopbarLocals() {
}
}
module.exports = { getTopbarLocals, formatRelative, computeNextUpdate };
module.exports = { getTopbarLocals };
-1
View File
@@ -25,7 +25,6 @@
<%- include('../partials/layout', {
title: 'PDGA Courses - Sweden',
heading: 'PDGA Courses - Sweden',
activePage: 'courses',
cssFiles: ['courses.css'],
jsFiles: ['courses.js'],
-1
View File
@@ -56,7 +56,6 @@
<%- include('../partials/layout', {
title: 'PDGA Ratings',
heading: 'PDGA Player Ratings',
activePage: 'players',
cssFiles: ['players.css'],
jsFiles: ['tooltips.js', 'chart.js', 'progress.js', 'players.js'],
+1
View File
@@ -32,6 +32,7 @@
class="topbar__refresh"
type="button"
hx-post="/api/refresh-all"
hx-vals='{"page": "<%= activePage %>"}'
hx-target="#topbar"
hx-swap="outerHTML"
hx-disabled-elt="this"