c749d72a6a
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 15s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 51s
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 0s
Elevates the primary school detail hero from a flat report header into a scannable editorial block. Parents can read the headline signal in seconds. - A1: bump .schoolName to clamp(2rem, 5vw, 3.25rem) Playfair. - A2: framework-aware signal chip strip via new buildOfstedHeroChip() helper. Branches on ofsted.framework so Report Card schools never show a fake overall grade — they get "Ofsted Report Card" + inspection date + Safeguarding: Met/Not met. OEIF schools keep the grade word. - A3: oversized Playfair stats — Reading, Writing & Maths % (primary) or Attainment 8 (secondary) with inline DeltaChip vs national, Ofsted verdict with tone colouring, and first-choice offer rate. - B1: italic serif one-sentence summary via buildSchoolSummary() helper, also framework-aware so Report Card schools are described by framework, not a synthetic grade. - C1: new DeltaChip component reused in the two headline KS2 metric cards (rwm_expected_pct, rwm_high_pct). All copy uses "Reading, Writing & Maths" in full. Secondary detail view untouched in this slice. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
/**
|
|
* DeltaChip — small coloured chip showing how a value compares to a baseline.
|
|
*
|
|
* Example: <DeltaChip value={70} baseline={60} unit="pts" /> → "+10 pts"
|
|
*
|
|
* Colours (reuse globals.css status tokens):
|
|
* above baseline → statusGood (teal)
|
|
* below baseline → statusBad (coral)
|
|
* within ±tolerance → statusWarn (gold, "in line")
|
|
*/
|
|
|
|
import styles from './DeltaChip.module.css';
|
|
|
|
interface DeltaChipProps {
|
|
value: number | null | undefined;
|
|
baseline: number | null | undefined;
|
|
/** Unit suffix for the delta (e.g. "pts", "%") */
|
|
unit?: string;
|
|
/** Absolute delta below which the chip is treated as neutral */
|
|
tolerance?: number;
|
|
/** Override label when we want "vs national" under a number */
|
|
suffix?: string;
|
|
/** Smaller variant for inline use next to metric values */
|
|
size?: 'sm' | 'md';
|
|
}
|
|
|
|
export function DeltaChip({
|
|
value,
|
|
baseline,
|
|
unit = 'pts',
|
|
tolerance = 1,
|
|
suffix,
|
|
size = 'md',
|
|
}: DeltaChipProps) {
|
|
if (value == null || baseline == null) return null;
|
|
|
|
const delta = value - baseline;
|
|
const rounded = Math.round(delta);
|
|
|
|
let tone: 'good' | 'bad' | 'neutral';
|
|
if (Math.abs(delta) < tolerance) tone = 'neutral';
|
|
else if (delta > 0) tone = 'good';
|
|
else tone = 'bad';
|
|
|
|
const toneClass =
|
|
tone === 'good' ? styles.good : tone === 'bad' ? styles.bad : styles.neutral;
|
|
|
|
const sign = rounded > 0 ? '+' : '';
|
|
const label = `${sign}${rounded} ${unit}`.trim();
|
|
|
|
return (
|
|
<span className={`${styles.chip} ${toneClass} ${size === 'sm' ? styles.sm : ''}`}>
|
|
{label}
|
|
{suffix && <span className={styles.suffix}>{suffix}</span>}
|
|
</span>
|
|
);
|
|
}
|