Refactor: Move DashboardFilterProvider to pages directory

- Move DashboardFilterProvider component and tests from providers/ to pages/
- Update DashboardPage imports to reflect new structure
- Update documentation with latest task progress

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-25 19:45:10 +02:00
parent 69a0296c47
commit c1135150c3
5 changed files with 15 additions and 25 deletions

View File

@@ -1,27 +1,3 @@
### 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`

View File

@@ -179,6 +179,20 @@ The distinction between **`pages/`** and **`components/`** is fundamental to the
- **Utils** are pure functions with no side effects and no React dependency.
- **Theme** contains exclusively Fluent UI custom token overrides and theme definitions — no component logic.
### Providers — App-Wide vs Page-Scoped
The `providers/` directory is reserved for **app-wide context providers** — providers that wrap the entire application or large sections of it and are used by many pages or components.
**App-wide providers belong in `providers/`:**
- `AuthProvider` — authentication state for the whole app
- `ThemeProvider` — theme/styling state for the whole app
- `TimezoneProvider` — timezone preference for the whole app
**Page-scoped providers belong co-located with their consumer:**
If a React Context provider is used by **only one page** (e.g., `DashboardFilterProvider` is used only by `DashboardPage`), it should live **in the same directory as the page** or in a subdirectory alongside the page's components. This prevents the `providers/` directory from being cluttered with page-specific state and makes the scope of these providers clear to future contributors.
**Example:** `DashboardFilterProvider` manages dashboard time-range and origin filters. It is instantiated only inside `DashboardPage.tsx` and its sub-components. Therefore, it lives in `pages/DashboardFilterProvider.tsx` (or `pages/dashboard/DashboardFilterProvider.tsx` if the page is split into a subdirectory), not in `providers/`.
---
## 5. UI Framework — Fluent UI React (v9)

View File

@@ -16,7 +16,7 @@ import { TopCountriesBarChart } from "../components/TopCountriesBarChart";
import { TopCountriesPieChart } from "../components/TopCountriesPieChart";
import { useCommonSectionStyles } from "../components/commonStyles";
import { useDashboardCountryData } from "../hooks/useDashboardCountryData";
import { DashboardFilterProvider, useDashboardFilters } from "../providers/DashboardFilterProvider";
import { DashboardFilterProvider, useDashboardFilters } from "./DashboardFilterProvider";
// ---------------------------------------------------------------------------