manual save(2026-01-05 11:01)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { Menu, X, Building2 } from 'lucide-react';
|
||||
import { Menu, X, Building2, Phone, Mail, Search, ChevronDown } from 'lucide-react';
|
||||
import { NAVIGATION_MENU } from '../lib/constants';
|
||||
|
||||
/**
|
||||
@@ -40,137 +40,250 @@ export const Header: React.FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<motion.header
|
||||
className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${
|
||||
isScrolled
|
||||
? 'bg-white/95 backdrop-blur-sm shadow-md'
|
||||
: 'bg-white shadow-sm'
|
||||
}`}
|
||||
initial={{ y: -100 }}
|
||||
animate={{ y: 0 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex items-center justify-between h-[70px]">
|
||||
{/* Logo 区域 */}
|
||||
<>
|
||||
{/* 顶部信息栏 */}
|
||||
<motion.div
|
||||
className={`fixed top-0 left-0 right-0 z-50 bg-gradient-to-r from-primary-dark to-primary text-white text-xs transition-all duration-300 ${
|
||||
isScrolled ? 'h-0 opacity-0 overflow-hidden' : 'h-10'
|
||||
}`}
|
||||
initial={{ y: -40 }}
|
||||
animate={{ y: 0 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-full flex items-center justify-between">
|
||||
<div className="flex items-center gap-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<Phone size={14} />
|
||||
<span>400-123-4567</span>
|
||||
</div>
|
||||
<div className="hidden sm:flex items-center gap-2">
|
||||
<Mail size={14} />
|
||||
<span>contact@chengyu.com</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="hidden md:flex items-center gap-4">
|
||||
<span className="text-white/80">欢迎来到诚裕集团官网</span>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-white/60">|</span>
|
||||
<button className="hover:text-accent transition-colors">简体中文</button>
|
||||
<span className="text-white/60">/</span>
|
||||
<button className="hover:text-accent transition-colors">English</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* 主导航栏 */}
|
||||
<motion.header
|
||||
className={`fixed left-0 right-0 z-50 transition-all duration-300 ${
|
||||
isScrolled
|
||||
? 'top-0 bg-white/95 backdrop-blur-md shadow-lg'
|
||||
: 'top-10 bg-white shadow-md'
|
||||
}`}
|
||||
initial={{ y: -100 }}
|
||||
animate={{ y: 0 }}
|
||||
transition={{ duration: 0.3, delay: 0.1 }}
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex items-center justify-between h-[80px]">
|
||||
{/* Logo 区域 - 增强版 */}
|
||||
<Link
|
||||
to="/"
|
||||
className="flex items-center gap-3 group"
|
||||
className="flex items-center gap-3 group relative"
|
||||
aria-label="返回首页"
|
||||
>
|
||||
<motion.div
|
||||
className="flex items-center justify-center w-10 h-10 rounded-lg bg-primary text-white"
|
||||
whileHover={{ scale: 1.05 }}
|
||||
className="relative flex items-center justify-center w-12 h-12 rounded-xl bg-gradient-to-br from-primary to-primary-light text-white shadow-lg"
|
||||
whileHover={{ scale: 1.05, rotate: 5 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
>
|
||||
<Building2 size={24} />
|
||||
<Building2 size={26} />
|
||||
{/* 光晕效果 */}
|
||||
<div className="absolute inset-0 rounded-xl bg-gradient-to-br from-primary to-primary-light opacity-20 blur-xl group-hover:opacity-40 transition-opacity" />
|
||||
</motion.div>
|
||||
<div className="hidden sm:block">
|
||||
<span className="text-lg font-bold text-primary-dark group-hover:text-primary transition-colors">
|
||||
<span className="text-xl font-bold bg-gradient-to-r from-primary-dark to-primary bg-clip-text text-transparent group-hover:from-primary group-hover:to-primary-light transition-all">
|
||||
诚裕集团
|
||||
</span>
|
||||
<p className="text-xs text-gray-500 -mt-1">Chengyu Group</p>
|
||||
<p className="text-xs text-gray-500 -mt-1 font-medium tracking-wider">CHENGYU GROUP</p>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
{/* 桌面端导航菜单 */}
|
||||
{/* 桌面端导航菜单 - 增强版 */}
|
||||
<nav
|
||||
className="hidden md:flex items-center gap-1"
|
||||
className="hidden lg:flex items-center gap-1"
|
||||
role="navigation"
|
||||
aria-label="主导航"
|
||||
>
|
||||
{NAVIGATION_MENU.map((item) => (
|
||||
<Link
|
||||
{NAVIGATION_MENU.map((item, index) => (
|
||||
<motion.div
|
||||
key={item.id}
|
||||
to={item.path}
|
||||
className={`relative px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200 ${
|
||||
isActive(item.path)
|
||||
? 'text-primary'
|
||||
: 'text-gray-600 hover:text-primary'
|
||||
}`}
|
||||
aria-current={isActive(item.path) ? 'page' : undefined}
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: index * 0.1 }}
|
||||
>
|
||||
{item.label}
|
||||
{/* 活动状态指示器 */}
|
||||
{isActive(item.path) && (
|
||||
<Link
|
||||
to={item.path}
|
||||
className={`group relative px-5 py-3 text-sm font-medium rounded-xl transition-all duration-300 flex items-center gap-2 ${
|
||||
isActive(item.path)
|
||||
? 'text-primary bg-primary/5'
|
||||
: 'text-gray-700 hover:text-primary hover:bg-primary/5'
|
||||
}`}
|
||||
aria-current={isActive(item.path) ? 'page' : undefined}
|
||||
>
|
||||
<span className="relative z-10">{item.label}</span>
|
||||
|
||||
{/* 活动状态指示器 - 渐变下划线 */}
|
||||
{isActive(item.path) && (
|
||||
<motion.div
|
||||
layoutId="activeIndicator"
|
||||
className="absolute bottom-1 left-1/2 -translate-x-1/2 w-8 h-1 bg-gradient-to-r from-primary to-accent rounded-full"
|
||||
transition={{ type: 'spring', stiffness: 400, damping: 30 }}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 悬停背景效果 */}
|
||||
<motion.div
|
||||
layoutId="activeIndicator"
|
||||
className="absolute bottom-0 left-1/2 -translate-x-1/2 w-6 h-0.5 bg-accent rounded-full"
|
||||
transition={{ type: 'spring', stiffness: 500, damping: 30 }}
|
||||
className="absolute inset-0 rounded-xl bg-gradient-to-r from-primary/10 to-accent/10 opacity-0 group-hover:opacity-100 transition-opacity duration-300"
|
||||
initial={false}
|
||||
/>
|
||||
)}
|
||||
{/* 悬停效果 */}
|
||||
{!isActive(item.path) && (
|
||||
<span className="absolute inset-0 rounded-lg bg-primary/5 scale-0 transition-transform duration-200 group-hover:scale-100" />
|
||||
)}
|
||||
</Link>
|
||||
</Link>
|
||||
</motion.div>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
{/* 桌面端 CTA 按钮 */}
|
||||
<div className="hidden md:flex items-center gap-3">
|
||||
{/* 桌面端操作区域 */}
|
||||
<div className="hidden lg:flex items-center gap-3">
|
||||
{/* 搜索按钮 */}
|
||||
<motion.button
|
||||
className="px-5 py-2 text-sm font-medium text-white bg-primary rounded-lg hover:bg-primary-light transition-colors shadow-sm"
|
||||
className="p-2.5 rounded-lg text-gray-600 hover:text-primary hover:bg-primary/5 transition-all"
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
aria-label="搜索"
|
||||
>
|
||||
<Search size={20} />
|
||||
</motion.button>
|
||||
|
||||
{/* 联系电话按钮 */}
|
||||
<motion.a
|
||||
href="tel:400-123-4567"
|
||||
className="flex items-center gap-2 px-4 py-2.5 text-sm font-medium text-primary border-2 border-primary rounded-lg hover:bg-primary hover:text-white transition-all"
|
||||
whileHover={{ scale: 1.02 }}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
>
|
||||
立即咨询
|
||||
<Phone size={16} />
|
||||
<span className="hidden xl:inline">400-123-4567</span>
|
||||
</motion.a>
|
||||
|
||||
{/* CTA 按钮 - 渐变风格 */}
|
||||
<motion.button
|
||||
className="relative px-6 py-2.5 text-sm font-medium text-white rounded-lg overflow-hidden group"
|
||||
whileHover={{ scale: 1.02 }}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-primary to-primary-light" />
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-accent to-primary opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
|
||||
<span className="relative z-10 flex items-center gap-2">
|
||||
立即咨询
|
||||
<motion.span
|
||||
animate={{ x: [0, 3, 0] }}
|
||||
transition={{ repeat: Infinity, duration: 1.5 }}
|
||||
>
|
||||
→
|
||||
</motion.span>
|
||||
</span>
|
||||
</motion.button>
|
||||
</div>
|
||||
|
||||
{/* 移动端菜单按钮 */}
|
||||
<motion.button
|
||||
className="md:hidden p-2 rounded-lg text-gray-600 hover:bg-gray-100 transition-colors"
|
||||
className="lg:hidden p-2.5 rounded-xl text-gray-600 hover:bg-primary/5 hover:text-primary transition-all"
|
||||
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
||||
aria-label={isMobileMenuOpen ? '关闭菜单' : '打开菜单'}
|
||||
aria-expanded={isMobileMenuOpen}
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
>
|
||||
{isMobileMenuOpen ? <X size={24} /> : <Menu size={24} />}
|
||||
<motion.div
|
||||
animate={{ rotate: isMobileMenuOpen ? 90 : 0 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
{isMobileMenuOpen ? <X size={24} /> : <Menu size={24} />}
|
||||
</motion.div>
|
||||
</motion.button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 移动端菜单 */}
|
||||
{/* 移动端菜单 - 增强版 */}
|
||||
<AnimatePresence>
|
||||
{isMobileMenuOpen && (
|
||||
<motion.nav
|
||||
initial={{ opacity: 0, height: 0 }}
|
||||
animate={{ opacity: 1, height: 'auto' }}
|
||||
exit={{ opacity: 0, height: 0 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
className="md:hidden bg-white border-t border-gray-100 overflow-hidden"
|
||||
transition={{ duration: 0.3 }}
|
||||
className="lg:hidden bg-gradient-to-b from-white to-gray-50 border-t border-gray-100 overflow-hidden shadow-xl"
|
||||
role="navigation"
|
||||
aria-label="移动端导航"
|
||||
>
|
||||
<div className="px-4 py-4 space-y-2">
|
||||
{NAVIGATION_MENU.map((item) => (
|
||||
<Link
|
||||
<div className="px-4 py-6 space-y-3">
|
||||
{NAVIGATION_MENU.map((item, index) => (
|
||||
<motion.div
|
||||
key={item.id}
|
||||
to={item.path}
|
||||
className={`block px-4 py-3 rounded-lg text-base font-medium transition-all duration-200 ${
|
||||
isActive(item.path)
|
||||
? 'bg-primary/5 text-primary'
|
||||
: 'text-gray-600 hover:bg-gray-50'
|
||||
}`}
|
||||
aria-current={isActive(item.path) ? 'page' : undefined}
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ delay: index * 0.05 }}
|
||||
>
|
||||
{item.label}
|
||||
</Link>
|
||||
<Link
|
||||
to={item.path}
|
||||
className={`block px-5 py-3.5 rounded-xl text-base font-medium transition-all duration-200 ${
|
||||
isActive(item.path)
|
||||
? 'bg-gradient-to-r from-primary/10 to-accent/10 text-primary shadow-sm'
|
||||
: 'text-gray-700 hover:bg-primary/5 active:scale-95'
|
||||
}`}
|
||||
aria-current={isActive(item.path) ? 'page' : undefined}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<span>{item.label}</span>
|
||||
{isActive(item.path) && (
|
||||
<motion.div
|
||||
className="w-2 h-2 rounded-full bg-gradient-to-r from-primary to-accent"
|
||||
layoutId="mobileActiveIndicator"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Link>
|
||||
</motion.div>
|
||||
))}
|
||||
<div className="pt-4 border-t border-gray-100">
|
||||
|
||||
{/* 移动端联系方式 */}
|
||||
<motion.div
|
||||
className="pt-4 mt-2 border-t border-gray-200 space-y-3"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ delay: 0.3 }}
|
||||
>
|
||||
<a
|
||||
href="tel:400-123-4567"
|
||||
className="flex items-center gap-3 px-5 py-3 rounded-xl text-gray-700 hover:bg-primary/5 transition-all"
|
||||
>
|
||||
<Phone size={18} className="text-primary" />
|
||||
<span className="text-sm font-medium">400-123-4567</span>
|
||||
</a>
|
||||
|
||||
<motion.button
|
||||
className="w-full px-4 py-3 text-base font-medium text-white bg-primary rounded-lg"
|
||||
className="w-full px-5 py-3.5 text-base font-medium text-white rounded-xl bg-gradient-to-r from-primary to-primary-light shadow-lg shadow-primary/30"
|
||||
whileTap={{ scale: 0.98 }}
|
||||
>
|
||||
立即咨询
|
||||
</motion.button>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.nav>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</motion.header>
|
||||
</motion.header>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user