62eeee5f7c
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 1m1s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 53s
Build and Push Docker Images / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 2m4s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
Frontend - Dynamic-import Chart.js components on detail/compare views so Chart.js no longer ships in initial JS. - Drop force-dynamic on home, compare, rankings so internal data fetches reuse Next.js's per-call revalidate cache. - Switch /school/[slug] to ISR with a 7-day revalidate window (school data updates annually). - Preconnect to analytics + postcodes.io; remove redundant defer on the Umami Script tag (afterInteractive already covers it). - Bump images.minimumCacheTTL to 1 year. - Extract HowItWorks and Editorial sections as server components passed to HomeView via slot props so their JSX stays out of the client bundle. Backend - Add GZipMiddleware (min 512 bytes). - Add CacheAndETagMiddleware: per-path Cache-Control with long s-maxage + stale-while-revalidate, ETag generation, and 304 on If-None-Match. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
60 lines
2.7 KiB
TypeScript
60 lines
2.7 KiB
TypeScript
// Server component: pure markup, no client state.
|
||
|
||
import styles from './HomeView.module.css';
|
||
|
||
interface EditorialSectionProps {
|
||
totalSchools: number | null;
|
||
localAuthorityCount: number;
|
||
}
|
||
|
||
export function EditorialSection({ totalSchools, localAuthorityCount }: EditorialSectionProps) {
|
||
return (
|
||
<section className={styles.editorial}>
|
||
<div className={styles.editorialGrid}>
|
||
<div className={styles.editorialText}>
|
||
<div className={styles.editorialKicker}>About school data</div>
|
||
<h2 className={styles.editorialHeading}>Making UK school performance data actually readable</h2>
|
||
<p>
|
||
School performance data in England is rich but fragmented. The Department for Education publishes
|
||
Key Stage 2 SATs, GCSE attainment, Ofsted outcomes, progress scores, admissions figures and
|
||
demographics — each in its own table, each with its own jargon.
|
||
</p>
|
||
<p>
|
||
SchoolCompare brings it all into one place. Every school page shows performance against the national
|
||
average, explains what the numbers mean, and lets you shortlist schools side by side. Built for
|
||
parents, governors, journalists, and anyone who wants to understand a school without reading a
|
||
40-page inspection report.
|
||
</p>
|
||
</div>
|
||
<div className={styles.factbox}>
|
||
<h3 className={styles.factboxHeading}>Coverage at a glance</h3>
|
||
<div className={styles.factRow}>
|
||
<span className={styles.factKey}>Schools covered</span>
|
||
<span className={styles.factVal}>{totalSchools ? `${totalSchools.toLocaleString()}` : '24,000+'}</span>
|
||
</div>
|
||
<div className={styles.factRow}>
|
||
<span className={styles.factKey}>Local authorities</span>
|
||
<span className={styles.factVal}>{localAuthorityCount > 0 ? localAuthorityCount : 152}</span>
|
||
</div>
|
||
<div className={styles.factRow}>
|
||
<span className={styles.factKey}>Phases</span>
|
||
<span className={styles.factVal}>Primary & Secondary</span>
|
||
</div>
|
||
<div className={styles.factRow}>
|
||
<span className={styles.factKey}>Latest results year</span>
|
||
<span className={styles.factVal}>2024/25</span>
|
||
</div>
|
||
<div className={styles.factRow}>
|
||
<span className={styles.factKey}>Historical data</span>
|
||
<span className={styles.factVal}>2016–2025</span>
|
||
</div>
|
||
<div className={styles.factRow}>
|
||
<span className={styles.factKey}>Metrics per school</span>
|
||
<span className={styles.factVal}>40+</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
);
|
||
}
|