diff --git a/web/src/app/layout.tsx b/web/src/app/layout.tsx index 9bb4b5f..4a852ea 100644 --- a/web/src/app/layout.tsx +++ b/web/src/app/layout.tsx @@ -1,6 +1,7 @@ import type { Metadata } from 'next' import { Geist, Geist_Mono, Averia_Serif_Libre } from 'next/font/google' import './globals.css' +import Navbar from '@/components/Navbar' const geistSans = Geist({ variable: '--font-geist-sans', @@ -32,7 +33,9 @@ export default function RootLayout({ + {children} diff --git a/web/src/components/Navbar.tsx b/web/src/components/Navbar.tsx new file mode 100644 index 0000000..660e912 --- /dev/null +++ b/web/src/components/Navbar.tsx @@ -0,0 +1,163 @@ +'use client' + +import { useEffect, useRef, useState } from 'react' +import Link from 'next/link' +import Image from 'next/image' +import { usePathname } from 'next/navigation' + +const navLinks = [ + { label: 'Home', href: '/' }, + { label: 'About Us', href: '/about' }, + { label: 'Events', href: '/events' }, + { label: 'Sponsors', href: '/sponsors' }, +] + +const ctaLink = { label: 'Join SSA!', href: '/contact' } + +export default function Navbar() { + const [hidden, setHidden] = useState(false) + const [menuOpen, setMenuOpen] = useState(false) + const pathname = usePathname() + const menuOpenRef = useRef(false) + + useEffect(() => { + menuOpenRef.current = menuOpen + }, [menuOpen]) + + useEffect(() => { + // eslint-disable-next-line react-hooks/exhaustive-deps + setHidden(window.scrollY > 80) + + let lastY = window.scrollY + + const handleScroll = () => { + if (menuOpenRef.current) return + const y = window.scrollY + if (y > lastY && y > 80) { + setHidden(true) + } else if (y <= lastY) { + setHidden(false) + } + lastY = y + } + + window.addEventListener('scroll', handleScroll, { passive: true }) + return () => window.removeEventListener('scroll', handleScroll) + }, []) + + useEffect(() => { + const handleResize = () => { + if (window.innerWidth >= 768) setMenuOpen(false) + } + window.addEventListener('resize', handleResize) + return () => window.removeEventListener('resize', handleResize) + }, []) + + useEffect(() => { + if (menuOpen) { + document.body.style.overflow = 'hidden' + } else { + document.body.style.overflow = '' + } + return () => { + document.body.style.overflow = '' + } + }, [menuOpen]) + + return ( + <> + + +
+ +
+ + {menuOpen && ( +
setMenuOpen(false)} + /> + )} + + ) +}