);
}
// Bar chart via pure CSS
function BarChart({ data, color = "var(--color-primary)" }: { data: { label: string; value: number }[]; color?: string }) {
const max = Math.max(...data.map((d) => d.value), 1);
if (data.length === 0) return
No data
;
return (
{data.map((d, i) => (
{d.value || ""}
{d.label}
))}
);
}
// Horizontal progress bar for library breakdown
function HorizontalBar({ label, value, max, subLabel, color = "var(--color-primary)" }: { label: string; value: number; max: number; subLabel?: string; color?: string }) {
const pct = max > 0 ? (value / max) * 100 : 0;
return (
{label}{subLabel || formatNumber(value)}
);
}
export default async function DashboardPage() {
let stats: StatsResponse | null = null;
try {
stats = await fetchStats();
} catch (e) {
console.error("Failed to fetch stats:", e);
}
if (!stats) {
return (
StripStream Backoffice
Unable to load statistics. Make sure the API is running.
Overview of your comic collection. Manage your libraries, track your reading progress, and explore your books and series.
{/* Overview stat cards */}
{/* Charts row */}
{/* Reading status donut */}
Reading Status
{/* By format donut */}
By Format ({
label: (f.format || "Unknown").toUpperCase(),
value: f.count,
color: formatColors[i % formatColors.length],
}))}
/>
{/* By library donut */}
By Library ({
label: l.library_name,
value: l.book_count,
color: formatColors[i % formatColors.length],
}))}
/>
{/* Second row */}
{/* Monthly additions bar chart */}
Books Added (Last 12 Months) ({
label: m.month.slice(5), // "MM" from "YYYY-MM"
value: m.books_added,
}))}
color="hsl(198 78% 37%)"
/>
{/* Top series */}
Top Series