feat(destinations): the post-16 section, replacing the placeholder
The 'Post-16 destination data coming soon' note is deleted rather than reworded: for a school with no sixth form the truthful statement is that the question does not apply, and a placeholder there implies something is missing. hasSixthForm and .sixthFormNote go with it — nothing else used them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BvdDKvFFSZuMVDH5fEyTob
This commit is contained in:
1 parent
cef2f77149
commit
2b4cf20d75
5 files changed
+94
-18
No files matched your search
@@ -0,0 +1,45 @@
|
|||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
import { Post16DestinationsSection } from '@/components/school/Post16DestinationsSection';
|
||||||
|
import type { DestinationPhase } from '@/lib/types';
|
||||||
|
|
||||||
|
const phase: DestinationPhase = {
|
||||||
|
cohort_year: '2022/23',
|
||||||
|
groups: {
|
||||||
|
all: {
|
||||||
|
cohort: 96,
|
||||||
|
categories: [
|
||||||
|
{ category: 'higher_education', pupils: 56, percentage: 58.3, status: 'published' },
|
||||||
|
{ category: 'further_education', pupils: 12, percentage: 12.5, status: 'published' },
|
||||||
|
{ category: 'apprenticeship', pupils: 9, percentage: 9.4, status: 'published' },
|
||||||
|
{ category: 'employment', pupils: 13, percentage: 13.5, status: 'published' },
|
||||||
|
{ category: 'not_sustained', pupils: 6, percentage: 6.3, status: 'published' },
|
||||||
|
],
|
||||||
|
aggregates: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('Post16DestinationsSection', () => {
|
||||||
|
it('names the Year 13 cohort, not Year 11', () => {
|
||||||
|
const { container } = render(<Post16DestinationsSection destinations={phase} />);
|
||||||
|
expect(container.textContent).toMatch(/Year 13/);
|
||||||
|
expect(container.textContent).not.toMatch(/Year 11/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('reports higher education destinations', () => {
|
||||||
|
render(<Post16DestinationsSection destinations={phase} />);
|
||||||
|
expect(screen.getByText(/UK higher education/i)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('uses its own anchor so the nav does not collide with After Year 11', () => {
|
||||||
|
const { container } = render(<Post16DestinationsSection destinations={phase} />);
|
||||||
|
expect(container.querySelector('#post16-destinations')).toBeTruthy();
|
||||||
|
expect(container.querySelector('#destinations')).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders nothing when no group carries categories', () => {
|
||||||
|
const empty: DestinationPhase = { cohort_year: '2022/23', groups: {} };
|
||||||
|
const { container } = render(<Post16DestinationsSection destinations={empty} />);
|
||||||
|
expect(container.firstChild).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Post16DestinationsSection — where a school's Year 13 leavers went.
|
||||||
|
* Server component.
|
||||||
|
*
|
||||||
|
* A separate publication, a separate cohort and a separate question from
|
||||||
|
* After Year 11, so it is a separate section rather than a tab: a parent
|
||||||
|
* choosing a secondary and a student choosing a sixth form are not the same
|
||||||
|
* reader.
|
||||||
|
*
|
||||||
|
* Not rendered at all for a school without post-16 provision. A "no data"
|
||||||
|
* placeholder there would imply something is missing, when the truthful
|
||||||
|
* statement is that the question does not apply — which is why the old
|
||||||
|
* "Post-16 destination data coming soon" note is gone rather than reworded.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { DestinationPhase } from '@/lib/types';
|
||||||
|
import { Section, sectionStyles } from './sectionShared';
|
||||||
|
import { DestinationsView } from './DestinationsView';
|
||||||
|
|
||||||
|
export function Post16DestinationsSection({
|
||||||
|
destinations,
|
||||||
|
}: { destinations: DestinationPhase }) {
|
||||||
|
const hasContent = Object.values(destinations.groups)
|
||||||
|
.some(group => (group?.categories?.length ?? 0) > 0);
|
||||||
|
if (!hasContent) return null;
|
||||||
|
|
||||||
|
const cohort = destinations.groups.all?.cohort ?? null;
|
||||||
|
const year = destinations.cohort_year;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Section id="post16-destinations">
|
||||||
|
<h2 className={sectionStyles.sectionTitle}>After the sixth form</h2>
|
||||||
|
<p className={sectionStyles.sectionSubtitle}>
|
||||||
|
Where {cohort ? `the ${cohort} students` : 'the students'} who finished
|
||||||
|
Year 13{year ? ` in ${year}` : ''} went next.
|
||||||
|
</p>
|
||||||
|
<DestinationsView destinations={destinations} phase="ks5" />
|
||||||
|
</Section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
} from './lastDistanceOffered';
|
} from './lastDistanceOffered';
|
||||||
|
|
||||||
export function SecondaryAdmissionsSection({
|
export function SecondaryAdmissionsSection({
|
||||||
admissions, admissionsHistory, admissionDistance, schoolInfo, hasSixthForm,
|
admissions, admissionsHistory, admissionDistance, schoolInfo,
|
||||||
}: {
|
}: {
|
||||||
/* Nullable for the same reason as the primary section: a school can have a
|
/* Nullable for the same reason as the primary section: a school can have a
|
||||||
published cut-off and no EES admissions row. */
|
published cut-off and no EES admissions row. */
|
||||||
@@ -23,7 +23,6 @@ export function SecondaryAdmissionsSection({
|
|||||||
admissionsHistory: SchoolAdmissions[];
|
admissionsHistory: SchoolAdmissions[];
|
||||||
admissionDistance: SchoolAdmissionDistance | null;
|
admissionDistance: SchoolAdmissionDistance | null;
|
||||||
schoolInfo: School;
|
schoolInfo: School;
|
||||||
hasSixthForm: boolean;
|
|
||||||
}) {
|
}) {
|
||||||
const cutoff = describeCutoff(admissionDistance);
|
const cutoff = describeCutoff(admissionDistance);
|
||||||
// Moved with this section from SecondarySchoolDetailView, its only consumer.
|
// Moved with this section from SecondarySchoolDetailView, its only consumer.
|
||||||
@@ -112,11 +111,6 @@ export function SecondaryAdmissionsSection({
|
|||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{hasSixthForm && (
|
|
||||||
<div className={styles.sixthFormNote}>
|
|
||||||
This school has a sixth form (Post-16 provision). Post-16 destination data coming soon.
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -21,6 +21,7 @@ import type { SecondaryFlags } from '@/lib/schoolSections';
|
|||||||
import { OfstedSection } from './OfstedSection';
|
import { OfstedSection } from './OfstedSection';
|
||||||
import { GcseSection } from './GcseSection';
|
import { GcseSection } from './GcseSection';
|
||||||
import { DestinationsSection } from './DestinationsSection';
|
import { DestinationsSection } from './DestinationsSection';
|
||||||
|
import { Post16DestinationsSection } from './Post16DestinationsSection';
|
||||||
import { SecondaryAdmissionsSection } from './SecondaryAdmissionsSection';
|
import { SecondaryAdmissionsSection } from './SecondaryAdmissionsSection';
|
||||||
import { DistanceSection } from './DistanceSection';
|
import { DistanceSection } from './DistanceSection';
|
||||||
import { SecondaryHistorySection } from './SecondaryHistorySection';
|
import { SecondaryHistorySection } from './SecondaryHistorySection';
|
||||||
@@ -94,6 +95,12 @@ export function SecondarySchoolSections({
|
|||||||
<DestinationsSection destinations={destinations.ks4} />
|
<DestinationsSection destinations={destinations.ks4} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Sixth-form schools only. Absent, not placeheld, for a school with no
|
||||||
|
post-16 provision — the question simply does not apply there. */}
|
||||||
|
{flags.hasKs5Destinations && destinations?.ks5 && (
|
||||||
|
<Post16DestinationsSection destinations={destinations.ks5} />
|
||||||
|
)}
|
||||||
|
|
||||||
{/* See PrimarySchoolSections: distance and EES admissions are independent
|
{/* See PrimarySchoolSections: distance and EES admissions are independent
|
||||||
sources, so either one warrants the section. */}
|
sources, so either one warrants the section. */}
|
||||||
{(admissions || admissionDistance) && (
|
{(admissions || admissionDistance) && (
|
||||||
@@ -102,7 +109,6 @@ export function SecondarySchoolSections({
|
|||||||
admissionDistance={admissionDistance}
|
admissionDistance={admissionDistance}
|
||||||
admissionsHistory={admissionsHistory}
|
admissionsHistory={admissionsHistory}
|
||||||
schoolInfo={schoolInfo}
|
schoolInfo={schoolInfo}
|
||||||
hasSixthForm={flags.hasSixthForm}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -1883,15 +1883,7 @@
|
|||||||
color: var(--phase-secondary-text);
|
color: var(--phase-secondary-text);
|
||||||
border: 1px solid rgba(var(--status-above-rgb), 0.2);
|
border: 1px solid rgba(var(--status-above-rgb), 0.2);
|
||||||
}
|
}
|
||||||
.sixthFormNote {
|
|
||||||
margin-top: 1rem;
|
|
||||||
padding: 0.625rem 0.875rem;
|
|
||||||
background: var(--bg-secondary);
|
|
||||||
border-radius: 6px;
|
|
||||||
font-size: 0.825rem;
|
|
||||||
color: var(--text-secondary);
|
|
||||||
border-left: 3px solid var(--brand);
|
|
||||||
}
|
|
||||||
.genderSplitHint {
|
.genderSplitHint {
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
@@ -2107,7 +2099,6 @@
|
|||||||
border-top: 1px solid var(--border);
|
border-top: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.cutoffMapFigure {
|
.cutoffMapFigure {
|
||||||
/* Enough to read a set of concentric rings and no more — this is a
|
/* Enough to read a set of concentric rings and no more — this is a
|
||||||
diagram of a number, not a map anyone navigates by. */
|
diagram of a number, not a map anyone navigates by. */
|
||||||
|
|||||||
Reference in new issue
Block a user