Files
school_compare/nextjs-app/components/school/PrimarySchoolSections.tsx
T
TudorandClaude Opus 5.5 9ef48da4b1 fix(school): the Ofsted section shows the grade still in force and the latest visit
The section is dated by the latest visit and headlines the grade still in force with the inspection that awarded or confirmed it, or 'No overall grade'. A later visit that isn't the grade's source gets its own line, with an ungraded outcome such as 'Standards maintained'. The primary and secondary no-grade branches merge, so the secondary page no longer drops the sixth-form and early-years judgements (audit M2), and 'Not rated' goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 16:31:26 +01:00

164 lines
6.0 KiB
TypeScript

/**
* PrimarySchoolSections — the section sequence for primary and all-through
* detail pages. Server component.
*
* All-through schools route here rather than to SecondarySchoolSections,
* because this list renders BOTH the KS2 and KS4 blocks (ResultsSection and
* HistorySection branch on isAllThrough); the secondary list is KS4-only and
* would silently drop their SATs data.
*
* The render conditions here MUST match buildNavItems in lib/schoolSections,
* or the sticky nav will link to sections that do not exist.
*/
import type {
School, SchoolResult, AbsenceData, OfstedInspection, SchoolCensus,
SchoolAdmissions, SchoolAdmissionDistance, SchoolDeprivation, SchoolFinance, NationalAverages,
NearbySchool,
} from '@/lib/types';
import { ofstedLegacyAreas } from '@/lib/utils';
import type { SchoolFlags } from '@/lib/schoolSections';
import { OfstedSection } from './OfstedSection';
import { ResultsSection } from './ResultsSection';
import { AdmissionsSection } from './AdmissionsSection';
import { DistanceSection } from './DistanceSection';
import { InclusionSection } from './InclusionSection';
import { HistorySection } from './HistorySection';
import { SchoolLifeSection } from './SchoolLifeSection';
import { LocalAreaSection } from './LocalAreaSection';
import { FinancesSection } from './FinancesSection';
import { NearbySchoolsSection } from './NearbySchoolsSection';
export interface PrimarySchoolSectionsProps {
schoolInfo: School;
yearlyData: SchoolResult[];
absenceData: AbsenceData | null;
ofsted: OfstedInspection | null;
census: SchoolCensus | null;
admissions: SchoolAdmissions | null;
admissionsHistory: SchoolAdmissions[];
admissionDistance: SchoolAdmissionDistance | null;
deprivation: SchoolDeprivation | null;
finance: SchoolFinance | null;
nationalAvg: NationalAverages | null;
/** Nearby schools of a comparable intake. Absent on an older API build. */
nearbySchools?: NearbySchool[];
flags: SchoolFlags;
}
export function PrimarySchoolSections({
schoolInfo, yearlyData, absenceData, ofsted, census,
admissions, admissionsHistory, admissionDistance,
deprivation, finance, nationalAvg, nearbySchools, flags,
}: PrimarySchoolSectionsProps) {
const primaryAvg = nationalAvg?.primary ?? {};
const secondaryAvg = nationalAvg?.secondary ?? {};
const isReportCard = !!(ofsted?.report_card && Object.keys(ofsted.report_card).length > 0);
// Report cards are dated by their own inspection (rc_inspection_date);
// anything else by the school's latest visit, never the older inspection a
// grade may come from.
const ofstedInspectedDate = isReportCard
? ofsted?.rc_inspection_date ?? null
: ofsted?.latest_visit?.date ?? null;
const oeifAreas = ofsted ? ofstedLegacyAreas(ofsted) : [];
const oeifAllSameGrade =
!!ofsted &&
!isReportCard &&
ofsted.overall_effectiveness != null &&
oeifAreas.length >= 3 &&
oeifAreas.every((a) => a.value === ofsted.overall_effectiveness);
return (
<>
{ofsted && (
<OfstedSection
ofsted={ofsted}
urn={schoolInfo.urn}
isReportCard={isReportCard}
ofstedInspectedDate={ofstedInspectedDate}
oeifAllSameGrade={oeifAllSameGrade}
oeifAreas={oeifAreas}
/>
)}
{flags.hasAnyResults && flags.latestResults && (
<ResultsSection
latestResults={flags.latestResults}
schoolInfo={schoolInfo}
primaryAvg={primaryAvg}
secondaryAvg={secondaryAvg}
isAllThrough={flags.isAllThrough}
isSecondary={flags.isSecondary}
isSpecial={flags.isSpecial}
hasKS2Results={flags.hasKS2Results}
hasKS4Results={flags.hasKS4Results}
ks2Placeholder={flags.ks2Placeholder}
suppressKs2Comparison={flags.suppressKs2Comparison}
suppressKs4Comparison={flags.suppressKs4Comparison}
/>
)}
{/* Either source is enough to justify the section. The cut-off distance
and the EES admissions figures come from different places and a
minority of schools have one without the other — gating on admissions
alone would hide a published distance on those pages. */}
{(admissions || admissionDistance) && (
<AdmissionsSection
admissions={admissions}
admissionsHistory={admissionsHistory}
admissionDistance={admissionDistance}
isAllThrough={flags.isAllThrough}
/>
)}
{/* Its own section, directly after Admissions: it answers the question
the tile above raises. */}
<DistanceSection admissionDistance={admissionDistance} schoolInfo={schoolInfo} />
{flags.hasInclusionData && (
<InclusionSection
latestResults={flags.latestResults}
census={census}
hasGenderSplit={flags.hasGenderSplit}
primaryAvg={primaryAvg}
/>
)}
{yearlyData.length > 0 && (
<HistorySection
yearlyData={yearlyData}
schoolInfo={schoolInfo}
nationalAvg={nationalAvg}
primaryAvg={primaryAvg}
secondaryAvg={secondaryAvg}
isAllThrough={flags.isAllThrough}
isPrimary={flags.isPrimary}
isSecondary={flags.isSecondary}
hasKS2Results={flags.hasKS2Results}
hasKS4Results={flags.hasKS4Results}
suppressKs2Comparison={flags.suppressKs2Comparison}
suppressKs4Comparison={flags.suppressKs4Comparison}
/>
)}
{flags.hasSchoolLife && (
<SchoolLifeSection absenceData={absenceData} primaryAvg={primaryAvg} />
)}
{flags.hasDeprivation && deprivation && (
<LocalAreaSection deprivation={deprivation} />
)}
{flags.hasFinance && finance && <FinancesSection finance={finance} />}
{/* Last: it is where the reader goes next, not part of this school. */}
<NearbySchoolsSection
urn={schoolInfo.urn}
thisMetricValue={flags.latestResults?.rwm_expected_pct ?? null}
nearby={nearbySchools}
/>
</>
);
}