Files
school_compare/nextjs-app/components/Navigation.tsx
Tudor 3d24050d11
All checks were successful
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 1m8s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m5s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
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>
2026-03-23 21:31:28 +00:00

61 lines
1.8 KiB
TypeScript

/**
* Navigation Component
* Main navigation header with active link highlighting
*/
'use client';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { useComparison } from '@/hooks/useComparison';
import styles from './Navigation.module.css';
export function Navigation() {
const pathname = usePathname();
const { selectedSchools } = useComparison();
const isActive = (path: string) => {
if (path === '/') {
return pathname === '/';
}
return pathname.startsWith(path);
};
return (
<header className={styles.header}>
<div className={styles.container}>
<Link href="/" className={styles.logo}>
<div className={styles.logoIcon}>
<svg viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="20" cy="20" r="18" stroke="currentColor" strokeWidth="2"/>
<path d="M20 6L20 34M8 14L32 14M6 20L34 20M8 26L32 26" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
<circle cx="20" cy="20" r="3" fill="currentColor"/>
</svg>
</div>
<span className={styles.logoText}>SchoolCompare</span>
</Link>
<nav className={styles.nav}>
<Link
href="/compare"
className={isActive('/compare') ? `${styles.navLink} ${styles.active}` : styles.navLink}
>
Compare
{selectedSchools.length > 0 && (
<span key={selectedSchools.length} className={styles.badge}>
{selectedSchools.length}
</span>
)}
</Link>
<Link
href="/rankings"
className={isActive('/rankings') ? `${styles.navLink} ${styles.active}` : styles.navLink}
>
Rankings
</Link>
</nav>
</div>
</header>
);
}