feat(ux): implement comprehensive UX audit fixes across all pages
Addresses 28 issues identified in UX audit (P0–P3 severity): P0 — Critical: - Fix compare URL sharing: seed ComparisonContext from SSR initialData when localStorage is empty, making /compare?urns=... links shareable - Remove permanently broken "Avg. Scaled Score" column from school detail historical data table P1 — High priority: - Add radius selector (0.5–10 mi) to postcode search in FilterBar - Make Add to Compare a toggle (remove) on SchoolCards - Hide hero title/description once a search is active - Show school count + quick-search prompts on empty landing page - Compare empty state opens in-page school search modal directly - Remove URN from school detail header (irrelevant to end users) - Move map above performance chart in school detail page - Add ← Back navigation to school detail page - Add sort controls to search results (RWM%, distance, A–Z) - Show metric descriptions below metric selector - Expand ComparisonToast to list school names with per-school remove - Add progress score explainer (0 = national average) throughout P2 — Medium: - Remove console.log statements from ComparisonView - Colour-code comparison school cards to match chart line colours - Replace plain loading text with LoadingSkeleton in ComparisonView - Rankings empty state uses shared EmptyState component - Rankings year filter shows actual year e.g. "2023 (Latest)" - Rankings subtitle shows top-N count - Add View link alongside Add button in rankings table - Remove placeholder Privacy Policy / Terms links from footer - Replace untappable 10px info icons with visible metric hint text - Show active filter chips in search results header P3 — Polish: - Remove redundant "Home" nav link (logo already links home) - Add / and Ctrl+K keyboard shortcut to focus search input - Add Share button to compare page (copies URL to clipboard) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
|
||||
'use client';
|
||||
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useComparison } from '@/hooks/useComparison';
|
||||
import { PerformanceChart } from './PerformanceChart';
|
||||
import { SchoolMap } from './SchoolMap';
|
||||
@@ -19,6 +20,7 @@ interface SchoolDetailViewProps {
|
||||
}
|
||||
|
||||
export function SchoolDetailView({ schoolInfo, yearlyData, absenceData }: SchoolDetailViewProps) {
|
||||
const router = useRouter();
|
||||
const { addSchool, removeSchool, isSelected } = useComparison();
|
||||
const isInComparison = isSelected(schoolInfo.urn);
|
||||
|
||||
@@ -36,6 +38,11 @@ export function SchoolDetailView({ schoolInfo, yearlyData, absenceData }: School
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
{/* Back Navigation */}
|
||||
<div className={styles.backNav}>
|
||||
<button onClick={() => router.back()} className={styles.backButton}>← Back</button>
|
||||
</div>
|
||||
|
||||
{/* Header Section */}
|
||||
<header className={styles.header}>
|
||||
<div className={styles.headerContent}>
|
||||
@@ -52,9 +59,6 @@ export function SchoolDetailView({ schoolInfo, yearlyData, absenceData }: School
|
||||
{schoolInfo.school_type}
|
||||
</span>
|
||||
)}
|
||||
<span className={styles.metaItem}>
|
||||
URN: {schoolInfo.urn}
|
||||
</span>
|
||||
</div>
|
||||
{schoolInfo.address && (
|
||||
<p className={styles.address}>
|
||||
@@ -137,6 +141,23 @@ export function SchoolDetailView({ schoolInfo, yearlyData, absenceData }: School
|
||||
)}
|
||||
|
||||
</div>
|
||||
{(latestResults.reading_progress !== null || latestResults.writing_progress !== null || latestResults.maths_progress !== null) && (
|
||||
<p className={styles.progressNote}>Progress scores: 0 = national average. Positive = above average, negative = below average.</p>
|
||||
)}
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Map */}
|
||||
{schoolInfo.latitude && schoolInfo.longitude && (
|
||||
<section className={styles.mapSection}>
|
||||
<h2 className={styles.sectionTitle}>Location</h2>
|
||||
<div className={styles.mapContainer}>
|
||||
<SchoolMap
|
||||
schools={[schoolInfo]}
|
||||
center={[schoolInfo.latitude, schoolInfo.longitude]}
|
||||
zoom={15}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
@@ -269,20 +290,6 @@ export function SchoolDetailView({ schoolInfo, yearlyData, absenceData }: School
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Map */}
|
||||
{schoolInfo.latitude && schoolInfo.longitude && (
|
||||
<section className={styles.mapSection}>
|
||||
<h2 className={styles.sectionTitle}>Location</h2>
|
||||
<div className={styles.mapContainer}>
|
||||
<SchoolMap
|
||||
schools={[schoolInfo]}
|
||||
center={[schoolInfo.latitude, schoolInfo.longitude]}
|
||||
zoom={15}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* All Years Data Table */}
|
||||
{yearlyData.length > 0 && (
|
||||
<section className={styles.historySection}>
|
||||
@@ -297,7 +304,6 @@ export function SchoolDetailView({ schoolInfo, yearlyData, absenceData }: School
|
||||
<th>Reading Progress</th>
|
||||
<th>Writing Progress</th>
|
||||
<th>Maths Progress</th>
|
||||
<th>Avg. Scaled Score</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -309,7 +315,6 @@ export function SchoolDetailView({ schoolInfo, yearlyData, absenceData }: School
|
||||
<td>{result.reading_progress !== null ? formatProgress(result.reading_progress) : '-'}</td>
|
||||
<td>{result.writing_progress !== null ? formatProgress(result.writing_progress) : '-'}</td>
|
||||
<td>{result.maths_progress !== null ? formatProgress(result.maths_progress) : '-'}</td>
|
||||
<td>-</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
||||
Reference in New Issue
Block a user