/** * Who goes there — the school's community from the latest census plus GIAS * facts. Benchmark chips use the computed state-school averages and must * carry their provenance wording (never "England average" for computed * figures). Copy verbatim from the reviewed mockups. */ 'use client'; import { verdict } from '@/lib/compareLogic'; import type { Benchmarks, ComparisonData, School } from '@/lib/types'; import { Cell, Chip, Measure, Section, SectionGrid, sectionStyles as s } from './sectionShared'; function pctSplit(part: number | null | undefined, total: number | null | undefined): string | null { if (part == null || total == null || total === 0) return null; return `${Math.round((part / total) * 100)}%`; } export function CompareCommunity({ schools, data, benchmarks, isSecondary: propIsSecondary, }: { schools: School[]; data: Record; benchmarks?: Benchmarks; isSecondary?: boolean; }) { const isSecondary = propIsSecondary !== undefined ? propIsSecondary : schools.some( (school) => data[String(school.urn)]?.school_info?.attainment_8_score != null, ); const bench = isSecondary ? benchmarks?.secondary : benchmarks?.primary; const fsmChip = (value: number | null) => { // FSM is anchored only against a real FSM benchmark (census-sourced, // pupil-weighted). disadvantaged_pct is a different measure (FSM6+CLA) // — never fall back across definitions; no anchor means no chip. const anchor = bench?.fsm_pct ?? null; if (value == null || anchor == null) return null; const v = verdict(value, anchor, 3); return ( {v === 'above' && `Above the state-school average (${Math.round(anchor)}%)`} {v === 'close' && `About the state-school average (${Math.round(anchor)}%)`} {v === 'below' && `Below the state-school average (${Math.round(anchor)}%)`} ); }; const anyAllThrough = schools.some((school) => /all.?through/i.test(school.phase ?? '')); return (
The school's community, from the latest school census. State-school averages are computed from our dataset and shown for context — there's no “right” number here. {anyAllThrough && ( <> {' '} For all-through schools these figures cover the whole school, all ages — not just the {isSecondary ? 'secondary' : 'primary'} phase. )} } > {schools.map((school, i) => { const info = data[String(school.urn)]?.school_info as (School & { gias_total_pupils?: number | null; capacity?: number | null }) | undefined; const census = data[String(school.urn)]?.census; const pupils = census?.total_pupils ?? info?.gias_total_pupils ?? null; const capacity = info?.capacity ?? null; let capNote: string | null = null; if (pupils != null && capacity != null && capacity > 0) { capNote = pupils >= capacity ? `${capacity.toLocaleString('en-GB')} places — at or above capacity` : `of ${capacity.toLocaleString('en-GB')} places (${Math.round((pupils / capacity) * 100)}% full)`; } return ( {pupils != null ? ( <> {pupils.toLocaleString('en-GB')} {capNote && {capNote}} ) : ( No data )} ); })} {schools.map((school, i) => { const census = data[String(school.urn)]?.census; const girls = pctSplit(census?.female_pupils, census?.total_pupils); const boys = pctSplit(census?.male_pupils, census?.total_pupils); return ( {girls && boys ? `${girls} / ${boys}` : No data} ); })} {schools.map((school, i) => { const fsm = data[String(school.urn)]?.census?.fsm_pct ?? null; return ( {fsm != null ? ( <> {Math.round(fsm)}% {fsmChip(fsm)} ) : ( No data )} ); })} {schools.map((school, i) => { const eal = data[String(school.urn)]?.census?.eal_pct ?? null; return ( {eal != null ? `${Math.round(eal)}%` : No data} ); })} {schools.map((school, i) => { const rows = data[String(school.urn)]?.yearly_data ?? []; let sen: number | null = null; for (let r = rows.length - 1; r >= 0; r--) { if (rows[r].sen_support_pct != null) { sen = rows[r].sen_support_pct; break; } } const high = sen != null && bench?.sen_support_pct != null && sen >= bench.sen_support_pct * 1.75; return ( {sen != null ? ( <> {Math.round(sen)}% {high && Well above average} ) : ( No data )} ); })} {schools.map((school, i) => { const info = data[String(school.urn)]?.school_info; const faith = info?.religious_denomination; const none = !faith || faith === 'Does not apply' || faith === 'None'; return ( {none ? 'None' : faith} ); })} {schools.map((school, i) => { const info = data[String(school.urn)]?.school_info; return ( {info?.age_range || No data} ); })} {schools.map((school, i) => { const info = data[String(school.urn)]?.school_info; const trust = info?.trust_name; const la = info?.local_authority ?? school.local_authority; return ( {trust ? trust : la ? `${la} council` : No data} ); })}
); }