refactor: simplify header component and improve hero section layouts

This commit is contained in:
2025-10-23 16:36:37 +02:00
parent 987b46588b
commit 9b3c620706
5 changed files with 64 additions and 134 deletions

View File

@@ -1,123 +1,61 @@
'use client'
import { useEffect, useRef, useState } from 'react'
import { Link } from 'react-router-dom'
import { AnimatePresence, motion } from 'framer-motion'
import clsx from 'clsx'
import { Container } from './Container'
import { Button } from './Button'
function NavLinks() {
let [hoveredIndex, setHoveredIndex] = useState<number | null>(null)
let timeoutRef = useRef<number | null>(null)
return (
<>
{[
['Home', '/'],
['Cloud', '/cloud'],
['Network', '/network'],
['Agents', '/agents'],
].map(([label, href], index) => (
<Link
key={label}
to={href}
className={clsx(
'relative rounded-lg px-3 py-2 text-sm text-black transition-colors delay-150 hover:text-cyan-500 hover:delay-0',
)}
onMouseEnter={() => {
if (timeoutRef.current) {
window.clearTimeout(timeoutRef.current)
}
setHoveredIndex(index)
}}
onMouseLeave={() => {
timeoutRef.current = window.setTimeout(() => {
setHoveredIndex(null)
}, 200)
}}
>
<AnimatePresence>
{hoveredIndex === index && (
<motion.span
className="absolute inset-0 rounded-lg bg-white/50"
layoutId="hoverBackground"
initial={{ opacity: 0 }}
animate={{ opacity: 1, transition: { duration: 0.15 } }}
exit={{
opacity: 0,
transition: { duration: 0.15 },
}}
/>
)}
</AnimatePresence>
<span className="relative z-10">{label}</span>
</Link>
))}
</>
)
}
export function Header() {
const [isVisible, setIsVisible] = useState(true)
const [lastScrollY, setLastScrollY] = useState(0)
const controlHeader = () => {
if (typeof window !== 'undefined') {
if (window.scrollY > lastScrollY && window.scrollY > 100) {
// Hides when scrolling down past 100px
setIsVisible(false)
} else {
// Shows when scrolling up
setIsVisible(true)
}
setLastScrollY(window.scrollY)
}
}
useEffect(() => {
if (typeof window !== 'undefined') {
window.addEventListener('scroll', controlHeader)
return () => {
window.removeEventListener('scroll', controlHeader)
}
}
}, [lastScrollY])
return (
<motion.header
className="fixed top-0 left-0 right-0 z-50 bg-white/90 shadow-lg ring-1 ring-gray-200"
initial={{ y: 0, opacity: 1 }}
animate={{ y: isVisible ? 0 : -100, opacity: isVisible ? 1 : 0 }}
transition={{ duration: 0.3, ease: 'easeInOut' }}
>
<div className="mx-auto flex max-w-7xl items-center justify-between px-4 py-3 sm:px-6 lg:px-8">
<div className="flex items-center gap-x-5">
<Link to="/" aria-label="Home">
<img src="/src/images/logomark.svg" alt="Mycelium" className="h-10 w-auto" />
</Link>
</div>
<div className="flex items-center gap-x-5">
<NavLinks />
</div>
<div className="flex items-center gap-8">
<div className="flex items-center gap-6 max-lg:hidden">
<Button
to="https://threefold.info/mycelium_network/docs/"
variant="outline"
as="a"
target="_blank"
rel="noopener noreferrer"
>
Docs
</Button>
<Button to="/download" variant="solid" color="cyan">
Get Mycelium
</Button>
<header>
<nav>
<Container className="relative z-50 flex justify-between py-8">
<div className="relative z-10 flex items-center gap-16">
<Link to="/" aria-label="Home">
<img src="/src/images/logomark.svg" alt="Mycelium" className="h-10 w-auto" />
</Link>
<div className="hidden lg:flex lg:gap-10">
<Link
to="/"
className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
>
Home
</Link>
<Link
to="/cloud"
className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
>
Cloud
</Link>
<Link
to="/network"
className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
>
Network
</Link>
<Link
to="/agents"
className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
>
Agents
</Link>
</div>
</div>
</div>
</div>
</motion.header>
<div className="flex items-center gap-6">
<div className="flex items-center gap-6 max-lg:hidden">
<Button
to="https://threefold.info/mycelium_network/docs/"
variant="outline"
as="a"
target="_blank"
rel="noopener noreferrer"
>
Docs
</Button>
<Button to="/download" variant="solid" color="cyan">
Get Mycelium
</Button>
</div>
</div>
</Container>
</nav>
</header>
)
}