Advogados/Template-01/src/components/layout/Navbar.tsx
2026-05-13 19:14:22 -03:00

161 lines
5.6 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { Menu, X, Scale, Search } from 'lucide-react';
import { Link, useLocation, useNavigate } from 'react-router-dom';
import { cn } from '../../lib/utils';
export function Navbar() {
const [isScrolled, setIsScrolled] = useState(false);
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const location = useLocation();
const navigate = useNavigate();
useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 10);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
// Handle hash scrolling when navigating across pages
useEffect(() => {
if (location.hash) {
const element = document.querySelector(location.hash);
if (element) {
setTimeout(() => {
element.scrollIntoView({ behavior: 'smooth' });
}, 100);
}
} else {
window.scrollTo(0,0);
}
}, [location]);
const handleNavClick = (e: React.MouseEvent<HTMLAnchorElement>, href: string) => {
setIsMobileMenuOpen(false);
if (href.startsWith('/#')) {
const hash = href.substring(1);
if (location.pathname === '/') {
e.preventDefault();
const element = document.querySelector(hash);
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
// Update URL hash without jumping
window.history.pushState(null, '', hash);
}
} else {
// Let it navigate to /#hash normally
}
}
};
const navLinks = [
{ name: 'Sobre', href: '/sobre' },
{ name: 'Áreas de Atuação', href: '/areas' },
{ name: 'Como Funciona', href: '/funcionamento' },
{ name: 'Blog', href: '/blog' },
{ name: 'Contato', href: '/contato' },
];
return (
<nav
className={cn(
'fixed left-0 right-0 top-0 z-50 transition-all duration-300',
isScrolled
? 'bg-white shadow-md py-3'
: 'bg-brand-blue py-5 text-white'
)}
>
<div className="mx-auto flex max-w-7xl items-center justify-between px-6 lg:px-8">
<Link to="/" className="flex items-center gap-2">
<Scale className={cn("h-8 w-8", isScrolled ? "text-brand-gold" : "text-brand-gold")} />
<div className="flex flex-col">
<span className={cn("font-serif text-xl font-bold leading-none tracking-tight", isScrolled ? "text-brand-blue" : "text-white")}>
João Silva
</span>
<span className={cn("text-xs font-medium tracking-widest", isScrolled ? "text-gray-500" : "text-gray-300")}>
ADVOGADO
</span>
</div>
</Link>
{/* Desktop Nav */}
<div className="hidden items-center gap-8 md:flex">
{navLinks.map((link) => (
<Link
key={link.name}
to={link.href}
onClick={(e) => handleNavClick(e, link.href)}
className={cn(
'text-sm font-medium transition-colors hover:text-brand-gold',
isScrolled ? 'text-gray-700' : 'text-gray-200'
)}
>
{link.name}
</Link>
))}
<div className="flex items-center gap-6 border-l border-white/20 pl-6">
<Link
to="/blog?focus=true"
title="Buscar Artigos"
className={cn(
'transition-colors hover:text-brand-gold',
isScrolled ? 'text-brand-blue' : 'text-white'
)}
>
<Search className="h-5 w-5" />
</Link>
<Link
to="/contato"
className="rounded-none border-2 border-brand-gold bg-brand-gold px-6 py-2 text-sm font-semibold text-white transition-colors hover:bg-transparent hover:text-brand-gold"
>
Consulta Online
</Link>
</div>
</div>
{/* Mobile Nav Toggle */}
<button
className="md:hidden"
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
>
{isMobileMenuOpen ? (
<X className={cn("h-6 w-6", isScrolled ? "text-brand-blue" : "text-white")} />
) : (
<Menu className={cn("h-6 w-6", isScrolled ? "text-brand-blue" : "text-white")} />
)}
</button>
</div>
{/* Mobile Menu */}
{isMobileMenuOpen && (
<div className="absolute left-0 right-0 top-full flex flex-col items-center gap-6 bg-white py-8 shadow-xl md:hidden">
{navLinks.map((link) => (
<Link
key={link.name}
to={link.href}
onClick={(e) => handleNavClick(e, link.href)}
className="text-base font-medium text-gray-800 transition-colors hover:text-brand-gold"
>
{link.name}
</Link>
))}
<Link
to="/blog?focus=true"
onClick={() => setIsMobileMenuOpen(false)}
className="flex items-center gap-2 text-base font-medium text-gray-800 transition-colors hover:text-brand-gold"
>
<Search className="h-5 w-5" /> Buscar Artigo
</Link>
<Link
to="/contato"
onClick={() => setIsMobileMenuOpen(false)}
className="mt-4 rounded-none border-2 border-brand-gold bg-brand-gold px-8 py-3 text-base font-semibold text-white transition-colors hover:bg-white hover:text-brand-gold"
>
Consulta Online
</Link>
</div>
)}
</nav>
);
}