Files
school_compare/nextjs-app/components/school/SecondarySchoolSections.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

157 lines
5.9 KiB
TypeScript

/**
* SecondarySchoolSections — the section sequence for secondary detail pages.
* Server component.
*
* Wrapped in `.secondaryScope`, which activates the secondary-only style
* overrides in schoolSections.module.css. Those rules target class names the
* primary page also uses (.card, .sectionTitle, .metricCard …), so scoping is
* what keeps them from restyling primary pages.
*
* The render conditions here MUST match buildSecondaryNavItems 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,
SchoolDestinations, NearbySchool,
} from '@/lib/types';
import { ofstedLegacyAreas } from '@/lib/utils';
import type { SecondaryFlags } from '@/lib/schoolSections';
import { OfstedSection } from './OfstedSection';
import { GcseSection } from './GcseSection';
import { DestinationsSection } from './DestinationsSection';
import { Post16DestinationsSection } from './Post16DestinationsSection';
import { SecondaryAdmissionsSection } from './SecondaryAdmissionsSection';
import { DistanceSection } from './DistanceSection';
import { SecondaryHistorySection } from './SecondaryHistorySection';
import { WellbeingSection } from './WellbeingSection';
import { FinancesSection } from './FinancesSection';
import { NearbySchoolsSection } from './NearbySchoolsSection';
import styles from './schoolSections.module.css';
export interface SecondarySchoolSectionsProps {
schoolInfo: School;
yearlyData: SchoolResult[];
absenceData: AbsenceData | null;
ofsted: OfstedInspection | null;
census: SchoolCensus | null;
admissions: SchoolAdmissions | null;
/** Needed to tell a year with no published cut-off apart from a year the
* school simply was not oversubscribed. */
admissionsHistory: SchoolAdmissions[];
/** Absent — not null — while the admission_distance flag is off. The two
* mean different things to the reader and must stay distinguishable:
* see SecondaryAdmissionsSection, which words the absence. */
admissionDistance: SchoolAdmissionDistance | null | undefined;
deprivation: SchoolDeprivation | null;
finance: SchoolFinance | null;
nationalAvg: NationalAverages | null;
destinations: SchoolDestinations | null;
/** Nearby schools of a comparable intake. Absent on an older API build. */
nearbySchools?: NearbySchool[];
flags: SecondaryFlags;
}
export function SecondarySchoolSections({
schoolInfo, yearlyData, ofsted, census,
admissions, admissionsHistory, admissionDistance,
deprivation, finance, nationalAvg, destinations, nearbySchools, flags,
}: SecondarySchoolSectionsProps) {
const secondaryAvg = nationalAvg?.secondary ?? {};
const isReportCard = !!(ofsted?.report_card && Object.keys(ofsted.report_card).length > 0);
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 (
<div className={styles.secondaryScope}>
{ofsted && (
<OfstedSection
ofsted={ofsted}
urn={schoolInfo.urn}
isReportCard={isReportCard}
ofstedInspectedDate={ofstedInspectedDate}
oeifAllSameGrade={oeifAllSameGrade}
oeifAreas={oeifAreas}
/>
)}
{flags.hasResults && flags.latestResults && (
<GcseSection
latestResults={flags.latestResults}
schoolInfo={schoolInfo}
secondaryAvg={secondaryAvg}
p8Suspended={flags.p8Suspended}
suppressComparison={flags.suppressComparison}
/>
)}
{/* Destinations follow attainment: they answer "and then what happened",
which only lands once the results are in view. */}
{flags.hasKs4Destinations && destinations?.ks4 && (
<DestinationsSection destinations={destinations.ks4} />
)}
{/* Sixth-form schools only. Absent, not placeheld, for a school with no
post-16 provision — the question simply does not apply there. */}
{flags.hasKs5Destinations && destinations?.ks5 && (
<Post16DestinationsSection destinations={destinations.ks5} />
)}
{/* See PrimarySchoolSections: distance and EES admissions are independent
sources, so either one warrants the section. */}
{(admissions || admissionDistance) && (
<SecondaryAdmissionsSection
admissions={admissions}
admissionDistance={admissionDistance}
admissionsHistory={admissionsHistory}
schoolInfo={schoolInfo}
/>
)}
{/* See PrimarySchoolSections — same placement, same reason. */}
<DistanceSection admissionDistance={admissionDistance} schoolInfo={schoolInfo} />
{yearlyData.length > 1 && (
<SecondaryHistorySection
yearlyData={yearlyData}
schoolInfo={schoolInfo}
nationalAvg={nationalAvg}
secondaryAvg={secondaryAvg}
suppressComparison={flags.suppressComparison}
/>
)}
{flags.hasWellbeing && (
<WellbeingSection
latestResults={flags.latestResults}
census={census}
schoolInfo={schoolInfo}
deprivation={deprivation}
hasDeprivation={flags.hasDeprivation}
/>
)}
{flags.hasFinance && finance && (
<FinancesSection finance={finance} showPremises />
)}
{/* Last: it is where the reader goes next, not part of this school. */}
<NearbySchoolsSection
urn={schoolInfo.urn}
thisMetricValue={flags.latestResults?.attainment_8_score ?? null}
nearby={nearbySchools}
/>
</div>
);
}