2026-08-16 13:42:06 +01:00
|
|
|
/**
|
|
|
|
|
* CutoffDistanceDetail — the full year-by-year cut-off story.
|
|
|
|
|
*
|
|
|
|
|
* Chart, table, map and postcode check, in that order: the shape of the trend,
|
|
|
|
|
* then what happened in each year, then the same numbers over real streets,
|
|
|
|
|
* then the reader's own address measured against them.
|
|
|
|
|
*
|
|
|
|
|
* Shared by both templates because the content is identical, but placed
|
|
|
|
|
* differently by each. The primary page has a segmented control and gives this
|
|
|
|
|
* its own "Distance" tab; the secondary page is one flat panel by design, so it
|
|
|
|
|
* renders inline beneath the metric cards. Extracting it keeps the caveats and
|
|
|
|
|
* the ordering from drifting apart between the two.
|
|
|
|
|
*
|
|
|
|
|
* Server component — the map and postcode form are the only client parts, and
|
|
|
|
|
* they carry their own boundary.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import type { School } from '@/lib/types';
|
|
|
|
|
import { sectionStyles as styles } from './sectionShared';
|
|
|
|
|
import { CutoffTrendChart } from './charts';
|
|
|
|
|
import { CutoffYearTable } from './CutoffYearTable';
|
|
|
|
|
import { CutoffMapPanel } from './CutoffMapPanel';
|
|
|
|
|
import {
|
2026-08-20 14:54:02 +01:00
|
|
|
cutoffTrendSummary, cutoffCoverageNote, CUTOFF_CHECK_CAVEAT,
|
2026-08-16 13:42:06 +01:00
|
|
|
type CutoffYearRow,
|
|
|
|
|
} from './lastDistanceOffered';
|
|
|
|
|
|
|
|
|
|
export function CutoffDistanceDetail({
|
|
|
|
|
rows,
|
|
|
|
|
schoolInfo,
|
|
|
|
|
}: {
|
|
|
|
|
rows: CutoffYearRow[];
|
|
|
|
|
schoolInfo: School;
|
|
|
|
|
}) {
|
|
|
|
|
const publishedYears = rows.filter((r) => r.status === 'published').length;
|
|
|
|
|
if (publishedYears < 2) return null;
|
|
|
|
|
|
|
|
|
|
const trendSummary = cutoffTrendSummary(rows);
|
|
|
|
|
const coverageNote = cutoffCoverageNote(rows);
|
2026-08-20 14:54:02 +01:00
|
|
|
/*
|
|
|
|
|
* The chart appears at the same four points that let cutoffTrendSummary
|
|
|
|
|
* state a direction. Below that we already refuse to call the series a
|
|
|
|
|
* trend, and drawing a trend line under that refusal contradicts it — three
|
|
|
|
|
* points joined by a line say "look, it is falling" whatever the sentence
|
|
|
|
|
* beneath admits. The table carries every one of those years anyway, with
|
|
|
|
|
* the reasons a line cannot show, so nothing is lost by leaving it out.
|
|
|
|
|
*/
|
|
|
|
|
const showChart = publishedYears >= 4;
|
2026-08-16 13:42:06 +01:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
2026-08-20 14:54:02 +01:00
|
|
|
{showChart && (
|
|
|
|
|
<>
|
|
|
|
|
<div className={styles.admissionsChartCap}>Last distance offered, by year</div>
|
|
|
|
|
<CutoffTrendChart rows={rows} />
|
|
|
|
|
<p className={styles.cutoffChartKey}>
|
|
|
|
|
Gaps are years with no published figure — the line is never drawn
|
|
|
|
|
across one. The table says what happened in each.
|
|
|
|
|
</p>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
2026-08-16 13:42:06 +01:00
|
|
|
{trendSummary && <p className={styles.admissionsTrendSummary}>{trendSummary}</p>}
|
|
|
|
|
|
|
|
|
|
<CutoffYearTable rows={rows} />
|
|
|
|
|
{coverageNote && <p className={styles.cutoffChartKey}>{coverageNote}</p>}
|
|
|
|
|
|
|
|
|
|
<CutoffMapPanel schoolInfo={schoolInfo} rows={rows} />
|
|
|
|
|
|
2026-08-20 14:54:02 +01:00
|
|
|
{/* The single caveat for the whole section. It lives here rather than
|
|
|
|
|
inside the check, so it still renders for a school with no
|
|
|
|
|
coordinates — where there is a table but no map and no check. */}
|
|
|
|
|
<p className={styles.cutoffCheckCaveat}>{CUTOFF_CHECK_CAVEAT}</p>
|
2026-08-16 13:42:06 +01:00
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
}
|