fix(school-detail): hero Ofsted chip mislabels OEIF schools as Report Card
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 13s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 45s
Build and Push Docker Images / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s

The API returns ``framework`` as the literal string "NULL" for older OEIF
inspections (it comes from the upstream ``event_type_grouping`` column),
not real null. The original render path checks ``=== 'ReportCard'`` and
correctly treats anything else as OEIF — but buildOfstedHeroChip inverted
that and treated anything not exactly equal to ``'OEIF'`` as Report Card,
so OLQH (inspected Nov 2023, Outstanding) was being labelled as a Report
Card school in the hero strip and the at-a-glance tile.

- Invert the helper: only branch into Report Card when framework is
  explicitly ``'ReportCard'``; treat OEIF / null / "NULL" / anything else
  as OEIF, and require ``overall_effectiveness`` to render the grade word.
- Replace the toneClass field (which reused .ofstedGrade{N} / .rcGrade{N}
  badge classes and dragged in their backgrounds) with a clean tone enum
  ``teal | green | gold | coral | neutral``. The serif Ofsted heroStat
  picked up the badge background and rendered as a green box around
  "Report Card" — gone now.
- Hero chip backgrounds use color-mix() against the tone variable so all
  five tones share one rule.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Tudor Sitaru
2026-04-08 10:44:37 +01:00
parent c749d72a6a
commit 2d6e39eebc
3 changed files with 70 additions and 70 deletions
+5 -5
View File
@@ -213,7 +213,7 @@ export function SchoolDetailView({
{/* Hero signal chip strip */}
<div className={styles.heroChips}>
<div className={`${styles.heroChip} ${styles[ofstedHeroChip.toneClass] ?? ''}`}>
<div className={`${styles.heroChip} ${styles[`tone-${ofstedHeroChip.tone}`]}`}>
<div className={styles.heroChipTitle}>{ofstedHeroChip.title}</div>
<div className={styles.heroChipSub}>{ofstedHeroChip.subtitle}</div>
{ofstedHeroChip.detail && (
@@ -222,7 +222,7 @@ export function SchoolDetailView({
</div>
{admissions?.oversubscribed && (
<div className={`${styles.heroChip} ${styles.heroChipWarn}`}>
<div className={`${styles.heroChip} ${styles['tone-gold']}`}>
<div className={styles.heroChipTitle}>Oversubscribed</div>
<div className={styles.heroChipSub}>
{admissions.first_preference_offer_pct != null
@@ -233,7 +233,7 @@ export function SchoolDetailView({
)}
{isPrimary && heroRwm != null && heroRwmNat != null && heroRwm > heroRwmNat && (
<div className={`${styles.heroChip} ${styles.heroChipGood}`}>
<div className={`${styles.heroChip} ${styles['tone-teal']}`}>
<div className={styles.heroChipTitle}>Above national average</div>
<div className={styles.heroChipSub}>
Reading, Writing &amp; Maths · {Math.round(heroRwm)} vs {Math.round(heroRwmNat)}
@@ -242,7 +242,7 @@ export function SchoolDetailView({
)}
{isSecondary && heroAtt8 != null && heroAtt8Nat != null && heroAtt8 > heroAtt8Nat && (
<div className={`${styles.heroChip} ${styles.heroChipGood}`}>
<div className={`${styles.heroChip} ${styles['tone-teal']}`}>
<div className={styles.heroChipTitle}>Above national average</div>
<div className={styles.heroChipSub}>
Attainment 8 · {heroAtt8.toFixed(1)} vs {heroAtt8Nat.toFixed(1)}
@@ -276,7 +276,7 @@ export function SchoolDetailView({
{ofsted && (
<div className={styles.heroStat}>
<div className={`${styles.heroStatNumberSerif} ${styles[ofstedHeroChip.toneClass] ?? ''}`}>
<div className={`${styles.heroStatNumberSerif} ${styles[`tone-${ofstedHeroChip.tone}`]}`}>
{ofstedHeroChip.state === 'oeif'
? ofstedHeroChip.title.replace(/^Ofsted\s+/, '')
: ofstedHeroChip.state === 'reportCard'