From 2b4cf20d75e6be1bc622cad2a7b9c71f13d12312 Mon Sep 17 00:00:00 2001
From: Tudor
Date: Fri, 28 Aug 2026 16:15:21 +0100
Subject: [PATCH] feat(destinations): the post-16 section, replacing the
placeholder
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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
Claude-Session: https://claude.ai/code/session_01BvdDKvFFSZuMVDH5fEyTob
---
.../Post16DestinationsSection.test.tsx | 45 +++++++++++++++++++
.../school/Post16DestinationsSection.tsx | 40 +++++++++++++++++
.../school/SecondaryAdmissionsSection.tsx | 8 +---
.../school/SecondarySchoolSections.tsx | 8 +++-
.../school/schoolSections.module.css | 11 +----
5 files changed, 94 insertions(+), 18 deletions(-)
create mode 100644 nextjs-app/__tests__/components/Post16DestinationsSection.test.tsx
create mode 100644 nextjs-app/components/school/Post16DestinationsSection.tsx
diff --git a/nextjs-app/__tests__/components/Post16DestinationsSection.test.tsx b/nextjs-app/__tests__/components/Post16DestinationsSection.test.tsx
new file mode 100644
index 0000000..946d88f
--- /dev/null
+++ b/nextjs-app/__tests__/components/Post16DestinationsSection.test.tsx
@@ -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();
+ expect(container.textContent).toMatch(/Year 13/);
+ expect(container.textContent).not.toMatch(/Year 11/);
+ });
+
+ it('reports higher education destinations', () => {
+ render();
+ 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();
+ 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();
+ expect(container.firstChild).toBeNull();
+ });
+});
diff --git a/nextjs-app/components/school/Post16DestinationsSection.tsx b/nextjs-app/components/school/Post16DestinationsSection.tsx
new file mode 100644
index 0000000..e5113eb
--- /dev/null
+++ b/nextjs-app/components/school/Post16DestinationsSection.tsx
@@ -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 (
+
+ After the sixth form
+
+ Where {cohort ? `the ${cohort} students` : 'the students'} who finished
+ Year 13{year ? ` in ${year}` : ''} went next.
+
+
+
+ );
+}
diff --git a/nextjs-app/components/school/SecondaryAdmissionsSection.tsx b/nextjs-app/components/school/SecondaryAdmissionsSection.tsx
index 49c8970..73a8e36 100644
--- a/nextjs-app/components/school/SecondaryAdmissionsSection.tsx
+++ b/nextjs-app/components/school/SecondaryAdmissionsSection.tsx
@@ -15,7 +15,7 @@ import {
} from './lastDistanceOffered';
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
published cut-off and no EES admissions row. */
@@ -23,7 +23,6 @@ export function SecondaryAdmissionsSection({
admissionsHistory: SchoolAdmissions[];
admissionDistance: SchoolAdmissionDistance | null;
schoolInfo: School;
- hasSixthForm: boolean;
}) {
const cutoff = describeCutoff(admissionDistance);
// Moved with this section from SecondarySchoolDetailView, its only consumer.
@@ -112,11 +111,6 @@ export function SecondaryAdmissionsSection({
)}
- {hasSixthForm && (
-
- This school has a sixth form (Post-16 provision). Post-16 destination data coming soon.
-
- )}
);
}
diff --git a/nextjs-app/components/school/SecondarySchoolSections.tsx b/nextjs-app/components/school/SecondarySchoolSections.tsx
index 8530f47..f3542ef 100644
--- a/nextjs-app/components/school/SecondarySchoolSections.tsx
+++ b/nextjs-app/components/school/SecondarySchoolSections.tsx
@@ -21,6 +21,7 @@ import type { SecondaryFlags } from '@/lib/schoolSections';
import { OfstedSection } from './OfstedSection';
import { GcseSection } from './GcseSection';
import { DestinationsSection } from './DestinationsSection';
+import { Post16DestinationsSection } from './Post16DestinationsSection';
import { SecondaryAdmissionsSection } from './SecondaryAdmissionsSection';
import { DistanceSection } from './DistanceSection';
import { SecondaryHistorySection } from './SecondaryHistorySection';
@@ -94,6 +95,12 @@ export function SecondarySchoolSections({
)}
+ {/* 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 && (
+
+ )}
+
{/* See PrimarySchoolSections: distance and EES admissions are independent
sources, so either one warrants the section. */}
{(admissions || admissionDistance) && (
@@ -102,7 +109,6 @@ export function SecondarySchoolSections({
admissionDistance={admissionDistance}
admissionsHistory={admissionsHistory}
schoolInfo={schoolInfo}
- hasSixthForm={flags.hasSixthForm}
/>
)}
diff --git a/nextjs-app/components/school/schoolSections.module.css b/nextjs-app/components/school/schoolSections.module.css
index 7e26d29..931fee0 100644
--- a/nextjs-app/components/school/schoolSections.module.css
+++ b/nextjs-app/components/school/schoolSections.module.css
@@ -1883,15 +1883,7 @@
color: var(--phase-secondary-text);
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 {
font-size: 0.7rem;
color: var(--text-muted);
@@ -2107,7 +2099,6 @@
border-top: 1px solid var(--border);
}
-
.cutoffMapFigure {
/* Enough to read a set of concentric rings and no more — this is a
diagram of a number, not a map anyone navigates by. */