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"),
});
}
}