From 96d5fcf5b07b6f175b48e9b20fcb765a320a907f Mon Sep 17 00:00:00 2001 From: Tudor Date: Fri, 24 Jul 2026 12:18:12 +0100 Subject: [PATCH] feat(detail): move religious character into header details + mobile reveal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Religious character now sits with the other labelled header details (near County / Constituency) as "Religious character: " ("None" for Does not apply / None), instead of as an identity chip. On mobile/tablet (≤768px) the header details block was hidden outright; it's now collapsed behind a "Show all details" toggle that reveals the full block (headteacher, website, pupils, trust, phone, religious character, county, constituency). Applied to both the primary and secondary detail views for parity. Extends the e2e journey with the mobile toggle behaviour. Co-Authored-By: Claude Opus 4.8 --- e2e/tests/journeys.spec.ts | 18 ++++++++++ .../components/SchoolDetailView.module.css | 34 ++++++++++++++++--- nextjs-app/components/SchoolDetailView.tsx | 33 +++++++++++++----- .../SecondarySchoolDetailView.module.css | 27 +++++++++++++++ .../components/SecondarySchoolDetailView.tsx | 32 ++++++++++++----- 5 files changed, 124 insertions(+), 20 deletions(-) diff --git a/e2e/tests/journeys.spec.ts b/e2e/tests/journeys.spec.ts index 2ed3e54..a8893eb 100644 --- a/e2e/tests/journeys.spec.ts +++ b/e2e/tests/journeys.spec.ts @@ -148,6 +148,24 @@ test('school detail page shows GIAS identity/contact details and drops the unwir } }); +test('header details collapse behind a "Show all details" toggle on mobile', async ({ page }) => { + await page.setViewportSize({ width: 390, height: 844 }); + const [urn] = await twoPrimaryUrns(page); + await page.goto(`/school/${urn}`); + await expect(page.locator('h1').first()).toBeVisible({ timeout: 15_000 }); + + // Collapsed by default on mobile/tablet … + const details = page.locator('#school-header-details'); + await expect(details).toBeHidden(); + const toggle = page.getByRole('button', { name: /show all details/i }); + await expect(toggle).toBeVisible(); + + // … and the link reveals them (label flips to "Hide details"). + await toggle.click(); + await expect(details).toBeVisible(); + await expect(page.getByRole('button', { name: /hide details/i })).toBeVisible(); +}); + test('a report-card school shows its report card, dated to the report-card inspection', async ({ page }) => { // Detail views detected report cards via `framework`, which the API never // sets to "ReportCard" — so report-card schools rendered as legacy ratings diff --git a/nextjs-app/components/SchoolDetailView.module.css b/nextjs-app/components/SchoolDetailView.module.css index 0ea36c2..5286103 100644 --- a/nextjs-app/components/SchoolDetailView.module.css +++ b/nextjs-app/components/SchoolDetailView.module.css @@ -197,6 +197,22 @@ text-decoration: underline; } +/* "Show all details" reveal — only rendered on mobile/tablet, where the + header details block is collapsed below the fold. Hidden on desktop. */ +.detailsToggle { + display: none; + align-items: center; + gap: 0.25rem; + margin-top: 0.5rem; + padding: 0; + background: none; + border: none; + font-size: 0.8125rem; + font-weight: 600; + color: var(--accent-teal, #2d7d7d); + cursor: pointer; +} + /* Gender split card — sits in the Pupils & Inclusion heroStatGrid */ .genderSplitValue { display: flex; @@ -1205,14 +1221,24 @@ gap: 0.375rem; } - /* Secondary header info (headteacher, website, pupil count, trust) - isn't needed above the fold on phones — pupil count lives in the - Pupils & Inclusion section, website is one scroll away. Reclaim - the ~3 vertical lines so the actual metrics surface sooner. */ + /* Secondary header info (headteacher, website, pupil count, trust, + contact, area) isn't needed above the fold on phones/tablets, so it's + collapsed by default and revealed on demand via the "Show all details" + link — reclaiming the vertical space so the metrics surface sooner. */ + .detailsToggle { + display: inline-flex; + } + .headerDetails { display: none; } + .headerDetailsOpen { + display: flex; + flex-direction: column; + gap: 0.375rem; + } + .metricsGrid { grid-template-columns: repeat(2, 1fr); } diff --git a/nextjs-app/components/SchoolDetailView.tsx b/nextjs-app/components/SchoolDetailView.tsx index adca63c..3a14cc7 100644 --- a/nextjs-app/components/SchoolDetailView.tsx +++ b/nextjs-app/components/SchoolDetailView.tsx @@ -99,6 +99,9 @@ export function SchoolDetailView({ const heroMapRef = useRef(null); // "All ▾" jump menu listing every section. const [sectionsOpen, setSectionsOpen] = useState(false); + // Header details (headteacher, contact, trust, area) collapse behind a + // "Show all details" link on mobile/tablet, where they're below the fold. + const [detailsOpen, setDetailsOpen] = useState(false); // Back returns to wherever the user came from; deep-links (no in-app history) // fall back to search so the button never dead-ends or leaves the site. @@ -354,13 +357,6 @@ export function SchoolDetailView({ {schoolInfo.age_range && ( {formatAgeRange(schoolInfo.age_range)} )} - {schoolInfo.religious_denomination && ( - - {['Does not apply', 'None'].includes(schoolInfo.religious_denomination) - ? 'None' - : schoolInfo.religious_denomination} - - )} {schoolInfo.nursery_provision && ( Nursery )} @@ -391,7 +387,20 @@ export function SchoolDetailView({ )}

)} -
+ +
{schoolInfo.headteacher_name && ( Headteacher: {schoolInfo.headteacher_name} @@ -433,6 +442,14 @@ export function SchoolDetailView({ )} + {schoolInfo.religious_denomination && ( + + Religious character:{' '} + {['Does not apply', 'None'].includes(schoolInfo.religious_denomination) + ? 'None' + : schoolInfo.religious_denomination} + + )} {schoolInfo.county && ( County: {schoolInfo.county} diff --git a/nextjs-app/components/SecondarySchoolDetailView.module.css b/nextjs-app/components/SecondarySchoolDetailView.module.css index a4f02e0..cf57443 100644 --- a/nextjs-app/components/SecondarySchoolDetailView.module.css +++ b/nextjs-app/components/SecondarySchoolDetailView.module.css @@ -207,6 +207,22 @@ text-decoration: underline; } +/* "Show all details" reveal — only rendered on mobile/tablet, where the + header details block is collapsed below the fold. Hidden on desktop. */ +.detailsToggle { + display: none; + align-items: center; + gap: 0.25rem; + margin-top: 0.5rem; + padding: 0; + background: none; + border: none; + font-size: 0.8125rem; + font-weight: 600; + color: var(--accent-teal, #2d7d7d); + cursor: pointer; +} + .actions { display: flex; gap: 0.5rem; @@ -1066,7 +1082,18 @@ padding: 0.1rem 0.375rem; } + /* Collapsed below the fold on phones/tablets; revealed via "Show all + details" so the metrics surface sooner. */ + .detailsToggle { + display: inline-flex; + } + .headerDetails { + display: none; + } + + .headerDetailsOpen { + display: flex; flex-direction: column; gap: 0.375rem; } diff --git a/nextjs-app/components/SecondarySchoolDetailView.tsx b/nextjs-app/components/SecondarySchoolDetailView.tsx index 1304a36..dedd252 100644 --- a/nextjs-app/components/SecondarySchoolDetailView.tsx +++ b/nextjs-app/components/SecondarySchoolDetailView.tsx @@ -83,6 +83,8 @@ export function SecondarySchoolDetailView({ const isInComparison = isSelected(schoolInfo.urn); const [activeSection, setActiveSection] = useState(''); + // Header details collapse behind a "Show all details" link on mobile/tablet. + const [detailsOpen, setDetailsOpen] = useState(false); const latestResults = yearlyData.length > 0 ? yearlyData[yearlyData.length - 1] : null; @@ -246,13 +248,6 @@ export function SecondarySchoolDetailView({ {schoolInfo.age_range && ( {formatAgeRange(schoolInfo.age_range)} )} - {schoolInfo.religious_denomination && ( - - {['Does not apply', 'None'].includes(schoolInfo.religious_denomination) - ? 'None' - : schoolInfo.religious_denomination} - - )} {schoolInfo.nursery_provision && ( Nursery )} @@ -288,7 +283,20 @@ export function SecondarySchoolDetailView({ )}

)} -
+ +
{schoolInfo.headteacher_name && ( Headteacher: {schoolInfo.headteacher_name} @@ -326,6 +334,14 @@ export function SecondarySchoolDetailView({ )} + {schoolInfo.religious_denomination && ( + + Religious character:{' '} + {['Does not apply', 'None'].includes(schoolInfo.religious_denomination) + ? 'None' + : schoolInfo.religious_denomination} + + )} {schoolInfo.county && ( County: {schoolInfo.county} -- 2.54.0