Portfolio / src /components /Navbar.tsx
Adeen
Deploy Next.js to HF Spaces
6d0ba8c
"use client";
import Link from "next/link";
import { useState, useEffect } from "react";
export default function Navbar() {
const [activeSection, setActiveSection] = useState("home");
const links = [
{ name: "Home", href: "#home" },
{ name: "About", href: "#about" },
{ name: "Services", href: "#services" },
{ name: "Portfolio", href: "#portfolio" },
{ name: "Contact", href: "#contact" },
];
useEffect(() => {
const handleScroll = () => {
const sections = links.map(link => link.href.substring(1));
let current = "home";
for (const section of sections) {
const element = document.getElementById(section);
if (element) {
const rect = element.getBoundingClientRect();
// If the section's top is near the top of the viewport
if (rect.top <= 200) {
current = section;
}
}
}
setActiveSection(current);
};
window.addEventListener("scroll", handleScroll);
// Initial check
handleScroll();
return () => window.removeEventListener("scroll", handleScroll);
}, []);
const handleScrollTo = (e: React.MouseEvent<HTMLAnchorElement>, href: string) => {
e.preventDefault();
const element = document.getElementById(href.substring(1));
if (element) {
// Because navbar might be sticky/fixed in layout or later, keeping scroll logic is good.
// But layout is not currently sticky. Let's just scroll smoothly.
element.scrollIntoView({ behavior: 'smooth' });
// Update URL hash without jumping
window.history.pushState(null, '', href);
}
};
return (
<header className="flex justify-between items-center py-6 px-10 md:px-16 lg:px-24 mx-auto w-full relative z-50">
<Link href="#home" onClick={(e) => handleScrollTo(e, '#home')} className="text-white font-bold text-2xl tracking-tighter cursor-pointer">Jacob.</Link>
<nav className="hidden md:flex gap-8 text-sm font-semibold">
{links.map((link) => {
const isActive = activeSection === link.href.substring(1);
return (
<a
key={link.name}
href={link.href}
onClick={(e) => handleScrollTo(e, link.href)}
className={`transition-colors duration-300 cursor-pointer ${isActive ? 'text-cyan-400 font-bold' : 'text-slate-300 hover:text-white'}`}
>
{link.name}
</a>
);
})}
</nav>
</header>
);
}