diff --git a/templates/header.templ b/templates/header.templ index 7d0f8288..9659da38 100644 --- a/templates/header.templ +++ b/templates/header.templ @@ -213,7 +213,7 @@ templ Header(user User, currentPath string) { - + } diff --git a/templates/header_templ.go b/templates/header_templ.go index 5b591656..1a5dc6ae 100644 --- a/templates/header_templ.go +++ b/templates/header_templ.go @@ -631,7 +631,7 @@ func Header(user User, currentPath string) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/web/src/stats.ts b/web/src/stats.ts index b084bdff..0fc06aab 100644 --- a/web/src/stats.ts +++ b/web/src/stats.ts @@ -244,8 +244,12 @@ async function loadSummary(): Promise { // Rendering ---------------------------------------------------------------- function fmtDay(iso: string): string { - const parts = iso.split("-"); - return parts.length >= 3 ? `${parts[1]}-${parts[2]}` : iso; + // "2026-10-15" → "Oct 15" — a bare "10-15" x-label reads like a NUMBER + // RANGE next to hour values (it was mistaken for "10-15 hours" on the + // listening chart), so spell the month out. + const d = new Date(iso + "T00:00:00"); + if (isNaN(d.getTime())) return iso; + return d.toLocaleDateString(undefined, { month: "short", day: "numeric" }); } function themeVar(name: string, fallback: string): string { @@ -335,15 +339,27 @@ async function renderDailyCharts(daily: DailyEntry[]): Promise { const accent = themeVar("--accent", "#7aa2f7"); const secondary = themeVar("--text-secondary", "#9aa0b5"); const labels = daily.map((d) => fmtDay(d.date)); - const baseOptions: ChartConfiguration["options"] = { + // Unit-carrying tooltips: a bare number next to "hrs"/"min"/"pages" + // invites misreading (the x-axis date confusion happened exactly once). + const chartOptions = (unit: string): ChartConfiguration["options"] => ({ responsive: true, maintainAspectRatio: false, - plugins: { legend: { display: false } }, + plugins: { + legend: { display: false }, + tooltip: { + callbacks: { + label: (ctx) => { + const v = typeof ctx.parsed === "number" ? ctx.parsed : ctx.parsed.y; + return `${Math.round(v * 10) / 10} ${unit}`; + }, + }, + }, + }, scales: { x: { grid: { display: false }, ticks: { color: secondary, maxTicksLimit: 10 } }, y: { grid: { color: "rgba(128,128,128,.15)" }, ticks: { color: secondary }, beginAtZero: true }, }, - }; + }); minutesChart?.destroy(); pagesChart?.destroy(); @@ -360,7 +376,7 @@ async function renderDailyCharts(daily: DailyEntry[]): Promise { labels, datasets: [{ data: daily.map((d) => d.minutes), backgroundColor: accent, borderRadius: 4 }], }, - options: baseOptions, + options: chartOptions("min"), }); } @@ -381,7 +397,7 @@ async function renderDailyCharts(daily: DailyEntry[]): Promise { }, ], }, - options: baseOptions, + options: chartOptions("pages"), }); } @@ -402,7 +418,7 @@ async function renderDailyCharts(daily: DailyEntry[]): Promise { }, ], }, - options: baseOptions, + options: chartOptions("hrs"), }); } }