diff --git a/components/layout/Header.tsx b/components/layout/Header.tsx index 600e178..48b5fc8 100644 --- a/components/layout/Header.tsx +++ b/components/layout/Header.tsx @@ -1,88 +1,205 @@ "use client"; +import { useState, useEffect } from "react"; import Link from "next/link"; import { usePathname } from "next/navigation"; +// Extracted icon components +const GitHubIcon = () => ( + +); + +const MenuIcon = () => ( + +); + +const CloseIcon = () => ( + +); + +// Navigation links configuration +const navLinks = [ + { href: "/", label: "Home" }, + { href: "/lessons", label: "Lessons" }, + { href: "/sandbox", label: "Sandbox" }, + { href: "/visualizer", label: "Visualizer" }, +]; + export default function Header() { const pathname = usePathname(); + const [isMenuOpen, setIsMenuOpen] = useState(false); + + // Close mobile menu when navigating between pages + useEffect(() => { + setIsMenuOpen(false); + }, [pathname]); + + // Close menu when clicking outside or pressing Escape + useEffect(() => { + if (!isMenuOpen) return; + + const handleOutsideClick = (event: MouseEvent) => { + const target = event.target as HTMLElement; + if ( + !target.closest("#mobile-menu-button") && + !target.closest("#mobile-menu") + ) { + setIsMenuOpen(false); + } + }; + + const handleEsc = (event: KeyboardEvent) => { + if (event.key === "Escape") { + setIsMenuOpen(false); + } + }; + + // Prevent scrolling when mobile menu is open + document.body.style.overflow = "hidden"; + + document.addEventListener("mousedown", handleOutsideClick); + document.addEventListener("keydown", handleEsc); + + return () => { + document.body.style.overflow = ""; + document.removeEventListener("mousedown", handleOutsideClick); + document.removeEventListener("keydown", handleEsc); + }; + }, [isMenuOpen]); + + const isActive = (path: string) => { + if (path === "/") { + return pathname === path; + } + return pathname === path || pathname.startsWith(`${path}/`); + }; return (
-
-
- - SQL Playground - -
-
-
- GitHub - + + + + + {/* Mobile menu button */} +
+ + GitHub + +
+ + {/* Mobile menu */} +
+
+ {navLinks.map((link) => ( + + {link.label} + + ))} +
+
); }