feat: shared visual layer + redesigned topbar (#4)
Introduce new design token set (paper/ink/line/accent + radius/shadow) with backward-compat aliases for legacy --surface/--navy/--text names. Swap DM Sans for Plus Jakarta Sans, add JetBrains Mono with tabular numerics. Replace .app-header with sticky .topbar partial (brand + segmented nav + Next update / Last refresh meta + Refresh all button). Add POST /api/refresh-all that runs refreshAllPlayersInDB() with an in-memory mutex and returns the rendered topbar so HTMX can swap it in. "Next update" is computed as first Tuesday of next month (approximation of PDGA's monthly cycle). "Last refresh" derives from MAX(players.last_updated).
This commit is contained in:
@@ -5,6 +5,9 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><%= title %></title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,300..700;1,300..700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
|
||||
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
|
||||
<link rel="stylesheet" href="/css/shared.css">
|
||||
<% if (typeof cssFiles !== 'undefined') { %>
|
||||
@@ -14,15 +17,7 @@
|
||||
<% } %>
|
||||
</head>
|
||||
<body>
|
||||
<header class="app-header">
|
||||
<div class="header-inner">
|
||||
<a href="/" class="app-logo">
|
||||
<span class="logo-icon"><i class="fas fa-compact-disc"></i></span>
|
||||
PDGA Ratings
|
||||
</a>
|
||||
<%- include('../partials/nav') %>
|
||||
</div>
|
||||
</header>
|
||||
<%- include('../partials/topbar', { activePage, lastRefresh, nextUpdate }) %>
|
||||
|
||||
<div class="container">
|
||||
<%- body %>
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<header class="topbar" id="topbar">
|
||||
<div class="topbar__inner">
|
||||
<a href="/" class="topbar__brand">
|
||||
<span class="topbar__brand-mark" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M3 17 L9 11 L13 15 L21 6" />
|
||||
<path d="M14 6 L21 6 L21 13" />
|
||||
</svg>
|
||||
</span>
|
||||
<span class="topbar__brand-text">
|
||||
<span class="topbar__brand-title">Rating Tracker</span>
|
||||
<span class="topbar__brand-sub">Disc golf · unofficial</span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="topbar__nav" aria-label="Primary">
|
||||
<a href="/" class="<%= activePage === 'players' ? 'active' : '' %>">Players</a>
|
||||
<a href="/courses" class="<%= activePage === 'courses' ? 'active' : '' %>">Courses</a>
|
||||
</nav>
|
||||
|
||||
<div class="topbar__meta">
|
||||
<div class="topbar__meta-item">
|
||||
<span class="topbar__meta-label">Next update</span>
|
||||
<span class="topbar__meta-value"><%= nextUpdate %></span>
|
||||
</div>
|
||||
<div class="topbar__meta-item">
|
||||
<span class="topbar__meta-label">Last refresh</span>
|
||||
<span class="topbar__meta-value"><%= lastRefresh %></span>
|
||||
</div>
|
||||
<span class="topbar__divider" aria-hidden="true"></span>
|
||||
<button
|
||||
class="topbar__refresh"
|
||||
type="button"
|
||||
hx-post="/api/refresh-all"
|
||||
hx-target="#topbar"
|
||||
hx-swap="outerHTML"
|
||||
hx-disabled-elt="this"
|
||||
>
|
||||
<span class="topbar__refresh-icon" aria-hidden="true">↻</span>
|
||||
<span class="topbar__refresh-spinner" aria-hidden="true"></span>
|
||||
<span class="topbar__refresh-label">Refresh all</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
Reference in New Issue
Block a user