"use client"; import { usePathname } from "next/navigation"; import { useState, useEffect } from "react"; import Link from "next/link"; import { useTheme } from "next-themes"; import { createPortal } from "react-dom"; import { Home, Info, BookOpen, Cpu, SlidersHorizontal, Terminal, Scale, ShoppingBag, Menu, X, Sun, Moon } from "lucide-react"; export default function Header() { const [drawerOpen, setDrawerOpen] = useState(false); const [mounted, setMounted] = useState(false); const pathname = usePathname(); useEffect(() => { setMounted(true); }, []); const menuItems = [ { text: "Início", href: "/", icon: , featured: true }, { text: "Sobre o Projeto", brief: "Sobre", href: "/sobre", icon: }, { text: "Glossário", href: "/glossario", icon: }, { text: "Séries", href: "/series", icon: , featured: true }, { text: "Seletor de ESP32", brief: "Seletor", href: "/seletor", icon: , featured: true }, { text: "Frameworks", href: "/frameworks", icon: , featured: true }, { text: "Comparar Séries", brief: "Comparar", href: "/comparacao", icon: , featured: true }, { text: "Catálogo de Placas", brief: "Catálogo", href: "/catalogo", icon: }, ]; const featuredItems = menuItems.filter(item => item.featured); function isActive(href) { if (href === "/") { return pathname === "/"; } return String(pathname).includes(href) && href !== "/"; } // Lock scroll when mobile menu is open useEffect(() => { if (drawerOpen) { document.body.style.overflow = "hidden"; } else { document.body.style.overflow = ""; } return () => { document.body.style.overflow = ""; }; }, [drawerOpen]); return ( {/* LOGO */} ESPDocs {/* Menu Desktop */} {featuredItems.map((item) => ( {item.icon} {item.brief || item.text} ))} {/* Divider */} {/* Theme Switcher Button */} {/* Full Menu Burger Trigger */} setDrawerOpen(true)} className="p-2.5 rounded-xl border border-slate-300 dark:border-slate-800 text-slate-600 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-900/80 hover:border-purple-500 dark:hover:border-purple-400 hover:text-purple-600 dark:hover:text-purple-400 transition-all cursor-pointer" aria-label="Abrir menu completo" aria-expanded={drawerOpen} > {/* Botões Mobile (Theme + Burger) */} setDrawerOpen(true)} className="p-2.5 rounded-xl border border-slate-300 dark:border-slate-800 text-slate-600 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-900/80 hover:border-purple-500 dark:hover:border-purple-400 transition-all cursor-pointer" aria-label="Abrir menu de navegação" aria-expanded={drawerOpen} > {/* Render side-panel and overlay at body level via React Portal to prevent layout leakage */} {mounted && createPortal( <> {drawerOpen && ( setDrawerOpen(false)} /> )} {/* Drawer Header */} Menu Navegação setDrawerOpen(false)} className="p-2 text-slate-500 hover:text-slate-800 dark:text-slate-400 dark:hover:text-white rounded-xl hover:bg-slate-50 dark:hover:bg-slate-800/60 transition-all cursor-pointer" aria-label="Fechar menu" > {/* Drawer Menu Items */} {menuItems.map((item) => ( setDrawerOpen(false)} aria-current={isActive(item.href) ? "page" : undefined} > {item.icon} {item.text} {isActive(item.href) && ( )} ))} {/* Drawer Footer Info */} ESPDocs • Plataforma Não Oficial > , document.body )} ); } /* Internal ThemeToggle Component */ function ThemeToggle() { const { resolvedTheme, setTheme } = useTheme(); const [mounted, setMounted] = useState(false); useEffect(() => setMounted(true), []); if (!mounted) { return ( ); } return ( setTheme(resolvedTheme === "dark" ? "light" : "dark")} className="w-10 h-10 rounded-xl bg-slate-100 dark:bg-slate-900 text-slate-600 dark:text-slate-300 hover:bg-slate-200 dark:hover:bg-slate-800/80 hover:text-purple-600 dark:hover:text-purple-400 border border-slate-250/20 dark:border-slate-800/60 shadow-xs flex items-center justify-center transition-all duration-300 cursor-pointer active:scale-95 shrink-0" aria-label="Alternar tema" > {resolvedTheme === "dark" ? ( ) : ( )} ); }
ESPDocs • Plataforma Não Oficial