"use client"; import { useEffect, useState } from "react"; import { tableOfContents } from "@/content/ebook"; export function ReadSidebar() { const [activeId, setActiveId] = useState(tableOfContents[0]?.id ?? ""); const [mobileOpen, setMobileOpen] = useState(false); useEffect(() => { const sections = tableOfContents .map((item) => document.getElementById(item.id)) .filter(Boolean) as HTMLElement[]; if (sections.length === 0) return; const observer = new IntersectionObserver( (entries) => { const visible = entries .filter((e) => e.isIntersecting) .sort((a, b) => b.intersectionRatio - a.intersectionRatio); if (visible[0]?.target.id) { setActiveId(visible[0].target.id); } }, { rootMargin: "-30% 0px -55% 0px", threshold: [0, 0.25, 0.5, 1] } ); sections.forEach((el) => observer.observe(el)); return () => observer.disconnect(); }, []); useEffect(() => { if (!mobileOpen) return; const prev = document.body.style.overflow; document.body.style.overflow = "hidden"; return () => { document.body.style.overflow = prev; }; }, [mobileOpen]); const tocList = (