import { useState, useMemo } from 'react'; import Markdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import TopBar from '../components/layout/TopBar'; import PageContainer from '../components/layout/PageContainer'; import { battleReferenceSections } from '../rules/battle-reference'; export default function RulesPage() { const [openSections, setOpenSections] = useState>(new Set()); const [search, setSearch] = useState(''); const filtered = useMemo(() => { if (!search.trim()) return battleReferenceSections.map((s, i) => ({ ...s, originalIndex: i })); const q = search.toLowerCase(); return battleReferenceSections .map((s, i) => ({ ...s, originalIndex: i })) .filter((s) => s.title.toLowerCase().includes(q) || s.content.toLowerCase().includes(q)); }, [search]); const toggle = (index: number) => { setOpenSections((prev) => { const next = new Set(prev); if (next.has(index)) { next.delete(index); } else { next.add(index); } return next; }); }; const expandAll = () => { setOpenSections(new Set(filtered.map((s) => s.originalIndex))); }; const collapseAll = () => { setOpenSections(new Set()); }; return ( <> setSearch(e.target.value)} />
{search.trim() && ( {filtered.length} result{filtered.length !== 1 ? 's' : ''} )}
{filtered.map((section) => (
{ e.preventDefault(); toggle(section.originalIndex); }}> {section.title}
(
{children}
), }} >{section.content}
))} {filtered.length === 0 && (

No sections match "{search}".

)}
); }