/** * Rankings Page (SSR) * Display top-ranked schools by various metrics */ import { fetchRankings, fetchFilters, fetchMetrics } from '@/lib/api'; import { RankingsView } from '@/components/RankingsView'; import { absoluteUrl } from '@/lib/site'; import type { Metadata } from 'next'; interface RankingsPageProps { searchParams: Promise<{ metric?: string; local_authority?: string; year?: string; phase?: string; }>; } export const metadata: Metadata = { // 'School Rankings' matched nothing anyone types. League tables is the // phrase parents actually search, and it spikes each results day. title: { absolute: 'Primary & Secondary School League Tables | schoolcompare' }, description: 'Rank English schools by SATs results, GCSEs, Progress 8 or Attainment 8, and filter by local authority or year. Built from the DfE’s own figures.', keywords: 'school rankings, top schools, best schools, KS2 rankings, KS4 rankings, school league tables', // Param forms (?metric=&local_authority=&year=&phase=) collapse here for // now. W3 replaces them with real indexable paths. alternates: { canonical: absoluteUrl('/rankings') }, }; // Dynamic via searchParams; remove force-dynamic so internal data fetches // can still use Next.js's per-call revalidate cache. export default async function RankingsPage({ searchParams }: RankingsPageProps) { const { metric: metricParam, local_authority, year: yearParam, phase: phaseParam } = await searchParams; const phase = phaseParam || 'primary'; const metric = metricParam || (phase === 'secondary' ? 'attainment_8_score' : 'rwm_expected_pct'); const year = yearParam ? parseInt(yearParam) : undefined; // Fetch rankings data with error handling try { const [rankingsResponse, filtersResponse, metricsResponse] = await Promise.all([ fetchRankings({ metric, local_authority, year, limit: 100, phase, }), fetchFilters(), fetchMetrics(), ]); // Metrics is already an array const metricsArray = metricsResponse?.metrics || []; return ( ); } catch (error) { console.error('Error fetching data for rankings page:', error); // Return error state with empty data return ( ); } }