"use client"; import React, { useEffect, useRef, useState } from "react"; import { ExternalLink } from "lucide-react"; // ── Types ───────────────────────────────────────────────────────────────────── interface SubSection { id: string; label: string; } interface NavSection { id: string; label: string; sub?: SubSection[]; } // ── Config ──────────────────────────────────────────────────────────────────── const NAV_SECTIONS: NavSection[] = [ { id: "section-1", label: "1. Объект" }, { id: "section-2", label: "2. Земля и риски" }, { id: "section-3", label: "3. Рынок", sub: [ { id: "section-3-1", label: "3.1 Настройки выборки" }, { id: "section-3-2", label: "3.2 Планировки" }, { id: "section-3-3", label: "3.3 Остатки и скорость" }, ], }, { id: "section-4", label: "4. Инфраструктура" }, { id: "section-5", label: "5. Свежесть" }, ]; // All section IDs in scroll order (for IntersectionObserver) const ALL_SECTION_IDS: string[] = NAV_SECTIONS.flatMap((s) => s.sub ? [s.id, ...s.sub.map((sub) => sub.id)] : [s.id], ); // ── Component ───────────────────────────────────────────────────────────────── export function AnalysisSidebar() { const [activeId, setActiveId] = useState(ALL_SECTION_IDS[0]); const observerRef = useRef(null); // Scrollspy via IntersectionObserver useEffect(() => { const candidates = ALL_SECTION_IDS.map((id) => document.getElementById(id), ).filter((el): el is HTMLElement => el !== null); if (candidates.length === 0) return; // Track which sections are visible; pick topmost visible one const visible = new Set(); observerRef.current = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { visible.add(entry.target.id); } else { visible.delete(entry.target.id); } }); // Pick the topmost section that is currently visible const next = ALL_SECTION_IDS.find((id) => visible.has(id)); if (next) setActiveId(next); }, { root: null, // Trigger when section top enters top 60% of viewport rootMargin: "-8px 0px -40% 0px", threshold: 0, }, ); candidates.forEach((el) => observerRef.current!.observe(el)); return () => { observerRef.current?.disconnect(); }; }, []); function handleAnchorClick( e: React.MouseEvent, targetId: string, ) { e.preventDefault(); const el = document.getElementById(targetId); if (el) { el.scrollIntoView({ behavior: "smooth", block: "start" }); } setActiveId(targetId); } return ( ); }