Files
BanGUI/frontend/src/hooks/useDashboardCountryData.ts
Lukas 69a0296c47 T-18: Merge useDashboardCountryData and useMapData into shared base hook
Create useBansByCountry as the shared base hook containing all common
fetch logic, abort-controller pattern, and state management. Both
useDashboardCountryData and useMapData now wrap this base hook:

- useDashboardCountryData: Thin wrapper that calls base hook with autoFetch=true
- useMapData: Wraps base hook with 300ms debounce layer

Changes:
- Create useBansByCountry.ts (base hook with optional autoFetch parameter)
- Refactor useDashboardCountryData.ts to use base hook
- Refactor useMapData.ts to use base hook with debounce wrapper
- Add tests for all three hooks

Benefits:
- Single source of truth for ban-by-country logic
- Bug fixes in base hook apply to both consumers
- Eliminates code duplication (~80 lines reduced)
- Maintains backward compatibility: existing call sites work unchanged

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-25 19:39:51 +02:00

52 lines
1.9 KiB
TypeScript

/**
* `useDashboardCountryData` hook.
*
* Fetches ban-by-country aggregates for dashboard chart components. This is a thin
* wrapper around {@link useBansByCountry} that preserves the original API and naming.
*
* Unlike `useMapData`, this hook has no debouncing.
*
* Re-fetches automatically when `timeRange` or `origin` changes.
*/
import type { BanOriginFilter, TimeRange } from "../types/ban";
import type { MapBanItem } from "../types/map";
import { useBansByCountry } from "./useBansByCountry";
/** Return value shape for {@link useDashboardCountryData}. */
export interface UseDashboardCountryDataResult {
/** ISO alpha-2 country code → ban count. */
countries: Record<string, number>;
/** ISO alpha-2 country code → human-readable country name. */
countryNames: Record<string, string>;
/** All ban records in the selected window. */
bans: MapBanItem[];
/** Total ban count in the window. */
total: number;
/** True while a fetch is in flight. */
loading: boolean;
/** Error message or `null`. */
error: string | null;
/** Re-fetch the data immediately. */
reload: () => void;
}
/**
* Fetch and expose ban-by-country data for dashboard charts.
*
* @param timeRange - Time-range preset: `"24h"`, `"7d"`, `"30d"`, or `"365d"`.
* @param origin - Origin filter: `"all"`, `"blocklist"`, or `"selfblock"`.
* @param source - Data source: `"fail2ban"` or `"archive"`.
* @returns Aggregated country data, ban list, loading state, and error.
*/
export function useDashboardCountryData(
timeRange: TimeRange,
origin: BanOriginFilter,
source: "fail2ban" | "archive" = "fail2ban",
): UseDashboardCountryDataResult {
const { countries, countryNames, bans, total, loading, error, refresh } =
useBansByCountry(timeRange, origin, source, undefined);
return { countries, countryNames, bans, total, loading, error, reload: refresh };
}