/** * SchoolDetailView Component * Displays comprehensive school information with performance charts */ 'use client'; import { useRouter } from 'next/navigation'; import { useComparison } from '@/hooks/useComparison'; import { PerformanceChart } from './PerformanceChart'; import { SchoolMap } from './SchoolMap'; import type { School, SchoolResult, AbsenceData, OfstedInspection, OfstedParentView, SchoolCensus, SchoolAdmissions, SenDetail, Phonics, SchoolDeprivation, SchoolFinance, } from '@/lib/types'; import { formatPercentage, formatProgress, calculateTrend } from '@/lib/utils'; import styles from './SchoolDetailView.module.css'; const OFSTED_LABELS: Record = { 1: 'Outstanding', 2: 'Good', 3: 'Requires Improvement', 4: 'Inadequate', }; interface SchoolDetailViewProps { schoolInfo: School; yearlyData: SchoolResult[]; absenceData: AbsenceData | null; ofsted: OfstedInspection | null; parentView: OfstedParentView | null; census: SchoolCensus | null; admissions: SchoolAdmissions | null; senDetail: SenDetail | null; phonics: Phonics | null; deprivation: SchoolDeprivation | null; finance: SchoolFinance | null; } export function SchoolDetailView({ schoolInfo, yearlyData, absenceData, ofsted, parentView, census, admissions, senDetail, phonics, deprivation, finance, }: SchoolDetailViewProps) { const router = useRouter(); const { addSchool, removeSchool, isSelected } = useComparison(); const isInComparison = isSelected(schoolInfo.urn); // Get latest results const latestResults = yearlyData.length > 0 ? yearlyData[yearlyData.length - 1] : null; // Handle add/remove from comparison const handleComparisonToggle = () => { if (isInComparison) { removeSchool(schoolInfo.urn); } else { addSchool(schoolInfo); } }; return (
{/* Back Navigation */}
{/* Header Section */}

{schoolInfo.school_name}

{schoolInfo.local_authority && ( {schoolInfo.local_authority} )} {schoolInfo.school_type && ( {schoolInfo.school_type} )}
{schoolInfo.address && (

{schoolInfo.address} {schoolInfo.postcode && `, ${schoolInfo.postcode}`}

)}
{/* Latest Results Summary */} {latestResults && (

Latest Results ({latestResults.year})

{latestResults.rwm_expected_pct !== null && (
RWM Expected Standard
{formatPercentage(latestResults.rwm_expected_pct)}
)} {latestResults.rwm_high_pct !== null && (
RWM Higher Standard
{formatPercentage(latestResults.rwm_high_pct)}
)} {latestResults.reading_progress !== null && (
Reading Progress
{formatProgress(latestResults.reading_progress)}
)} {latestResults.writing_progress !== null && (
Writing Progress
{formatProgress(latestResults.writing_progress)}
)} {latestResults.maths_progress !== null && (
Maths Progress
{formatProgress(latestResults.maths_progress)}
)}
{(latestResults.reading_progress !== null || latestResults.writing_progress !== null || latestResults.maths_progress !== null) && (

Progress scores: 0 = national average. Positive = above average, negative = below average.

)}
)} {/* Map */} {schoolInfo.latitude && schoolInfo.longitude && (

Location

)} {/* Performance Over Time */} {yearlyData.length > 0 && (

Performance Over Time

)} {/* Detailed Metrics */} {latestResults && (

Detailed Metrics

{/* Reading Metrics */}

Reading

{latestResults.reading_expected_pct !== null && (
Expected {formatPercentage(latestResults.reading_expected_pct)}
)} {latestResults.reading_high_pct !== null && (
Higher {formatPercentage(latestResults.reading_high_pct)}
)} {latestResults.reading_progress !== null && (
Progress {formatProgress(latestResults.reading_progress)}
)} {latestResults.reading_avg_score !== null && (
Avg Score {latestResults.reading_avg_score.toFixed(1)}
)}
{/* Writing Metrics */}

Writing

{latestResults.writing_expected_pct !== null && (
Expected {formatPercentage(latestResults.writing_expected_pct)}
)} {latestResults.writing_high_pct !== null && (
Higher {formatPercentage(latestResults.writing_high_pct)}
)} {latestResults.writing_progress !== null && (
Progress {formatProgress(latestResults.writing_progress)}
)}
{/* Maths Metrics */}

Maths

{latestResults.maths_expected_pct !== null && (
Expected {formatPercentage(latestResults.maths_expected_pct)}
)} {latestResults.maths_high_pct !== null && (
Higher {formatPercentage(latestResults.maths_high_pct)}
)} {latestResults.maths_progress !== null && (
Progress {formatProgress(latestResults.maths_progress)}
)} {latestResults.maths_avg_score !== null && (
Avg Score {latestResults.maths_avg_score.toFixed(1)}
)}
)} {/* Absence Data */} {absenceData && (

Absence Data

{absenceData.overall_absence_rate !== null && (
Overall Absence Rate
{formatPercentage(absenceData.overall_absence_rate)}
)} {absenceData.persistent_absence_rate !== null && (
Persistent Absence
{formatPercentage(absenceData.persistent_absence_rate)}
)}
)} {/* All Years Data Table */} {yearlyData.length > 0 && (

Historical Data

{yearlyData.map((result) => ( ))}
Year RWM Expected RWM Higher Reading Progress Writing Progress Maths Progress
{result.year} {result.rwm_expected_pct !== null ? formatPercentage(result.rwm_expected_pct) : '-'} {result.rwm_high_pct !== null ? formatPercentage(result.rwm_high_pct) : '-'} {result.reading_progress !== null ? formatProgress(result.reading_progress) : '-'} {result.writing_progress !== null ? formatProgress(result.writing_progress) : '-'} {result.maths_progress !== null ? formatProgress(result.maths_progress) : '-'}
)} {/* Ofsted Section */} {ofsted && (

Ofsted Inspection

{ofsted.overall_effectiveness ? OFSTED_LABELS[ofsted.overall_effectiveness] : 'Not rated'} {ofsted.inspection_date && ( Inspected: {new Date(ofsted.inspection_date).toLocaleDateString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' })} )}
{[ { 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 }, ...(ofsted.early_years_provision != null ? [{ label: 'Early Years', value: ofsted.early_years_provision }] : []), ].map(({ label, value }) => value != null && (
{label}
{OFSTED_LABELS[value]}
))}
{ofsted.inspection_type && (

{ofsted.inspection_type}

)}
)} {/* What Parents Think */} {parentView && parentView.total_responses != null && parentView.total_responses > 0 && (

What Parents Think

Based on {parentView.total_responses.toLocaleString()} parent responses to the Ofsted Parent View survey.

{[ { label: 'My child is happy here', pct: parentView.q_happy_pct }, { label: 'My child feels safe here', pct: parentView.q_safe_pct }, { label: 'Would recommend this school', pct: parentView.q_recommend_pct }, { label: 'Teaching is good', pct: parentView.q_teaching_pct }, { label: 'My child makes good progress', pct: parentView.q_progress_pct }, { label: 'School looks after wellbeing', pct: parentView.q_wellbeing_pct }, { label: 'Led and managed effectively', pct: parentView.q_leadership_pct }, { label: 'Behaviour is well managed', pct: parentView.q_behaviour_pct }, { label: 'Communicates well with parents', pct: parentView.q_communication_pct }, ].filter(q => q.pct != null).map(({ label, pct }) => (
{label}
{pct}%
))}
)} {/* Admissions */} {admissions && (

Admissions ({admissions.year})

{admissions.published_admission_number != null && (
Places available
{admissions.published_admission_number}
)} {admissions.total_applications != null && (
Applications received
{admissions.total_applications.toLocaleString()}
)} {admissions.first_preference_offers_pct != null && (
Got first choice
{admissions.first_preference_offers_pct}%
)} {admissions.oversubscribed != null && (
Oversubscribed
{admissions.oversubscribed ? 'Yes' : 'No'}
)}
)} {/* Pupils & Inclusion (Census + SEN) */} {(census || senDetail) && (

Pupils & Inclusion

{census?.class_size_avg != null && (
Average class size
{census.class_size_avg.toFixed(1)}
)}
{senDetail && ( <>

Primary SEN Needs (latest year)

{[ { label: 'Speech & Language', pct: senDetail.primary_need_speech_pct }, { label: 'Autism (ASD)', pct: senDetail.primary_need_autism_pct }, { label: 'Learning Difficulties', pct: senDetail.primary_need_mld_pct }, { label: 'Specific Learning (Dyslexia etc.)', pct: senDetail.primary_need_spld_pct }, { label: 'Social, Emotional & Mental Health', pct: senDetail.primary_need_semh_pct }, { label: 'Physical / Sensory', pct: senDetail.primary_need_physical_pct }, ].filter(n => n.pct != null).map(({ label, pct }) => (
{label}
{pct}%
))}
)}
)} {/* Year 1 Phonics */} {phonics && phonics.year1_phonics_pct != null && (

Year 1 Phonics ({phonics.year})

Reached expected standard
{formatPercentage(phonics.year1_phonics_pct)}
{phonics.year2_phonics_pct != null && (
Year 2 (re-takers) standard
{formatPercentage(phonics.year2_phonics_pct)}
)}
)} {/* Deprivation Context */} {deprivation && deprivation.idaci_decile != null && (

Deprivation Context

Area deprivation decile
{deprivation.idaci_decile} / 10
1 = most deprived, 10 = least deprived
{deprivation.idaci_score != null && (
IDACI score
{deprivation.idaci_score.toFixed(3)}
)}
)} {/* Finances */} {finance && finance.per_pupil_spend != null && (

Finances ({finance.year})

{finance.per_pupil_spend != null && (
Spend per pupil
£{Math.round(finance.per_pupil_spend).toLocaleString()}
)} {finance.teacher_cost_pct != null && (
Teacher costs
{finance.teacher_cost_pct.toFixed(1)}% of budget
)} {finance.staff_cost_pct != null && (
All staff costs
{finance.staff_cost_pct.toFixed(1)}% of budget
)}
)}
); }