Files
fotospiel-app/resources/js/guest-v2/hooks/usePollStats.ts
2026-02-02 13:01:20 +01:00

58 lines
1.5 KiB
TypeScript

import React from 'react';
import { fetchEventStats } from '../services/statsApi';
import type { EventStats } from '../services/eventApi';
const defaultStats: EventStats = { onlineGuests: 0, tasksSolved: 0, latestPhotoAt: null };
export function usePollStats(eventToken: string | null, intervalMs = 10000) {
const [stats, setStats] = React.useState<EventStats>(defaultStats);
const [loading, setLoading] = React.useState<boolean>(Boolean(eventToken));
const [error, setError] = React.useState<string | null>(null);
React.useEffect(() => {
if (!eventToken) {
setStats(defaultStats);
setLoading(false);
setError(null);
return;
}
let active = true;
let timer: number | null = null;
const poll = async () => {
if (document.visibilityState === 'hidden') {
timer = window.setTimeout(poll, intervalMs);
return;
}
try {
setLoading(true);
const next = await fetchEventStats(eventToken);
if (!active) return;
setStats(next);
setError(null);
} catch (err) {
if (!active) return;
setError(err instanceof Error ? err.message : 'Failed to load stats');
} finally {
if (active) {
setLoading(false);
timer = window.setTimeout(poll, intervalMs);
}
}
};
poll();
return () => {
active = false;
if (timer) {
window.clearTimeout(timer);
}
};
}, [eventToken, intervalMs]);
return { stats, loading, error } as const;
}