feat(stats): add stats page and pile trend
Build, Test & Push Frontend / quality-check (push) Successful in 15s
Build, Test & Push Frontend / docker (push) Successful in 22s

Show the stat groups on /stats, the pile trend on the dashboard card,
one switch per group in the settings, and the shared groups on the
public profile.
This commit is contained in:
lobo committed 2026-09-27 07:16:10 +02:00
1 parent 83bbc2730d
commit 9d1c7bb40d
31 files changed
+978 -11

No files matched your search

+39
View File
@@ -0,0 +1,39 @@
import {useCallback, useEffect, useState} from 'react';
import {apiFetch} from '../utils/api.js';
import {statsUrl} from '../utils/stats.js';
/**
* GET /api/library/stats for the given groups (none = all). stats is null while loading and after an error.
*
* @param onUnauthorized called on a 401, e.g. useSessionExpired
*/
export default function useUserStats(groups, onUnauthorized, enabled = true) {
const [stats, setStats] = useState(null);
const [failed, setFailed] = useState(false);
const key = groups.join(',');
const load = useCallback(async () => {
setFailed(false);
try {
const response = await apiFetch(statsUrl(key));
if (response.status === 401) {
onUnauthorized();
return;
}
if (!response.ok) {
setFailed(true);
return;
}
setStats(await response.json());
} catch (err) {
console.error('Stats load error:', err);
setFailed(true);
}
}, [key, onUnauthorized]);
useEffect(() => {
if (enabled) load();
}, [enabled, load]);
return {stats, failed, reload: load};
}