forked from emre/www_projectmycelium_com
		
	refactor: simplify header component and improve hero section layouts
This commit is contained in:
		@@ -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>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,13 @@
 | 
			
		||||
import { Outlet } from 'react-router-dom'
 | 
			
		||||
import { FloatingNav } from './ui/floating-navbar'
 | 
			
		||||
import { Footer } from './Footer'
 | 
			
		||||
import { Header } from './Header'
 | 
			
		||||
 | 
			
		||||
export function Layout() {
 | 
			
		||||
  const navItems = [
 | 
			
		||||
    { name: 'Home', link: '/' },
 | 
			
		||||
    { name: 'Cloud', link: '/cloud' },
 | 
			
		||||
    { name: 'Network', link: '/network' },
 | 
			
		||||
    { name: 'Agents', link: '/agents' },
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="bg-white antialiased" style={{ fontFamily: 'var(--font-inter)' }}>
 | 
			
		||||
      <Header />
 | 
			
		||||
      <main>
 | 
			
		||||
            <main className="">
 | 
			
		||||
        <Outlet />
 | 
			
		||||
      </main>
 | 
			
		||||
      <Footer />
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ export function HomeAurora() {
 | 
			
		||||
          backgroundSize: "cover",
 | 
			
		||||
          backgroundPosition: "center",
 | 
			
		||||
        }}
 | 
			
		||||
        className="relative mx-auto py-24 h-screen flex flex-col items-center justify-center gap-4 px-4 max-w-5xl"
 | 
			
		||||
        className="relative mx-auto pb-24 pt-0 h-screen flex flex-col items-center justify-center gap-4 px-4 max-w-5xl"
 | 
			
		||||
      >
 | 
			
		||||
        <div className="text-center text-gray-800">
 | 
			
		||||
          <H1>Decentralized Autonomous <span className="text-bold lg:text-8xl">Agentic Cloud.</span></H1>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,28 +1,27 @@
 | 
			
		||||
'use client'
 | 
			
		||||
 | 
			
		||||
import { H1, P } from '@/components/Texts'
 | 
			
		||||
import { FadeIn } from '@/components/FadeIn'
 | 
			
		||||
import { Button } from '@/components/Button'
 | 
			
		||||
 | 
			
		||||
export function HomeHero() {
 | 
			
		||||
  return (
 | 
			
		||||
    <div
 | 
			
		||||
      className="relative isolate overflow-hidden bg-white"
 | 
			
		||||
        <div
 | 
			
		||||
      className="relative isolate overflow-hidden bg-white h-screen -z-10  flex items-center justify-center"
 | 
			
		||||
      style={{
 | 
			
		||||
        backgroundImage: 'url(/images/cloud.png)',
 | 
			
		||||
        backgroundSize: 'cover',
 | 
			
		||||
        backgroundPosition: 'center',
 | 
			
		||||
      }}
 | 
			
		||||
    >
 | 
			
		||||
      <div className="mx-auto max-w-7xl px-6  py-24 lg:py-32 lg:flex lg:px-8">
 | 
			
		||||
        <div className="mx-auto max-w-2xl shrink-0 lg:mx-0 lg:pt-8">
 | 
			
		||||
          <H1 color="primary" className="mt-10 text-5xl font-semibold tracking-tight text-pretty sm:text-7xl">
 | 
			
		||||
      <div className="mx-auto max-w-7xl px-6 lg:px-8">
 | 
			
		||||
        <div className="-mt-32 mx-auto max-w-2xl text-center">
 | 
			
		||||
                    <H1 color="primary" className="text-5xl font-semibold tracking-tight text-pretty sm:text-7xl">
 | 
			
		||||
            Decentralized Autonomous Agentic Cloud.
 | 
			
		||||
          </H1>
 | 
			
		||||
          <P color="secondary" className="mt-8 text-lg font-medium text-pretty sm:text-xl/8">
 | 
			
		||||
            Mycelium's advancements in Agentic infrastructure supports private, secure and autonomous Agents that connect, learn and grow with you.
 | 
			
		||||
          </P>
 | 
			
		||||
          <div className="mt-10 flex items-center gap-x-6">
 | 
			
		||||
          <div className="mt-10 flex items-center justify-center gap-x-6">
 | 
			
		||||
            <Button variant="solid" color="cyan" href="#">
 | 
			
		||||
              Get started
 | 
			
		||||
            </Button>
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,7 @@ function BackgroundIllustration(props: React.ComponentPropsWithoutRef<'div'>) {
 | 
			
		||||
 | 
			
		||||
export function Hero() {
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="overflow-hidden lg:py-32 lg:pb-0 pb-24">
 | 
			
		||||
        <div className="overflow-hidden py-32">
 | 
			
		||||
      <Container>
 | 
			
		||||
        <div className="flex flex-col-reverse gap-y-16 lg:grid lg:grid-cols-12 lg:gap-x-8 lg:gap-y-20">
 | 
			
		||||
          <div className="relative z-10 mx-auto max-w-2xl lg:col-span-7 lg:max-w-none lg:pt-6 xl:col-span-6">
 | 
			
		||||
@@ -94,8 +94,8 @@ export function Hero() {
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div className="relative lg:mt-10 mt-0 lg:col-span-5 lg:row-span-2 xl:col-span-6">
 | 
			
		||||
            <BackgroundIllustration className="absolute top-4 left-1/2 h-[1026px] w-[1026px] -translate-x-1/2 stroke-gray-300/70 sm:top-16 lg:-top-12 lg:ml-12 ml-0" />
 | 
			
		||||
            <div className="mx-auto h-[448px] mask-[linear-gradient(to_bottom,white_60%,transparent)] lg:px-0 lg:absolute lg:-inset-x-10 lg:-top-24 lg:h-auto lg:pt-10 xl:-bottom-32">
 | 
			
		||||
            <BackgroundIllustration className="absolute top-4 left-1/2 h-[1026px] w-[1026px] -translate-x-1/2 stroke-gray-300/70 sm:top-16 lg:top-0 lg:ml-12 ml-0" />
 | 
			
		||||
            <div className="mx-auto h-[448px] mask-[linear-gradient(to_bottom,white_60%,transparent)] lg:px-0 lg:absolute lg:-inset-x-10 lg:top-0 lg:h-auto lg:pt-10 xl:-bottom-32">
 | 
			
		||||
              <img
 | 
			
		||||
                src={phoneFrame}
 | 
			
		||||
                alt="Mycelium application demo"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user