/** * Navigation Component * Top header nav for desktop; bottom tab bar for mobile (≤640px). */ 'use client'; import { useEffect } from 'react'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; import { useComparison } from '@/hooks/useComparison'; import styles from './Navigation.module.css'; type IconProps = { className?: string }; const SearchIcon = ({ className }: IconProps) => ( ); const CompareIcon = ({ className }: IconProps) => ( ); const RankingsIcon = ({ className }: IconProps) => ( ); const AdmissionsIcon = ({ className }: IconProps) => ( ); export function Navigation() { const pathname = usePathname(); const { selectedSchools } = useComparison(); const isActive = (path: string) => { if (path === '/') return pathname === '/'; return pathname.startsWith(path); }; /** * iOS Chrome (and some Android browsers) auto-hide their URL bar on scroll, * which grows the visual viewport without changing the layout viewport. * `position: fixed; bottom: 0` sticks to the layout viewport, so our tab * bar appears to float mid-screen with a gap beneath it. Track the delta * via VisualViewport and apply it as a translate so the bar always sits * flush against the visible bottom edge. */ useEffect(() => { const vv = window.visualViewport; if (!vv) return; const root = document.documentElement; const update = () => { const offset = window.innerHeight - (vv.height + vv.offsetTop); // Only positive offsets are meaningful (bar hidden → push down). root.style.setProperty('--mobile-bar-offset', `${Math.max(0, offset)}px`); }; update(); vv.addEventListener('resize', update); vv.addEventListener('scroll', update); return () => { vv.removeEventListener('resize', update); vv.removeEventListener('scroll', update); root.style.removeProperty('--mobile-bar-offset'); }; }, []); const items = [ { href: '/', label: 'Search', Icon: SearchIcon }, { href: '/compare', label: 'Compare', Icon: CompareIcon }, { href: '/rankings', label: 'Rankings', Icon: RankingsIcon }, { href: '/admissions', label: 'Admissions', Icon: AdmissionsIcon }, ] as const; return ( <>
SchoolCompare
); }