68 lines
2.5 KiB
TypeScript
68 lines
2.5 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useEffect } from "react";
|
|
|
|
interface PropertyNavProps {
|
|
sections: { id: string; label: string }[];
|
|
}
|
|
|
|
export default function PropertyNav({ sections }: PropertyNavProps) {
|
|
const [activeSection, setActiveSection] = useState(sections[0]?.id || "");
|
|
|
|
useEffect(() => {
|
|
const handleScroll = () => {
|
|
const scrollPosition = window.scrollY + 200;
|
|
|
|
for (const section of sections) {
|
|
const element = document.getElementById(section.id);
|
|
if (element) {
|
|
const { offsetTop, offsetHeight } = element;
|
|
if (scrollPosition >= offsetTop && scrollPosition < offsetTop + offsetHeight) {
|
|
setActiveSection(section.id);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
window.addEventListener("scroll", handleScroll);
|
|
return () => window.removeEventListener("scroll", handleScroll);
|
|
}, [sections]);
|
|
|
|
const scrollToSection = (id: string) => {
|
|
const element = document.getElementById(id);
|
|
if (element) {
|
|
const offset = 150; // Account for sticky header
|
|
const elementPosition = element.getBoundingClientRect().top;
|
|
const offsetPosition = elementPosition + window.pageYOffset - offset;
|
|
|
|
window.scrollTo({
|
|
top: offsetPosition,
|
|
behavior: "smooth"
|
|
});
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="sticky top-28 z-30 bg-white/95 dark:bg-gray-900/95 backdrop-blur-md border-b border-gray-200 dark:border-gray-800 shadow-sm">
|
|
|
|
<div className="max-w-7xl mx-auto px-6">
|
|
<nav className="flex gap-1 overflow-x-auto hide-scrollbar py-3">
|
|
{sections.map((section) => (
|
|
<button
|
|
key={section.id}
|
|
onClick={() => scrollToSection(section.id)}
|
|
className={`px-6 py-2 rounded-lg font-medium whitespace-nowrap transition-all duration-200 ${activeSection === section.id
|
|
? "bg-primary text-white shadow-md"
|
|
: "text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800"
|
|
}`}
|
|
>
|
|
{section.label}
|
|
</button>
|
|
))}
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|