"use client"; import Link from "next/link"; import { useEffect, useMemo, useState } from "react"; import { ChevronDown, ChevronUp } from "lucide-react"; export type AnchorSection = { id: string; label: string; }; export type BusinessSubNavMenu = { key: string; label: string; href?: string; current?: boolean; defaultOpen?: boolean; sections?: AnchorSection[]; }; type BusinessSubNavProps = { menus?: BusinessSubNavMenu[]; offsetTop?: number; className?: string; }; export default function BusinessSubNav({ menus = [], offsetTop = 120, className = "", }: BusinessSubNavProps) { const [activeId, setActiveId] = useState(""); const [openMenus, setOpenMenus] = useState>({}); const allSections = useMemo( () => menus.flatMap((menu) => menu.sections ?? []), [menus] ); useEffect(() => { const initialOpenState: Record = {}; menus.forEach((menu) => { initialOpenState[menu.key] = menu.defaultOpen ?? menu.current ?? false; }); setOpenMenus(initialOpenState); }, [menus]); useEffect(() => { if (!allSections.length) return; const observer = new IntersectionObserver( (entries) => { const visible = entries .filter((entry) => entry.isIntersecting) .sort((a, b) => b.intersectionRatio - a.intersectionRatio); if (visible[0]) { setActiveId(visible[0].target.id); } }, { rootMargin: `-${offsetTop}px 0px -55% 0px`, threshold: [0.2, 0.35, 0.5, 0.7], } ); const targets = allSections .map((section) => document.getElementById(section.id)) .filter(Boolean) as HTMLElement[]; targets.forEach((el) => observer.observe(el)); const hash = window.location.hash.replace("#", ""); const initialActive = allSections.find((section) => section.id === hash)?.id ?? allSections[0]?.id ?? ""; setActiveId(initialActive); return () => observer.disconnect(); }, [allSections, offsetTop]); useEffect(() => { if (!activeId) return; const parentMenu = menus.find((menu) => (menu.sections ?? []).some((section) => section.id === activeId) ); if (!parentMenu) return; setOpenMenus(() => { const nextOpenState: Record = {}; menus.forEach((menu) => { nextOpenState[menu.key] = menu.key === parentMenu.key; }); return nextOpenState; }); }, [activeId, menus]); const handleMove = (id: string) => { setActiveId(id); const target = document.getElementById(id); if (!target) return; window.history.replaceState(null, "", `#${id}`); const top = target.getBoundingClientRect().top + window.scrollY - offsetTop; window.scrollTo({ top, behavior: "smooth", }); }; const toggleMenu = (key: string) => { setOpenMenus((prev) => ({ ...prev, [key]: !prev[key], })); }; if (!menus.length) return null; return ( ); }