165 lines
7.3 KiB
TypeScript
165 lines
7.3 KiB
TypeScript
/**
|
|||
|
|
* OfstedSection — shared between the primary and secondary detail pages.
|
||
|
|
*
|
||
|
|
* The two versions were ~80% identical, but that figure masked a real fork in
|
||
|
|
* the no-overall-grade case: the primary page shows a "Not rated" badge, while
|
||
|
|
* the secondary page shows a four-area OEIF panel. The disclaimer copy also
|
||
|
|
* differs slightly. Both are preserved exactly via the `variant` prop rather
|
||
|
|
* than reconciled, because this refactor must not change either page. Merging
|
||
|
|
* them is a follow-up decision for a human, not a side effect of a move.
|
||
|
|
*
|
||
|
|
* Server component.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import type { OfstedInspection } from '@/lib/types';
|
||
|
|
import { Section, sectionStyles as styles } from './sectionShared';
|
||
|
|
|
||
|
|
const OFSTED_LABELS: Record<number, string> = {
|
||
|
|
1: 'Outstanding', 2: 'Good', 3: 'Requires Improvement', 4: 'Inadequate',
|
||
|
|
};
|
||
|
|
|
||
|
|
const RC_LABELS: Record<number, string> = {
|
||
|
|
1: 'Exceptional', 2: 'Strong', 3: 'Expected standard', 4: 'Needs attention', 5: 'Urgent improvement',
|
||
|
|
};
|
||
|
|
|
||
|
|
const RC_CATEGORIES = [
|
||
|
|
{ key: 'rc_inclusion' as const, label: 'Inclusion' },
|
||
|
|
{ key: 'rc_curriculum_teaching' as const, label: 'Curriculum & Teaching' },
|
||
|
|
{ key: 'rc_achievement' as const, label: 'Achievement' },
|
||
|
|
{ key: 'rc_attendance_behaviour' as const, label: 'Attendance & Behaviour' },
|
||
|
|
{ key: 'rc_personal_development' as const, label: 'Personal Development' },
|
||
|
|
{ key: 'rc_leadership_governance' as const, label: 'Leadership & Governance' },
|
||
|
|
{ key: 'rc_early_years' as const, label: 'Early Years' },
|
||
|
|
{ key: 'rc_sixth_form' as const, label: 'Sixth Form' },
|
||
|
|
];
|
||
|
|
|
||
|
|
export interface OfstedSectionProps {
|
||
|
|
ofsted: OfstedInspection;
|
||
|
|
urn: number;
|
||
|
|
isReportCard: boolean;
|
||
|
|
ofstedInspectedDate: string | null;
|
||
|
|
oeifAllSameGrade: boolean;
|
||
|
|
oeifAreas: { label: string; value: number }[];
|
||
|
|
variant?: 'primary' | 'secondary';
|
||
|
|
}
|
||
|
|
|
||
|
|
export function OfstedSection({
|
||
|
|
ofsted, urn, isReportCard, ofstedInspectedDate,
|
||
|
|
oeifAllSameGrade, oeifAreas, variant = 'primary',
|
||
|
|
}: OfstedSectionProps) {
|
||
|
|
const isSecondary = variant === 'secondary';
|
||
|
|
|
||
|
|
return (
|
||
|
|
<Section id="ofsted">
|
||
|
|
<h2 className={styles.sectionTitle}>
|
||
|
|
{isReportCard ? 'Ofsted Report Card' : 'Ofsted Rating'}
|
||
|
|
{ofstedInspectedDate && (
|
||
|
|
<span className={styles.ofstedDate}>
|
||
|
|
{isSecondary && ' '}Inspected {new Date(ofstedInspectedDate).toLocaleDateString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' })}
|
||
|
|
</span>
|
||
|
|
)}
|
||
|
|
<a
|
||
|
|
href={`https://reports.ofsted.gov.uk/inspection-reports/find-inspection-report/provider/ELS/${urn}`}
|
||
|
|
target="_blank"
|
||
|
|
rel="noopener noreferrer"
|
||
|
|
className={styles.ofstedReportLink}
|
||
|
|
data-umami-event="external_link_clicked"
|
||
|
|
data-umami-event-target="ofsted"
|
||
|
|
>
|
||
|
|
Ofsted reports ↗
|
||
|
|
</a>
|
||
|
|
</h2>
|
||
|
|
|
||
|
|
{isReportCard ? (
|
||
|
|
/* ── New Report Card layout ── */
|
||
|
|
<>
|
||
|
|
<p className={styles.ofstedDisclaimer}>
|
||
|
|
From November 2025, Ofsted replaced single overall grades with Report Cards rating schools across several areas.
|
||
|
|
</p>
|
||
|
|
<div className={`${styles.metricsGrid} ${styles.gradeGrid}`}>
|
||
|
|
{ofsted.rc_safeguarding_met != null && (
|
||
|
|
<div className={styles.metricCard}>
|
||
|
|
<div className={styles.metricLabel}>Safeguarding</div>
|
||
|
|
<div className={`${styles.metricValue} ${ofsted.rc_safeguarding_met ? styles.safeguardingMet : styles.safeguardingNotMet}`}>
|
||
|
|
{ofsted.rc_safeguarding_met ? 'Met' : 'Not met'}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
{RC_CATEGORIES.map(({ key, label }) => {
|
||
|
|
const value = ofsted[key] as number | null;
|
||
|
|
return value != null ? (
|
||
|
|
<div key={key} className={styles.metricCard}>
|
||
|
|
<div className={styles.metricLabel}>{label}</div>
|
||
|
|
<div className={`${styles.metricValue} ${styles[`rcGrade${value}`]}`}>
|
||
|
|
{RC_LABELS[value]}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
) : null;
|
||
|
|
})}
|
||
|
|
</div>
|
||
|
|
</>
|
||
|
|
) : (!isSecondary || ofsted.overall_effectiveness) ? (
|
||
|
|
/* ── Old OEIF layout ── */
|
||
|
|
<>
|
||
|
|
<div className={styles.ofstedHeader}>
|
||
|
|
<span className={`${styles.ofstedGrade} ${styles[`ofstedGrade${ofsted.overall_effectiveness}`]}`}>
|
||
|
|
{ofsted.overall_effectiveness ? OFSTED_LABELS[ofsted.overall_effectiveness] : 'Not rated'}
|
||
|
|
</span>
|
||
|
|
{ofsted.previous_overall != null &&
|
||
|
|
ofsted.previous_overall !== ofsted.overall_effectiveness && (
|
||
|
|
<span className={styles.ofstedPrevious}>
|
||
|
|
Previously: {OFSTED_LABELS[ofsted.previous_overall]}
|
||
|
|
</span>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
<p className={styles.ofstedDisclaimer}>
|
||
|
|
{ofsted.grade_source === 'ungraded_carried_forward'
|
||
|
|
? 'This overall grade is carried forward from an earlier inspection — Ofsted has since visited without issuing a new overall grade. From September 2024, Ofsted no longer makes an overall effectiveness judgement.'
|
||
|
|
: isSecondary
|
||
|
|
? 'From September 2024, Ofsted no longer makes an overall effectiveness judgement in inspections.'
|
||
|
|
: 'From September 2024, Ofsted no longer makes an overall effectiveness judgement in inspections of state-funded schools.'}
|
||
|
|
</p>
|
||
|
|
{oeifAllSameGrade ? (
|
||
|
|
<p className={styles.ofstedAllSame}>
|
||
|
|
Rated <strong>{OFSTED_LABELS[ofsted.overall_effectiveness!]}</strong> across all inspected areas — Quality of Teaching, Behaviour, Pupils' Development and Leadership.
|
||
|
|
</p>
|
||
|
|
) : (
|
||
|
|
<div className={`${styles.metricsGrid} ${styles.gradeGrid}`}>
|
||
|
|
{oeifAreas.map(({ label, value }) => (
|
||
|
|
<div key={label} className={styles.metricCard}>
|
||
|
|
<div className={styles.metricLabel}>{label}</div>
|
||
|
|
<div className={`${styles.metricValue} ${styles[`ofstedGrade${value}`]}`}>
|
||
|
|
{OFSTED_LABELS[value]}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
</>
|
||
|
|
) : (
|
||
|
|
/* ── Secondary only: inspected since Sept 2024, no overall grade ── */
|
||
|
|
<>
|
||
|
|
<p className={styles.sectionSubtitle}>
|
||
|
|
From September 2024, Ofsted no longer gives a single overall grade.
|
||
|
|
</p>
|
||
|
|
<div className={`${styles.metricsGrid} ${styles.gradeGrid}`}>
|
||
|
|
{[
|
||
|
|
{ label: 'Quality of Education', value: ofsted.quality_of_education },
|
||
|
|
{ label: 'Behaviour & Attitudes', value: ofsted.behaviour_attitudes },
|
||
|
|
{ label: 'Personal Development', value: ofsted.personal_development },
|
||
|
|
{ label: 'Leadership & Management', value: ofsted.leadership_management },
|
||
|
|
].filter(({ value }) => value != null).map(({ label, value }) => (
|
||
|
|
<div key={label} className={styles.metricCard}>
|
||
|
|
<div className={styles.metricLabel}>{label}</div>
|
||
|
|
<div className={`${styles.metricValue} ${styles[`ofstedGrade${value}`]}`}>
|
||
|
|
{OFSTED_LABELS[value!]}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</>
|
||
|
|
)}
|
||
|
|
</Section>
|
||
|
|
);
|
||
|
|
}
|