"use client"; import { ReactNode, useCallback, useEffect, useRef, useState } from "react"; import { SettingsSidebar, SidebarItem } from "./SettingsSidebar"; interface SettingsLayoutProps { children: ReactNode; sidebarItems: SidebarItem[]; isAdmin: boolean; } export function SettingsLayout({ children, sidebarItems, isAdmin }: SettingsLayoutProps) { const [activeSection, setActiveSection] = useState(sidebarItems[0]?.id || ""); const mainContentRef = useRef(null); // Handle sidebar click - scroll to section const handleSectionClick = useCallback((id: string) => { const element = document.getElementById(id); if (element) { element.scrollIntoView({ behavior: "smooth", block: "start" }); setActiveSection(id); } }, []); // Track active section based on scroll position useEffect(() => { const visibleItems = sidebarItems.filter(item => !item.adminOnly || isAdmin); // Find the scrollable parent (the main element in AuthenticatedLayout) const findScrollableParent = (el: HTMLElement | null): HTMLElement | null => { while (el) { const style = window.getComputedStyle(el); if (style.overflowY === 'auto' || style.overflowY === 'scroll') { return el; } el = el.parentElement; } return null; }; const scrollContainer = mainContentRef.current ? findScrollableParent(mainContentRef.current) : null; if (!scrollContainer) return; // Use scroll event for smooth tracking const handleScroll = () => { const containerRect = scrollContainer.getBoundingClientRect(); const offset = 150; // Offset from top // Find the section that's currently in view let currentSection = visibleItems[0]?.id || ""; for (const item of visibleItems) { const element = document.getElementById(item.id); if (element) { const rect = element.getBoundingClientRect(); // Check if element top is above the offset line if (rect.top <= containerRect.top + offset) { currentSection = item.id; } } } setActiveSection(prev => { if (prev !== currentSection) { return currentSection; } return prev; }); }; // Throttle scroll events let ticking = false; const scrollHandler = () => { if (!ticking) { requestAnimationFrame(() => { handleScroll(); ticking = false; }); ticking = true; } }; scrollContainer.addEventListener("scroll", scrollHandler, { passive: true }); // Initial check handleScroll(); return () => scrollContainer.removeEventListener("scroll", scrollHandler); }, [sidebarItems, isAdmin]); return (
{/* Subtle grey gradient for systems page feel */}
{/* Header */}

Settings

{/* Layout */}
{/* Sidebar */} {/* Main Content */}
{children}
); }