| "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 (rect.top <= 200) { |
| current = section; |
| } |
| } |
| } |
| setActiveSection(current); |
| }; |
|
|
| window.addEventListener("scroll", handleScroll); |
| |
| 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) { |
| |
| |
| element.scrollIntoView({ behavior: 'smooth' }); |
| |
| 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> |
| ); |
| } |
|
|