feat(backoffice): add dashboard statistics with charts

Add GET /stats API endpoint with collection overview, reading status,
format/library breakdowns, top series, and monthly additions.
Replace static home page with interactive dashboard featuring donut
charts, bar charts, and progress bars. Use distinct colors for series
(warning/yellow) across nav, page titles, and quick links.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-15 18:37:53 +01:00
parent 82444cda02
commit cf2e7a0be7
7 changed files with 714 additions and 75 deletions

View File

@@ -419,6 +419,66 @@ export async function updateReadingProgress(
});
}
export type StatsOverview = {
total_books: number;
total_series: number;
total_libraries: number;
total_pages: number;
total_size_bytes: number;
total_authors: number;
};
export type ReadingStatusStats = {
unread: number;
reading: number;
read: number;
};
export type FormatCount = {
format: string;
count: number;
};
export type LanguageCount = {
language: string | null;
count: number;
};
export type LibraryStatsItem = {
library_name: string;
book_count: number;
size_bytes: number;
read_count: number;
reading_count: number;
unread_count: number;
};
export type TopSeriesItem = {
series: string;
book_count: number;
read_count: number;
total_pages: number;
};
export type MonthlyAdditions = {
month: string;
books_added: number;
};
export type StatsResponse = {
overview: StatsOverview;
reading_status: ReadingStatusStats;
by_format: FormatCount[];
by_language: LanguageCount[];
by_library: LibraryStatsItem[];
top_series: TopSeriesItem[];
additions_over_time: MonthlyAdditions[];
};
export async function fetchStats() {
return apiFetch<StatsResponse>("/stats");
}
export async function markSeriesRead(seriesName: string, status: "read" | "unread" = "read") {
return apiFetch<{ updated: number }>("/series/mark-read", {
method: "POST",