2026-06-02 13:46:45 +01:00
|
|
|
|
// Server component: pure markup, no client state.
|
|
|
|
|
|
|
|
|
|
|
|
import styles from './HomeView.module.css';
|
|
|
|
|
|
|
|
|
|
|
|
interface EditorialSectionProps {
|
|
|
|
|
|
totalSchools: number | null;
|
|
|
|
|
|
localAuthorityCount: number;
|
2026-08-14 17:15:09 +01:00
|
|
|
|
latestYearLabel: string | null;
|
|
|
|
|
|
earliestYearLabel: string | null;
|
2026-06-02 13:46:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-14 17:15:09 +01:00
|
|
|
|
export function EditorialSection({
|
|
|
|
|
|
totalSchools,
|
|
|
|
|
|
localAuthorityCount,
|
|
|
|
|
|
latestYearLabel,
|
|
|
|
|
|
earliestYearLabel,
|
|
|
|
|
|
}: EditorialSectionProps) {
|
|
|
|
|
|
/*
|
|
|
|
|
|
* The coverage line replaces a six-row "Coverage at a glance" table.
|
|
|
|
|
|
*
|
|
|
|
|
|
* That table put six numbers on the page to say one thing, and the headline
|
|
|
|
|
|
* row was wrong: it read "24,000+" — its own hardcoded fallback — because
|
|
|
|
|
|
* DataInfoResponse declared a `total_schools` field the API does not send
|
|
|
|
|
|
* (it sends `unique_schools`). The fetch had succeeded; only that field was
|
|
|
|
|
|
* undefined, so the fallback rendered and nothing failed. Every figure here
|
|
|
|
|
|
* is now live, and any figure that isn't available is dropped rather than
|
|
|
|
|
|
* replaced with a guess.
|
|
|
|
|
|
*/
|
|
|
|
|
|
const coverage = [
|
|
|
|
|
|
totalSchools ? `${totalSchools.toLocaleString('en-GB')} schools` : null,
|
|
|
|
|
|
localAuthorityCount > 0 ? `${localAuthorityCount} local authorities` : null,
|
|
|
|
|
|
earliestYearLabel && latestYearLabel ? `${earliestYearLabel}–${latestYearLabel}` : null,
|
|
|
|
|
|
].filter(Boolean);
|
|
|
|
|
|
|
2026-06-02 13:46:45 +01:00
|
|
|
|
return (
|
2026-08-14 17:15:09 +01:00
|
|
|
|
// No class on the section: the page container owns the vertical rhythm
|
|
|
|
|
|
// now, and this band carries its own ground on the card inside it.
|
|
|
|
|
|
<section>
|
|
|
|
|
|
<div className={styles.editorialCard}>
|
|
|
|
|
|
<div className={styles.sectionHead}>
|
|
|
|
|
|
<p className={styles.sectionKicker}>About school data</p>
|
|
|
|
|
|
<h2 className={styles.sectionHeading}>
|
|
|
|
|
|
Making England's school performance data actually readable
|
|
|
|
|
|
</h2>
|
|
|
|
|
|
</div>
|
2026-06-02 13:46:45 +01:00
|
|
|
|
<div className={styles.editorialText}>
|
|
|
|
|
|
<p>
|
2026-07-21 09:07:23 +01:00
|
|
|
|
School performance data in England is rich but fragmented. The Department for Education and Ofsted
|
|
|
|
|
|
publish Key Stage 2 SATs, GCSE attainment, inspection outcomes, progress scores, admissions figures
|
|
|
|
|
|
and demographics — each in its own table, each with its own jargon.
|
2026-06-02 13:46:45 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
<p>
|
2026-08-07 18:33:30 +01:00
|
|
|
|
schoolcompare brings it all into one place. Every school page shows performance against the national
|
2026-08-14 17:15:09 +01:00
|
|
|
|
average, explains what the numbers mean, and lets you compare schools side by side. Built for
|
2026-06-02 13:46:45 +01:00
|
|
|
|
parents, governors, journalists, and anyone who wants to understand a school without reading a
|
2026-07-21 09:00:02 +01:00
|
|
|
|
full inspection report.
|
2026-06-02 13:46:45 +01:00
|
|
|
|
</p>
|
|
|
|
|
|
</div>
|
2026-08-14 17:15:09 +01:00
|
|
|
|
{coverage.length > 0 && (
|
|
|
|
|
|
<p className={styles.coverageLine}>{coverage.join(' · ')}</p>
|
|
|
|
|
|
)}
|
2026-06-02 13:46:45 +01:00
|
|
|
|
</div>
|
|
|
|
|
|
</section>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|