feat: include and mark 'Open, but proposed to close' schools #22
@@ -44,3 +44,24 @@ describe('SecondarySchoolRow sixth-form tag', () => {
|
||||
expect(screen.queryByText('Sixth form')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('SecondarySchoolRow proposed-to-close tag', () => {
|
||||
it('shows the tag when GIAS status is "Open, but proposed to close"', () => {
|
||||
render(
|
||||
<SecondarySchoolRow
|
||||
school={{ ...base, status: 'Open, but proposed to close' }}
|
||||
/>,
|
||||
);
|
||||
expect(screen.getByText(/Proposed to close/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('hides the tag for a plain open school', () => {
|
||||
render(<SecondarySchoolRow school={{ ...base, status: 'Open' }} />);
|
||||
expect(screen.queryByText(/Proposed to close/)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('hides the tag when status is missing', () => {
|
||||
render(<SecondarySchoolRow school={base} />);
|
||||
expect(screen.queryByText(/Proposed to close/)).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -212,3 +212,14 @@ describe('computeYBounds', () => {
|
||||
expect(computeYBounds([], 'progress')).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isProposedToClose', () => {
|
||||
const { isProposedToClose } = require('@/lib/utils');
|
||||
|
||||
it('is true only for the exact GIAS proposed-to-close status', () => {
|
||||
expect(isProposedToClose({ status: 'Open, but proposed to close' })).toBe(true);
|
||||
expect(isProposedToClose({ status: 'Open' })).toBe(false);
|
||||
expect(isProposedToClose({ status: null })).toBe(false);
|
||||
expect(isProposedToClose({})).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1543,3 +1543,18 @@
|
||||
.historyDisclosure[open] > .historyToggle::before {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
/* GIAS "Open, but proposed to close" notice strip */
|
||||
.closingStrip {
|
||||
background: #fdf6e3;
|
||||
border-left: 4px solid #e2c96f;
|
||||
border-radius: 0 6px 6px 0;
|
||||
padding: 0.55rem 0.9rem;
|
||||
margin: 0.5rem 0;
|
||||
font-size: 0.88rem;
|
||||
color: #6e5a00;
|
||||
max-width: 68ch;
|
||||
}
|
||||
.closingStrip strong {
|
||||
color: #8a6200;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import type {
|
||||
SchoolDeprivation, SchoolFinance, NationalAverages,
|
||||
} from '@/lib/types';
|
||||
import {
|
||||
formatPercentage, formatProgress, formatAcademicYear,
|
||||
formatPercentage, formatProgress, formatAcademicYear, isProposedToClose,
|
||||
} from '@/lib/utils';
|
||||
import { DeltaChip } from './DeltaChip';
|
||||
|
||||
@@ -313,6 +313,13 @@ export function SchoolDetailView({
|
||||
<span className={styles.metaItem}>{schoolInfo.gender}'s school</span>
|
||||
)}
|
||||
</div>
|
||||
{isProposedToClose(schoolInfo) && (
|
||||
<div className={styles.closingStrip} role="note">
|
||||
<strong>⚠ Proposed to close</strong> — this school is proposed for closure,
|
||||
although a formal closure process has not necessarily started. Check with the
|
||||
local authority before applying.
|
||||
</div>
|
||||
)}
|
||||
{schoolInfo.address && (
|
||||
<p className={styles.address}>
|
||||
{schoolInfo.address}{schoolInfo.postcode && `, ${schoolInfo.postcode}`}
|
||||
|
||||
@@ -254,3 +254,10 @@
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
/* GIAS "Open, but proposed to close" marker */
|
||||
.attrClosing {
|
||||
background: #fdf6e3;
|
||||
color: #8a6200;
|
||||
border: 1px solid #e2c96f;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
import type { School } from '@/lib/types';
|
||||
import { formatPercentage, calculateTrend, getPhaseStyle, schoolUrl, buildOfstedListBadge, formatAgeRange } from '@/lib/utils';
|
||||
import { formatPercentage, calculateTrend, getPhaseStyle, schoolUrl, buildOfstedListBadge, formatAgeRange, isProposedToClose } from '@/lib/utils';
|
||||
import styles from './SchoolRow.module.css';
|
||||
|
||||
interface SchoolRowProps {
|
||||
@@ -78,6 +78,9 @@ export function SchoolRow({
|
||||
{school.age_range && <span className={styles.attr}>{formatAgeRange(school.age_range)}</span>}
|
||||
{showDenomination && <span className={styles.attr}>{school.religious_denomination}</span>}
|
||||
{showGender && <span className={styles.attr}>{school.gender}</span>}
|
||||
{isProposedToClose(school) && (
|
||||
<span className={`${styles.attr} ${styles.attrClosing}`}>⚠ Proposed to close</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Line 3: Key stats */}
|
||||
|
||||
@@ -1099,3 +1099,18 @@
|
||||
padding: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* GIAS "Open, but proposed to close" notice strip */
|
||||
.closingStrip {
|
||||
background: #fdf6e3;
|
||||
border-left: 4px solid #e2c96f;
|
||||
border-radius: 0 6px 6px 0;
|
||||
padding: 0.55rem 0.9rem;
|
||||
margin: 0.5rem 0;
|
||||
font-size: 0.88rem;
|
||||
color: #6e5a00;
|
||||
max-width: 68ch;
|
||||
}
|
||||
.closingStrip strong {
|
||||
color: #8a6200;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import type {
|
||||
SchoolAdmissions, SenDetail, Phonics,
|
||||
SchoolDeprivation, SchoolFinance, NationalAverages,
|
||||
} from '@/lib/types';
|
||||
import { formatPercentage, formatProgress, formatAcademicYear, formatAgeRange } from '@/lib/utils';
|
||||
import { formatPercentage, formatProgress, formatAcademicYear, formatAgeRange, isProposedToClose } from '@/lib/utils';
|
||||
import { DeltaChip } from './DeltaChip';
|
||||
import { track, getNavigationSource } from '@/lib/analytics';
|
||||
import styles from './SecondarySchoolDetailView.module.css';
|
||||
@@ -237,6 +237,13 @@ export function SecondarySchoolDetailView({
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{isProposedToClose(schoolInfo) && (
|
||||
<div className={styles.closingStrip} role="note">
|
||||
<strong>⚠ Proposed to close</strong> — this school is proposed for closure,
|
||||
although a formal closure process has not necessarily started. Check with the
|
||||
local authority before applying.
|
||||
</div>
|
||||
)}
|
||||
{schoolInfo.address && (
|
||||
<p className={styles.address}>
|
||||
{schoolInfo.address}{schoolInfo.postcode && `, ${schoolInfo.postcode}`}
|
||||
|
||||
@@ -266,3 +266,9 @@
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.closingTag {
|
||||
background: #fdf6e3;
|
||||
color: #8a6200;
|
||||
border: 1px solid #e2c96f;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
'use client';
|
||||
|
||||
import type { School } from '@/lib/types';
|
||||
import { buildOfstedListBadge, getPhaseStyle, schoolUrl, formatAgeRange } from '@/lib/utils';
|
||||
import { buildOfstedListBadge, getPhaseStyle, schoolUrl, formatAgeRange, isProposedToClose } from '@/lib/utils';
|
||||
import styles from './SecondarySchoolRow.module.css';
|
||||
|
||||
function detectAdmissionsTag(school: School): string | null {
|
||||
@@ -97,6 +97,9 @@ export function SecondarySchoolRow({
|
||||
{admissionsTag}
|
||||
</span>
|
||||
)}
|
||||
{isProposedToClose(school) && (
|
||||
<span className={`${styles.provisionTag} ${styles.closingTag}`}>⚠ Proposed to close</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Line 3: KS4 stats */}
|
||||
|
||||
@@ -18,6 +18,7 @@ export interface School {
|
||||
religious_denomination: string | null;
|
||||
age_range: string | null;
|
||||
has_sixth_form?: boolean | null;
|
||||
status?: string | null; // GIAS establishment status ("Open" / "Open, but proposed to close")
|
||||
|
||||
// Address
|
||||
address1: string | null;
|
||||
|
||||
@@ -718,3 +718,18 @@ export function buildOfstedListBadge(school: {
|
||||
|
||||
return { label: 'Not yet inspected', cssClass: 'ofstedPending' };
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Establishment status
|
||||
// ============================================================================
|
||||
|
||||
export const PROPOSED_TO_CLOSE_STATUS = 'Open, but proposed to close';
|
||||
|
||||
/**
|
||||
* GIAS lists some operating schools as "Open, but proposed to close".
|
||||
* They remain open (and may stay open if the proposal is withdrawn), but the
|
||||
* UI marks them so families check with the local authority before applying.
|
||||
*/
|
||||
export function isProposedToClose(school: { status?: string | null }): boolean {
|
||||
return school.status === PROPOSED_TO_CLOSE_STATUS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user