diff --git a/nextjs-app/components/SchoolRow.tsx b/nextjs-app/components/SchoolRow.tsx index 6ff255b..dac2186 100644 --- a/nextjs-app/components/SchoolRow.tsx +++ b/nextjs-app/components/SchoolRow.tsx @@ -2,30 +2,23 @@ * SchoolRow Component * Four-line row for primary school search results * - * Line 1: School name · Ofsted badge + * Line 1: School name · Ofsted badge (framework-aware) * Line 2: School type · Age range · Denomination · Gender - * Line 3: R,W&M % · Progress score · Pupil count - * Line 4: Local authority · Distance + * Line 3: Reading, Writing & Maths % · trend arrow · vs-national delta · Pupils + * Line 4: Local authority · Distance */ import type { School } from '@/lib/types'; -import { formatPercentage, formatProgress, calculateTrend, getPhaseStyle, schoolUrl } from '@/lib/utils'; -import { progressBand } from '@/lib/metrics'; +import { formatPercentage, calculateTrend, getPhaseStyle, schoolUrl, buildOfstedListBadge } from '@/lib/utils'; import styles from './SchoolRow.module.css'; -const OFSTED_LABELS: Record = { - 1: 'Outstanding', - 2: 'Good', - 3: 'Req. Improvement', - 4: 'Inadequate', -}; - interface SchoolRowProps { school: School; isLocationSearch?: boolean; isInCompare?: boolean; onAddToCompare?: (school: School) => void; onRemoveFromCompare?: (urn: number) => void; + nationalAvgRwm?: number | null; } export function SchoolRow({ @@ -34,13 +27,22 @@ export function SchoolRow({ isInCompare = false, onAddToCompare, onRemoveFromCompare, + nationalAvgRwm, }: SchoolRowProps) { const trend = calculateTrend(school.rwm_expected_pct, school.prev_rwm_expected_pct); const phase = getPhaseStyle(school.phase); + const ofstedBadge = buildOfstedListBadge(school); - // Use reading progress as representative; fall back to writing, then maths - const progressScore = - school.reading_progress ?? school.writing_progress ?? school.maths_progress ?? null; + const showGender = school.gender && school.gender.toLowerCase() !== 'mixed'; + const showDenomination = + school.religious_denomination && + school.religious_denomination !== 'Does not apply'; + + // vs-national delta + const rwmDelta = + school.rwm_expected_pct != null && nationalAvgRwm != null + ? Math.round(school.rwm_expected_pct - nationalAvgRwm) + : null; const handleCompareClick = () => { if (isInCompare) { @@ -50,11 +52,6 @@ export function SchoolRow({ } }; - const showGender = school.gender && school.gender.toLowerCase() !== 'mixed'; - const showDenomination = - school.religious_denomination && - school.religious_denomination !== 'Does not apply'; - return (
{/* Left: four content lines */} @@ -65,16 +62,9 @@ export function SchoolRow({ {school.school_name} - {school.ofsted_grade && ( - - {OFSTED_LABELS[school.ofsted_grade]} - {school.ofsted_date && ( - - {' '}({new Date(school.ofsted_date).getFullYear()}) - - )} - - )} + + {ofstedBadge.label} +
{/* Line 2: Context tags */} @@ -92,50 +82,51 @@ export function SchoolRow({ {/* Line 3: Key stats */}
- {school.rwm_expected_pct != null ? ( - - - {formatPercentage(school.rwm_expected_pct, 0)} - - {school.prev_rwm_expected_pct != null && ( - - {trend === 'up' && ( - - - - )} - {trend === 'down' && ( - - - - )} - {trend === 'stable' && ( - - - - )} - - )} - R, W & M - - ) : ( - - - R, W & M - - )} - - {progressScore != null && ( - - {formatProgress(progressScore)} - - progress · {progressBand(progressScore)} + + + {school.rwm_expected_pct != null ? formatPercentage(school.rwm_expected_pct, 0) : '—'} + + {school.prev_rwm_expected_pct != null && ( + + {trend === 'up' && ( + + + + )} + {trend === 'down' && ( + + + + )} + {trend === 'stable' && ( + + + + )} - - )} + )} + Reading, Writing & Maths + {rwmDelta != null && ( + = 2 + ? styles.vsNational + : rwmDelta <= -2 + ? styles.vsNationalNeg + : styles.vsNationalFlat + } + > + {rwmDelta >= 2 + ? `+${rwmDelta} pts vs national` + : rwmDelta <= -2 + ? `${rwmDelta} pts vs national` + : '≈ national avg'} + + )} + {school.total_pupils != null && (