import { useCallback, useEffect, useState } from 'react' import ChapterView from './ui/ChapterView.tsx' import LibraryView from './ui/LibraryView.tsx' import { CHAPTERS } from './chapters/index.ts' const PARTS = ['Introduction', 'One dimension', 'Two dimensions', 'Beyond the square'] as const /** The introduction is front matter, so the chapter numbers start after it. */ const NUMBERED = CHAPTERS.filter((c) => c.part !== 'Introduction') function readHash(): string { const h = window.location.hash.replace(/^#\/?/, '') return h === '' ? CHAPTERS[0].id : h } export default function App() { const [route, setRoute] = useState(readHash) useEffect(() => { const on = () => setRoute(readHash()) window.addEventListener('hashchange', on) return () => window.removeEventListener('hashchange', on) }, []) const go = useCallback((id: string) => { window.location.hash = `/${id}` window.scrollTo({ top: 0 }) }, []) const chapter = CHAPTERS.find((c) => c.id === route) const index = CHAPTERS.findIndex((c) => c.id === route) return (
{route === 'library' ? ( ) : chapter ? ( <> ) : (

no such chapter: {route}

)}
) }