/** * The facts the school header and the search rows print, so a parent reads * the same words in the list and on the page. * * Every value comes from one register field. Nothing is inferred or explained * inline, and a missing field prints nothing. */ import type { School } from './types'; import { hasNurseryClasses, hasReligiousCharacter, isSelective, singleSexLabel } from './utils'; /** The search filter's type groups (backend/school_groups.py), without its * parenthesised notes: fees have a flag of their own. */ const TYPE_GROUP_LABELS: Record = { state: 'State school', independent: 'Independent school', special: 'Special school (SEND)', post16: 'Sixth form or college', alternative: 'Alternative provision', }; /** The school's type in the search filter's terms, or the register's own name * for a type in no group (secure units, online providers). */ export function schoolTypeLabel(school: Pick): string | null { const grouped = school.type_group ? TYPE_GROUP_LABELS[school.type_group] : undefined; return grouped ?? (school.school_type?.trim() || null); } /** "condition": changes who can apply or what it costs. * "provision": what the school offers. */ export type SchoolFlagKind = 'condition' | 'provision'; export interface SchoolFlag { label: string; kind: SchoolFlagKind; } type FlagFields = Pick< School, 'type_group' | 'admissions_policy' | 'gender' | 'religious_denomination' | 'nursery_provision' | 'has_sixth_form' | 'phase' >; /** * Flags for what applies, in a fixed order: conditions first, then provision. * * Selective needs the exact value. The register files a partly selective * school as "Non-selective", so that value is never printed. */ export function schoolFlags(school: FlagFields): SchoolFlag[] { const flags: SchoolFlag[] = []; const condition = (label: string) => flags.push({ label, kind: 'condition' }); const provision = (label: string) => flags.push({ label, kind: 'provision' }); const phase = school.phase?.trim().toLowerCase(); if (school.type_group === 'independent') condition('Fee-paying'); if (isSelective(school.admissions_policy)) condition('Selective'); const singleSex = singleSexLabel(school.gender); if (singleSex) condition(singleSex); if (hasReligiousCharacter(school.religious_denomination)) { condition(school.religious_denomination!.trim()); } if (hasNurseryClasses(school.nursery_provision) && phase !== 'nursery') provision('Nursery class'); if (school.has_sixth_form && phase !== '16 plus') provision('Sixth form'); return flags; }