/**
* 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 (
);
}
}