update: design
Vercel Production Deployment / Deploy-Production (push) Failing after 49s

This commit is contained in:
2025-11-19 11:58:16 +08:00
parent 021dad852b
commit 194a2d1810
7 changed files with 1653 additions and 722 deletions
+72 -44
View File
@@ -19,6 +19,46 @@ export default function Header() {
setIsMenuOpen(false);
}, []);
const sidebarVariants = {
open: {
x: 0,
transition: {
type: "spring" as const,
stiffness: 300,
damping: 30,
staggerChildren: 0.1,
delayChildren: 0.1,
},
},
closed: {
x: "100%",
transition: {
type: "spring" as const,
stiffness: 300,
damping: 30,
staggerChildren: 0.05,
staggerDirection: -1,
},
},
};
const menuItemVariants = {
open: {
y: 0,
opacity: 1,
transition: {
y: { stiffness: 1000, velocity: -100 },
},
},
closed: {
y: 20,
opacity: 0,
transition: {
y: { stiffness: 1000 },
},
},
};
// 导航链接组件
const NavLink = ({ href, children, className, onClick }: { href: string; children: React.ReactNode; className?: string; onClick?: () => void }) => (
<Link href={href} className={pathname === href ? "no-underline" : ""} onClick={onClick}>
@@ -38,25 +78,25 @@ export default function Header() {
);
return (
<>
<motion.header className="fixed top-0 left-0 right-0 bg-white/80 dark:bg-gray-950/80 py-3 px-5 z-40 backdrop-blur-sm shadow-sm">
<nav className="container max-w-7xl mx-auto flex justify-between items-center">
<div className="flex items-center">
<Link href="/">
<motion.h1 className="text-xl font-bold text-gray-900 dark:text-gray-100" whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }}>
<div className="pb-24">
<header className="w-full fixed top-0 left-0 right-0 bg-white/80 dark:bg-black/80 py-3 z-50 backdrop-blur-md border-b border-transparent dark:border-gray-800 transition-colors duration-300">
<nav className="mx-auto max-w-7xl flex justify-between items-center px-4 md:px-6">
<div className="flex items-center min-w-0">
<Link href="/" className="truncate">
<motion.h1 className="text-xl font-bold text-gray-900 dark:text-white truncate" whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }}>
智能计算实验室
</motion.h1>
</Link>
</div>
{/* 桌面端导航 */}
<div className="hidden md:flex space-x-6">
<div className="hidden md:flex space-x-6 shrink-0">
{NAV_LINKS.map((link) => (
<NavLink
key={link.path}
href={link.path}
className={`text-sm font-medium text-gray-700 dark:text-gray-200 hover:text-blue-600 dark:hover:text-blue-400 ${
pathname === link.path ? "border-b border-gray-600 dark:border-gray-400 hover:border-blue-600 dark:hover:border-blue-400" : "border-b border-transparent"
className={`text-sm font-medium text-gray-600 dark:text-gray-400 hover:text-black dark:hover:text-white transition-colors duration-200 ${
pathname === link.path ? "text-black dark:text-white font-bold" : ""
}`}
>
{link.label}
@@ -65,61 +105,49 @@ export default function Header() {
</div>
{/* 移动端菜单按钮 */}
<NavButton className="flex items-center md:hidden focus:outline-none" onClick={toggleMenu}>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-label="打开导航菜单" className="text-gray-900 dark:text-gray-100">
<NavButton className="flex items-center md:hidden focus:outline-none shrink-0 ml-4" onClick={toggleMenu}>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-label="打开导航菜单" className="text-gray-900 dark:text-white">
<path d="M4 6h16M4 12h16M4 18h16" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</NavButton>
</nav>
</motion.header>
</header>
{/* 遮罩层 */}
<div
className={`md:hidden fixed inset-0 bg-black bg-opacity-50 z-40 transition-opacity duration-300 ${isMenuOpen ? "opacity-25" : "opacity-0 pointer-events-none"}`}
className={`md:hidden fixed inset-0 bg-black/50 z-40 transition-opacity duration-300 ${isMenuOpen ? "opacity-100" : "opacity-0 pointer-events-none"}`}
onClick={closeMenu}
aria-hidden="true"
/>
{/* 移动端侧边菜单 */}
<motion.div
className="md:hidden fixed top-0 right-0 h-full w-64 bg-white dark:bg-gray-900 shadow-lg z-50"
initial={{ x: "100%" }}
animate={{ x: isMenuOpen ? 0 : "100%" }}
transition={{
type: "tween",
ease: [0.05, 1, 0.5, 1],
duration: 0.3,
}}
className="md:hidden fixed top-[57px] right-0 bottom-0 w-full max-w-xs bg-white/80 dark:bg-black/80 backdrop-blur-md border-l border-gray-200 dark:border-gray-800 shadow-2xl z-40"
initial="closed"
animate={isMenuOpen ? "open" : "closed"}
variants={sidebarVariants}
role="dialog"
aria-modal="true"
aria-label="导航菜单"
>
<div className="flex justify-between items-center p-3 border-b border-gray-200 dark:border-gray-800">
<h2 className="text-lg font-bold text-gray-900 dark:text-gray-100">智能计算实验室</h2>
<NavButton onClick={closeMenu} className="focus:outline-none">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-label="关闭导航菜单" className="text-gray-900 dark:text-gray-100">
<path d="M18 6L6 18M6 6l12 12" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</NavButton>
</div>
<div className="px-5 py-4">
<div className="px-6 py-8 flex flex-col gap-2 h-full overflow-y-auto">
{NAV_LINKS.map((link) => (
<NavLink
key={link.path}
href={link.path}
className={`block py-3 text-gray-700 dark:text-gray-200 hover:text-blue-600 dark:hover:text-blue-400 ${
pathname === link.path ? "border-l-2 border-blue-600 dark:border-blue-400 pl-3 font-medium" : "pl-3"
}`}
onClick={closeMenu}
>
{link.label}
</NavLink>
<motion.div key={link.path} variants={menuItemVariants}>
<NavLink
href={link.path}
className={`block py-4 px-4 rounded-0 text-lg transition-all duration-200 ${
pathname === link.path
? "bg-gray-100 dark:bg-gray-800 text-black dark:text-white font-bold"
: "text-gray-600 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-900 hover:text-black dark:hover:text-white"
}`}
onClick={closeMenu}
>
{link.label}
</NavLink>
</motion.div>
))}
</div>
</motion.div>
{/* 避免被导航栏遮挡 */}
<div className="h-16"></div>
</>
</div>
);
}