diff --git a/Docs/Tasks.md b/Docs/Tasks.md index f68fd66..91cccc2 100644 --- a/Docs/Tasks.md +++ b/Docs/Tasks.md @@ -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` diff --git a/Docs/Web-Development.md b/Docs/Web-Development.md index 82713ff..625ae9f 100644 --- a/Docs/Web-Development.md +++ b/Docs/Web-Development.md @@ -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) diff --git a/frontend/src/providers/DashboardFilterProvider.tsx b/frontend/src/pages/DashboardFilterProvider.tsx similarity index 100% rename from frontend/src/providers/DashboardFilterProvider.tsx rename to frontend/src/pages/DashboardFilterProvider.tsx diff --git a/frontend/src/pages/DashboardPage.tsx b/frontend/src/pages/DashboardPage.tsx index 6fbe4f9..543f536 100644 --- a/frontend/src/pages/DashboardPage.tsx +++ b/frontend/src/pages/DashboardPage.tsx @@ -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"; // --------------------------------------------------------------------------- diff --git a/frontend/src/providers/__tests__/DashboardFilterProvider.test.tsx b/frontend/src/pages/__tests__/DashboardFilterProvider.test.tsx similarity index 100% rename from frontend/src/providers/__tests__/DashboardFilterProvider.test.tsx rename to frontend/src/pages/__tests__/DashboardFilterProvider.test.tsx