Files
BanGUI/Docs/Tasks.md
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

4.8 KiB

T-18 · Merge useDashboardCountryData and useMapData — near-identical hooks

Where found: frontend/src/hooks/useDashboardCountryData.ts and frontend/src/hooks/useMapData.ts

Why this is needed: Both hooks call fetchBansByCountry, maintain the same state shape (countries, countryNames, bans, total, loading, error), and implement the same abort-controller pattern. The only behavioural difference is that useMapData adds a 300ms debounce. Any bug fix must be applied to both.

Goal: A single useBansByCountry base hook; useMapData adds the debounce on top.

What to do:

  1. Create useBansByCountry(range, origin, source, countryCode?) — the shared fetch logic without debounce.
  2. Refactor useDashboardCountryData to wrap useBansByCountry.
  3. Refactor useMapData to wrap useBansByCountry and add the debounce layer.
  4. Keep the existing hook names as thin wrappers to preserve call sites.

Possible traps and issues:

  • useMapData returns { data } (the full response object) whereas useDashboardCountryData unpacks countries, countryNames, bans, total. Normalise the return shape before collapsing.
  • Tests for each hook test them independently — update or merge.

Docs changes needed: None.

Doc references: frontend/src/hooks/useDashboardCountryData.ts, frontend/src/hooks/useMapData.ts


T-19 · Move DashboardFilterProvider — page-scoped provider in wrong directory

Where found: frontend/src/providers/DashboardFilterProvider.tsx — instantiated only inside DashboardPage.tsx

Why this is needed: The providers/ directory implies app-wide providers (alongside AuthProvider, ThemeProvider, TimezoneProvider). DashboardFilterProvider wraps only DashboardPageContent and is not used anywhere else. Its placement implies reuse that doesn't exist, misleading future contributors about its scope.

Goal: Co-located with its only consumer.

What to do:

  1. Move DashboardFilterProvider.tsx to frontend/src/pages/ (alongside DashboardPage.tsx) or to frontend/src/pages/dashboard/ if the page is split into a subdirectory.
  2. Update imports in DashboardPage.tsx and any tests.

Possible traps and issues: Only DashboardPage.tsx imports it — confirm with grep before moving.

Docs changes needed: Docs/Web-Development.md — document what belongs in providers/ (app-wide) vs co-located.

Doc references: Docs/Web-Development.md


T-20 · Replace inline style={{}} objects with makeStyles classes

Where found: frontend/src/pages/map/MapBansTable.tsx (multiple), pages/JailDetailPage.tsx, pages/HistoryPage.tsx, pages/history/IpDetailView.tsx, components/WorldMap.tsx, components/TopCountriesPieChart.tsx, components/TopCountriesBarChart.tsx

Why this is needed: The project uses Fluent UI's makeStyles with atomic CSS caching. Inline style={{}} objects are allocated on every render, bypass the atomic CSS cache, and are inconsistent with the established pattern. Exceptions are acceptable only for truly dynamic values (e.g. tooltip left/top that change on mouse move) — static layout values must use makeStyles.

Goal: All static layout properties moved to makeStyles. Inline styles only for genuinely dynamic values.

What to do:

  1. Audit each file listed above.
  2. For static display: flex, gap, margin, padding — move to makeStyles in that component's style block.
  3. Keep inline style only where the value is truly dynamic at runtime (e.g. WorldMap tooltip position, TopCountriesBarChart chart height).

Possible traps and issues:

  • MapBansTable.tsx has several consecutive inline style objects for its pagination row — these can be collapsed into one named class.
  • Some components use both tokens.* values and inline styles — ensure makeStyles is imported where it isn't already.

Docs changes needed: Docs/Web-Development.md — add styling rule: use makeStyles for all static styles; inline style only for runtime-dynamic values.

Doc references: Docs/Web-Development.md, Fluent UI v9 docs on makeStyles


T-21 · Fail2BanMetadataService has inline socket timeout hardcoded

Where found: backend/app/services/fail2ban_metadata_service.py:64socket_timeout: float = 5.0

Why this is needed: Part of the same constant duplication as T-08. This file doesn't use _SOCKET_TIMEOUT as a module constant — it hardcodes 5.0 inline as a local variable. Should use the constant from constants.py once T-08 is done.

Goal: After T-08, replace with FAIL2BAN_SOCKET_TIMEOUT_FAST import.

What to do: Covered by T-08 sweep.

Possible traps and issues: None — dependent on T-08.

Docs changes needed: None.

Doc references: backend/app/services/fail2ban_metadata_service.py