fix(compare): match mockups — remove trends table + mobile measure-first cards #42
@@ -75,34 +75,3 @@
|
||||
height: 360px;
|
||||
}
|
||||
}
|
||||
|
||||
.tableWrapper {
|
||||
overflow-x: auto;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.table th,
|
||||
.table td {
|
||||
text-align: left;
|
||||
padding: 0.6rem 0.75rem;
|
||||
border-bottom: 1px solid var(--border-light);
|
||||
}
|
||||
|
||||
.table th {
|
||||
background: var(--bg-secondary);
|
||||
font-size: 0.8rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.yearCell {
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
/**
|
||||
* Explore trends — the full grouped metric catalogue (nothing from the old
|
||||
* compare page is lost; spec §4's tier 3) driving the year-by-year chart
|
||||
* with its England reference line, plus the year-by-year table. Progress
|
||||
* metrics carry CI-based bands for the years DfE published them.
|
||||
* compare page is lost; spec §4's tier 3) driving the year-by-year chart with
|
||||
* its England reference line. Matches the mockup: a measure picker and the
|
||||
* chart only (no data table).
|
||||
*/
|
||||
|
||||
'use client';
|
||||
|
||||
import dynamic from 'next/dynamic';
|
||||
|
||||
import { progressBand } from '@/lib/compareLogic';
|
||||
import type { ComparisonData, MetricDefinition, NationalAverages, School } from '@/lib/types';
|
||||
import { formatAcademicYear, formatMetricValue, metricKind } from '@/lib/utils';
|
||||
import { track } from '@/lib/analytics';
|
||||
import { Chip, Section, sectionStyles as s } from './sectionShared';
|
||||
import { Section } from './sectionShared';
|
||||
import styles from './TrendsExplorer.module.css';
|
||||
|
||||
const ComparisonChart = dynamic(
|
||||
@@ -40,14 +38,6 @@ const SECONDARY_OPTGROUPS: { label: string; category: string }[] = [
|
||||
export const PRIMARY_CATEGORIES = PRIMARY_OPTGROUPS.map((g) => g.category);
|
||||
export const SECONDARY_CATEGORIES = SECONDARY_OPTGROUPS.map((g) => g.category);
|
||||
|
||||
const PROGRESS_CI: Record<string, [string, string]> = {
|
||||
reading_progress: ['reading_progress_lower_ci', 'reading_progress_upper_ci'],
|
||||
writing_progress: ['writing_progress_lower_ci', 'writing_progress_upper_ci'],
|
||||
maths_progress: ['maths_progress_lower_ci', 'maths_progress_upper_ci'],
|
||||
};
|
||||
|
||||
const BAND_LABEL = { above: 'Above average', average: 'Average', below: 'Below average' } as const;
|
||||
|
||||
export function TrendsExplorer({
|
||||
schools,
|
||||
data,
|
||||
@@ -78,21 +68,11 @@ export function TrendsExplorer({
|
||||
nationalByYear[entry.year] = block?.[metric] ?? null;
|
||||
}
|
||||
|
||||
const years = [
|
||||
...new Set(
|
||||
schools.flatMap(
|
||||
(school) => data[String(school.urn)]?.yearly_data.map((d) => Math.trunc(d.year)) ?? [],
|
||||
),
|
||||
),
|
||||
].sort((a, b) => a - b);
|
||||
|
||||
const handleMetricChange = (next: string) => {
|
||||
track('compare_metric_changed', { metric: next, phase: isPrimaryPhase ? 'primary' : 'secondary' });
|
||||
onMetricChange(next);
|
||||
};
|
||||
|
||||
const ciKeys = PROGRESS_CI[metric];
|
||||
|
||||
return (
|
||||
<Section
|
||||
title="Explore trends"
|
||||
@@ -128,8 +108,7 @@ export function TrendsExplorer({
|
||||
{metric.includes('progress') && (
|
||||
<p className={styles.progressNote}>
|
||||
Progress scores measure pupils' progress from KS1 to KS2. A score of 0 equals the
|
||||
national average. DfE stopped publishing KS2 progress after 2022/23 (no KS1 baseline);
|
||||
bands use DfE's confidence intervals, not the raw score alone.
|
||||
national average. DfE stopped publishing KS2 progress after 2022/23 (no KS1 baseline).
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -142,52 +121,6 @@ export function TrendsExplorer({
|
||||
nationalByYear={nationalByYear}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{years.length > 0 && (
|
||||
<div className={styles.tableWrapper}>
|
||||
<table className={styles.table}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Year</th>
|
||||
{schools.map((school) => (
|
||||
<th key={school.urn}>{school.school_name}</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{years.map((year) => (
|
||||
<tr key={year}>
|
||||
<td className={styles.yearCell}>{formatAcademicYear(year)}</td>
|
||||
{schools.map((school) => {
|
||||
const row = data[String(school.urn)]?.yearly_data.find(
|
||||
(d) => Math.trunc(d.year) === year,
|
||||
) as (Record<string, unknown> & { year: number }) | undefined;
|
||||
const value = row?.[metric];
|
||||
if (typeof value !== 'number') return <td key={school.urn}>–</td>;
|
||||
const band = ciKeys
|
||||
? progressBand(
|
||||
value,
|
||||
(row?.[ciKeys[0]] as number | null) ?? null,
|
||||
(row?.[ciKeys[1]] as number | null) ?? null,
|
||||
)
|
||||
: null;
|
||||
return (
|
||||
<td key={school.urn}>
|
||||
{formatMetricValue(value, metricKind(metric))}{' '}
|
||||
{band && (
|
||||
<Chip tone={band === 'above' ? 'good' : band === 'below' ? 'warn' : 'neutral'}>
|
||||
{BAND_LABEL[band]}
|
||||
</Chip>
|
||||
)}
|
||||
</td>
|
||||
);
|
||||
})}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</details>
|
||||
</Section>
|
||||
|
||||
Reference in New Issue
Block a user