({ label: formatChartLabel(m.month, period, locale), value: m.books_read }))}
+ data={reading_over_time.map((m) => ({ label: formatChartLabel(m.month, period, locale), value: m[dataKey] }))}
color="hsl(142 60% 45%)"
/>
);
@@ -202,7 +208,7 @@ export default async function DashboardPage({
for (const row of users_reading_over_time) {
const label = formatChartLabel(row.month, period, locale);
if (!byMonth.has(row.month)) byMonth.set(row.month, { label });
- byMonth.get(row.month)![row.username] = row.books_read;
+ byMonth.get(row.month)![row.username] = row[dataKey];
}
const chartData = [...byMonth.values()];
const lines = usernames.map((u, i) => ({
diff --git a/apps/backoffice/app/components/MetricToggle.tsx b/apps/backoffice/app/components/MetricToggle.tsx
new file mode 100644
index 0000000..b389a8e
--- /dev/null
+++ b/apps/backoffice/app/components/MetricToggle.tsx
@@ -0,0 +1,47 @@
+"use client";
+
+import { useRouter, useSearchParams } from "next/navigation";
+
+type Metric = "books" | "pages";
+
+export function MetricToggle({
+ labels,
+}: {
+ labels: { books: string; pages: string };
+}) {
+ const router = useRouter();
+ const searchParams = useSearchParams();
+ const raw = searchParams.get("metric");
+ const current: Metric = raw === "pages" ? "pages" : "books";
+
+ function setMetric(metric: Metric) {
+ const params = new URLSearchParams(searchParams.toString());
+ if (metric === "books") {
+ params.delete("metric");
+ } else {
+ params.set("metric", metric);
+ }
+ const qs = params.toString();
+ router.push(qs ? `?${qs}` : "/", { scroll: false });
+ }
+
+ const options: Metric[] = ["books", "pages"];
+
+ return (
+
+ {options.map((m) => (
+
+ ))}
+
+ );
+}
diff --git a/apps/backoffice/lib/api.ts b/apps/backoffice/lib/api.ts
index 15b8ad4..18eaeb8 100644
--- a/apps/backoffice/lib/api.ts
+++ b/apps/backoffice/lib/api.ts
@@ -699,12 +699,14 @@ export type RecentlyReadItem = {
export type MonthlyReading = {
month: string;
books_read: number;
+ pages_read: number;
};
export type UserMonthlyReading = {
month: string;
username: string;
books_read: number;
+ pages_read: number;
};
export type JobTimePoint = {
diff --git a/apps/backoffice/lib/i18n/en.ts b/apps/backoffice/lib/i18n/en.ts
index fe6ddcd..d9ea2a5 100644
--- a/apps/backoffice/lib/i18n/en.ts
+++ b/apps/backoffice/lib/i18n/en.ts
@@ -80,6 +80,8 @@ const en: Record = {
"dashboard.periodDay": "Day",
"dashboard.periodWeek": "Week",
"dashboard.periodMonth": "Month",
+ "dashboard.metricBooks": "Books",
+ "dashboard.metricPages": "Pages",
"dashboard.popularSeries": "Popular series",
"dashboard.noSeries": "No series yet",
"dashboard.unknown": "Unknown",
diff --git a/apps/backoffice/lib/i18n/fr.ts b/apps/backoffice/lib/i18n/fr.ts
index 0e99751..0d02292 100644
--- a/apps/backoffice/lib/i18n/fr.ts
+++ b/apps/backoffice/lib/i18n/fr.ts
@@ -78,6 +78,8 @@ const fr = {
"dashboard.periodDay": "Jour",
"dashboard.periodWeek": "Semaine",
"dashboard.periodMonth": "Mois",
+ "dashboard.metricBooks": "Livres",
+ "dashboard.metricPages": "Pages",
"dashboard.popularSeries": "Séries populaires",
"dashboard.noSeries": "Aucune série pour le moment",
"dashboard.unknown": "Inconnu",