feat(ux): 8 UX improvements — simpler home, advanced filters, phase tabs, 4-line rows
All checks were successful
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 48s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m13s
Build and Push Docker Images / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 32s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s

1. Simpler home page: only search box on landing, no filter dropdowns
2. Advanced filters: hidden behind toggle on results page, auto-open if active
3. Per-school phase rendering: each row renders based on its own data
4. Taller 4-line rows with context line (type, age range, denomination, gender)
5. Result-scoped filters: dropdown values reflect current search results
6. Fix blank filter values: exclude empty strings and "Not applicable"
7. Rankings: Primary/Secondary phase tabs with phase-specific metrics
8. Compare: Primary/Secondary tabs with school counts and phase metrics

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-29 08:57:06 +01:00
parent e8175561d5
commit 1d22877aec
14 changed files with 735 additions and 408 deletions

View File

@@ -1,10 +1,11 @@
/**
* SecondarySchoolRow Component
* Three-line row for secondary school search results
* Four-line row for secondary school search results
*
* Line 1: School name · School type · Ofsted badge
* Line 2: Attainment 8 (large) · ±LA avg delta · Eng & Maths 4+ · Pupils
* Line 3: LA name · gender tag · sixth form tag · admissions tag · distance
* Line 1: School name · Ofsted badge
* Line 2: School type · Age range · Gender · Sixth form · Admissions tag
* Line 3: Attainment 8 (large) · ±LA avg delta · Eng & Maths 4+ · Pupils
* Line 4: LA name · distance
*/
'use client';
@@ -67,17 +68,14 @@ export function SecondarySchoolRow({
return (
<div className={`${styles.row} ${isInCompare ? styles.rowInCompare : ''}`}>
{/* Left: three content lines */}
{/* Left: four content lines */}
<div className={styles.rowContent}>
{/* Line 1: School name + type + Ofsted badge */}
{/* Line 1: School name + Ofsted badge */}
<div className={styles.line1}>
<a href={`/school/${school.urn}`} className={styles.schoolName}>
{school.school_name}
</a>
{school.school_type && (
<span className={styles.schoolType}>{school.school_type}</span>
)}
{school.ofsted_grade && (
<span className={`${styles.ofstedBadge} ${styles[`ofsted${school.ofsted_grade}`]}`}>
{OFSTED_LABELS[school.ofsted_grade]}
@@ -90,8 +88,25 @@ export function SecondarySchoolRow({
)}
</div>
{/* Line 2: KS4 stats */}
{/* Line 2: Context tags */}
<div className={styles.line2}>
{school.school_type && <span>{school.school_type}</span>}
{school.age_range && <span>{school.age_range}</span>}
{showGender && (
<span className={styles.provisionTag}>{school.gender}</span>
)}
{sixthForm && (
<span className={styles.provisionTag}>Sixth form</span>
)}
{admissionsTag && (
<span className={`${styles.provisionTag} ${admissionsTag === 'Selective' ? styles.selectiveTag : ''}`}>
{admissionsTag}
</span>
)}
</div>
{/* Line 3: KS4 stats */}
<div className={styles.line3}>
<span className={styles.stat}>
<strong className={styles.statValueLarge}>
{att8 != null ? att8.toFixed(1) : '—'}
@@ -124,22 +139,11 @@ export function SecondarySchoolRow({
)}
</div>
{/* Line 3: Location + tags */}
<div className={styles.line3}>
{/* Line 4: Location + distance */}
<div className={styles.line4}>
{school.local_authority && (
<span>{school.local_authority}</span>
)}
{showGender && (
<span className={styles.provisionTag}>{school.gender}</span>
)}
{sixthForm && (
<span className={styles.provisionTag}>Sixth form</span>
)}
{admissionsTag && (
<span className={`${styles.provisionTag} ${admissionsTag === 'Selective' ? styles.selectiveTag : ''}`}>
{admissionsTag}
</span>
)}
{isLocationSearch && school.distance != null && (
<span className={styles.distanceBadge}>
{school.distance.toFixed(1)} mi