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>
52 lines
1.9 KiB
TypeScript
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 };
|
|
}
|