From 56aac2f9f2604afd76c5dcf980c8d94f59dbb609 Mon Sep 17 00:00:00 2001 From: zguiyang Date: Sat, 14 Mar 2026 12:22:43 +0800 Subject: [PATCH] refactor(header): replace emoji icons with Lucide React components and enhance navigation structure - Introduced `navItems` array with icons and links for streamlined navigation rendering. - Added `isActive` function to handle active state for improved user feedback. - Refined desktop and mobile navigation with updated styles and scalable icon usage. - Removed hardcoded emoji-based navigation for consistency with other components. --- src/components/GlassHeader.tsx | 130 ++++++++++++++++----------------- 1 file changed, 61 insertions(+), 69 deletions(-) diff --git a/src/components/GlassHeader.tsx b/src/components/GlassHeader.tsx index 549b2d9..dc60bcb 100644 --- a/src/components/GlassHeader.tsx +++ b/src/components/GlassHeader.tsx @@ -5,15 +5,18 @@ import Container from "./ui/Container.tsx"; import { useTranslations, getLocalizedPath } from "@/i18n/utils"; import type { Lang } from "@/types/i18n"; import { useState, useEffect } from "react"; -import { Menu, X } from "lucide-react"; +import { Menu, X, Home, Rocket, PenTool, Zap, Briefcase, User } from "lucide-react"; import { defaultLang } from "@/i18n/ui"; import { type GlassHeaderProps } from "@/types"; import { motion } from "framer-motion"; +import { cn } from "@/lib/utils"; export default function GlassHeader({ lang: propLang }: GlassHeaderProps) { const [lang, setLang] = useState(propLang || defaultLang); + const [currentPath, setCurrentPath] = useState(""); useEffect(() => { + setCurrentPath(window.location.pathname); const htmlLang = document.documentElement.lang as Lang; if (htmlLang && (!propLang || htmlLang !== lang)) { setLang(htmlLang); @@ -35,11 +38,24 @@ export default function GlassHeader({ lang: propLang }: GlassHeaderProps) { const toggleMenu = () => setIsMenuOpen(!isMenuOpen); + const navItems = [ + { key: 'nav.home', icon: Home, href: getLocalizedPath('/', lang) }, + { key: 'nav.projects', icon: Rocket, href: getLocalizedPath('/projects', lang) }, + { key: 'nav.blog', icon: PenTool, href: getLocalizedPath('/blog', lang) }, + { key: 'nav.now', icon: Zap, href: getLocalizedPath('/now', lang) }, + { key: 'nav.hire', icon: Briefcase, href: getLocalizedPath('/hire', lang) }, + { key: 'nav.about', icon: User, href: getLocalizedPath('/about', lang) }, + ]; + + const isActive = (path: string) => { + if (path === '/' || path === '/zh' || path === '/zh/') { + return currentPath === path; + } + return currentPath.startsWith(path); + }; + return ( - {[ - { key: 'nav.home', icon: '🏠 ', href: getLocalizedPath('/', lang) }, - { key: 'nav.projects', icon: '🚀 ', href: getLocalizedPath('/projects', lang) }, - { key: 'nav.blog', icon: '📝 ', href: getLocalizedPath('/blog', lang) }, - { key: 'nav.now', icon: '⚡ ', href: getLocalizedPath('/now', lang) }, - { key: 'nav.hire', icon: '💼 ', href: getLocalizedPath('/hire', lang) }, - { key: 'nav.about', icon: '👨‍💻 ', href: getLocalizedPath('/about', lang) }, - - ].map((item, index) => ( - - {item.icon} - {t(item.key as any)} - - ))} + {navItems.map((item) => { + const active = isActive(item.href); + return ( + + + {t(item.key as any)} + + ); + })}
{/* Language Switcher added here */} - + - + @@ -115,9 +116,6 @@ export default function GlassHeader({ lang: propLang }: GlassHeaderProps) { onClick={toggleMenu} aria-label="Toggle menu" whileTap={{ scale: 0.9 }} - initial={{ opacity: 0 }} - animate={{ opacity: 1 }} - transition={{ duration: 0.3, delay: 0.6 }} > {isMenuOpen ? : } @@ -126,7 +124,7 @@ export default function GlassHeader({ lang: propLang }: GlassHeaderProps) { {/* Mobile Navigation */}