66 lines
2.6 KiB
TypeScript
66 lines
2.6 KiB
TypeScript
/**
|
|||
|
|
* 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, 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<string, string> = {
|
||
|
|
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<School, 'type_group' | 'school_type'>): 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 (school.admissions_policy?.trim().toLowerCase() === 'selective') 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;
|
||
|
|
}
|