feat(map): fetch all schools for map view, add reference pin, cap radius at 5mi
All checks were successful
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 45s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m6s
Build and Push Docker Images / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 31s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s

- Remove 10-mile radius option; cap backend radius max at 5 miles
- Raise backend page_size max to 500 so map can fetch all schools in one call
- HomeView: when map view is active, fetch all schools within radius
  (page_size=500) instead of showing only the paginated first page;
  falls back to initial SSR schools while loading
- SchoolMap/LeafletMapInner: accept referencePoint prop and render a
  distinctive coral circle pin at the search postcode location

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-30 09:13:14 +01:00
parent daf24e4739
commit d6a45b8e12
5 changed files with 54 additions and 10 deletions

View File

@@ -35,6 +35,8 @@ export function HomeView({ initialSchools, filters, totalSchools }: HomeViewProp
const [hasMore, setHasMore] = useState(initialSchools.total_pages > 1);
const [isLoadingMore, setIsLoadingMore] = useState(false);
const [laAverages, setLaAverages] = useState<Record<string, number>>({});
const [mapSchools, setMapSchools] = useState<School[]>([]);
const [isLoadingMap, setIsLoadingMap] = useState(false);
const prevSearchParamsRef = useRef(searchParams.toString());
const hasSearch = searchParams.get('search') || searchParams.get('postcode');
@@ -52,6 +54,7 @@ export function HomeView({ initialSchools, filters, totalSchools }: HomeViewProp
setAllSchools(initialSchools.schools);
setCurrentPage(initialSchools.page);
setHasMore(initialSchools.total_pages > 1);
setMapSchools([]);
}
}, [searchParams, initialSchools]);
@@ -60,6 +63,20 @@ export function HomeView({ initialSchools, filters, totalSchools }: HomeViewProp
setSelectedMapSchool(null);
}, [resultsView, searchParams]);
// Fetch all schools within radius when map view is active
useEffect(() => {
if (resultsView !== 'map' || !isLocationSearch) return;
setIsLoadingMap(true);
const params: Record<string, any> = {};
searchParams.forEach((value, key) => { params[key] = value; });
params.page = 1;
params.page_size = 500;
fetchSchools(params, { cache: 'no-store' })
.then(r => setMapSchools(r.schools))
.catch(() => setMapSchools(initialSchools.schools))
.finally(() => setIsLoadingMap(false));
}, [resultsView, searchParams]);
// Fetch LA averages when secondary schools are visible
useEffect(() => {
if (!isSecondaryView) return;
@@ -214,13 +231,14 @@ export function HomeView({ initialSchools, filters, totalSchools }: HomeViewProp
<div className={styles.mapViewContainer}>
<div className={styles.mapContainer}>
<SchoolMap
schools={initialSchools.schools}
schools={isLoadingMap ? initialSchools.schools : mapSchools}
center={initialSchools.location_info?.coordinates}
referencePoint={initialSchools.location_info?.coordinates}
onMarkerClick={setSelectedMapSchool}
/>
</div>
<div className={styles.compactList}>
{initialSchools.schools.map((school) => (
{(isLoadingMap ? initialSchools.schools : mapSchools).map((school) => (
<div
key={school.urn}
className={`${styles.listItemWrapper} ${selectedMapSchool?.urn === school.urn ? styles.highlightedItem : ''}`}