Files
item_opina/components/layout/Navbar.tsx
2026-05-11 20:56:05 +02:00

145 lines
5.0 KiB
TypeScript

"use client";
import { useState, useEffect } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { Button } from "../ui/Button";
import { motion, AnimatePresence } from "framer-motion";
import { FiMenu, FiX, FiGlobe } from "react-icons/fi";
import { useLanguage } from "@/context/LanguageContext";
export const Navbar = () => {
const [isOpen, setIsOpen] = useState(false);
const pathname = usePathname();
const { locale, setLocale, t } = useLanguage();
const isActive = (path: string) => pathname === path;
useEffect(() => {
setIsOpen(false);
}, [pathname]);
useEffect(() => {
if (isOpen) {
document.body.style.overflow = "hidden";
} else {
document.body.style.overflow = "unset";
}
}, [isOpen]);
const navLinks = [
{ name: t.navbar.consultora, href: "/nosotros" },
{ name: t.navbar.servicios, href: "/servicios" },
{ name: t.navbar.participa, href: "/participa" },
{ name: t.navbar.insights, href: "/insights" },
];
return (
<nav className="w-full h-[80px] bg-white/80 backdrop-blur-md border-b border-crisp sticky top-0 z-[100]">
<div className="max-w-7xl mx-auto px-6 lg:px-12 h-full flex justify-between items-center">
{/* Logo */}
<Link href="/" className="text-[20px] md:text-[22px] font-extrabold tracking-tight text-navy uppercase">
Item Opina.
</Link>
{/* Menú Central (Escritorio) */}
<div className="hidden md:flex space-x-8 lg:space-x-10 text-[13px] lg:text-[14px] font-bold uppercase tracking-wider">
{navLinks.map((link) => (
<Link
key={link.href}
href={link.href}
className={`${isActive(link.href) ? "text-ocean" : "text-navy/60"} hover:text-ocean transition-colors`}
>
{link.name}
</Link>
))}
</div>
{/* Idiomas y Acción (Escritorio) */}
<div className="hidden md:flex items-center space-x-6">
{/* Selector de Idiomas */}
<div className="flex items-center gap-3 pr-6">
{(["es", "ca", "en"] as const).map((lang) => (
<button
key={lang}
onClick={() => setLocale(lang)}
className={`text-[11px] font-black uppercase transition-all ${
locale === lang ? "text-ocean scale-110" : "text-navy/30 hover:text-navy"
}`}
>
{lang}
</button>
))}
</div>
<Link href="/contacto">
<Button
variant={isActive("/contacto") ? "primary" : "outline"}
className="!py-2.5 !px-6 text-[12px]"
>
{t.navbar.contacto}
</Button>
</Link>
</div>
{/* Botón Hamburguesa (Móvil) */}
<button
onClick={() => setIsOpen(!isOpen)}
className="md:hidden text-navy p-2 outline-none focus:outline-none ring-0"
aria-label="Toggle Menu"
>
{isOpen ? <FiX size={28} /> : <FiMenu size={28} />}
</button>
</div>
{/* Menú Móvil (Overlay) */}
<AnimatePresence>
{isOpen && (
<motion.div
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: 20 }}
transition={{ duration: 0.3 }}
className="fixed inset-0 top-[80px] w-full h-[calc(100vh-80px)] bg-white z-[90] flex flex-col p-8 md:hidden"
>
<div className="flex flex-col space-y-6 mt-6">
{navLinks.map((link) => (
<Link
key={link.href}
href={link.href}
className={`text-[32px] font-extrabold uppercase tracking-tighter ${
isActive(link.href) ? "text-ocean" : "text-navy"
}`}
>
{link.name}
</Link>
))}
<div className="pt-8 flex flex-col gap-8">
{/* Selector de Idiomas Móvil */}
<div className="flex gap-6">
{(["es", "ca", "en"] as const).map((lang) => (
<button
key={lang}
onClick={() => setLocale(lang)}
className={`text-[16px] font-bold uppercase ${
locale === lang ? "text-ocean border-b-2 border-ocean" : "text-navy/40"
}`}
>
{lang === "es" ? "Español" : lang === "ca" ? "Català" : "English"}
</button>
))}
</div>
<Link href="/contacto">
<Button variant="primary" className="w-full !py-5 text-[16px] uppercase tracking-widest font-bold">
{t.navbar.contacto}
</Button>
</Link>
</div>
</div>
</motion.div>
)}
</AnimatePresence>
</nav>
);
};