generated from acmucsd/website-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
abd1f64
commit 00c77e2
Showing
8 changed files
with
233 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
'use client'; | ||
|
||
import { useEffect, useRef, useState } from 'react'; | ||
import styles from './style.module.scss'; | ||
import Typography from '../Typography'; | ||
import Image from 'next/image'; | ||
import Link from 'next/link'; | ||
import MenuIcon from '@mui/icons-material/Menu'; | ||
import CloseIcon from '@mui/icons-material/Close'; | ||
import { SwipeableDrawer } from '@mui/material'; | ||
|
||
const NavbarLogo = () => ( | ||
<div className={styles.logo}> | ||
<Image src="/assets/acm-logo.png" alt="ACM Logo" width={48} height={48} /> | ||
<Typography variant="body/large" className={styles.logoText}> | ||
<b>diamond</b> | ||
<br /> | ||
hacks | ||
</Typography> | ||
</div> | ||
); | ||
|
||
const links = [ | ||
{ name: 'Home', href: '/' }, | ||
{ name: 'About', href: '/#about' }, | ||
{ name: 'Impact', href: '/#impact' }, | ||
{ name: 'FAQ', href: '/#faq' }, | ||
{ name: 'Sponsors', href: '/#sponsors' }, | ||
{ name: '2024', href: 'https://2024.diamondhacks.acmucsd.com' }, | ||
]; | ||
|
||
const DEBOUNCE_MS = 150; // Prevent back-to-back updates within 150ms | ||
const MOBILE_BREAKPOINT = 870; // Matches $breakpoint-md from vars.scss | ||
|
||
export default function Navbar() { | ||
const [prevScrollPos, setPrevScrollPos] = useState(0); | ||
const [visible, setVisible] = useState(true); | ||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false); | ||
const lastUpdate = useRef(0); | ||
|
||
const onLinkClick = () => { | ||
lastUpdate.current = Date.now(); | ||
setVisible(false); | ||
setMobileMenuOpen(false); | ||
}; | ||
|
||
useEffect(() => { | ||
// Show/hide navbar on scroll | ||
const handleScroll = () => { | ||
const currentScrollPos = window.scrollY; | ||
const now = Date.now(); | ||
|
||
const readyToUpdate = now - lastUpdate.current > DEBOUNCE_MS; | ||
|
||
// Show navbar when scrolling up or at top of page | ||
const scrollingUp = currentScrollPos < prevScrollPos; | ||
const topOfPage = currentScrollPos < 10; | ||
const shouldBeVisible = scrollingUp || topOfPage; | ||
|
||
if (readyToUpdate) { | ||
setVisible(shouldBeVisible); | ||
setPrevScrollPos(currentScrollPos); | ||
lastUpdate.current = now; | ||
} | ||
}; | ||
|
||
window.addEventListener('scroll', handleScroll); | ||
return () => window.removeEventListener('scroll', handleScroll); | ||
}, [prevScrollPos]); | ||
|
||
useEffect(() => { | ||
// Close mobile menu when screen gets larger than mobile breakpoint | ||
const handleResize = () => { | ||
if (window.innerWidth > MOBILE_BREAKPOINT) { | ||
setMobileMenuOpen(false); | ||
} | ||
}; | ||
|
||
window.addEventListener('resize', handleResize); | ||
return () => window.removeEventListener('resize', handleResize); | ||
}, []); | ||
|
||
return ( | ||
<> | ||
<div className={`${styles.container} ${visible ? styles.visible : styles.hidden}`}> | ||
<NavbarLogo /> | ||
<Typography variant="body/large" className={styles.desktopLinks}> | ||
{links.map(link => ( | ||
<Link href={link.href} className={styles.link}> | ||
{link.name} | ||
</Link> | ||
))} | ||
</Typography> | ||
<div className={styles.mobileIcons}> | ||
<div className={`${styles.menuIcon} ${mobileMenuOpen ? '' : styles.hidden}`}> | ||
<CloseIcon onClick={() => setMobileMenuOpen(false)} /> | ||
</div> | ||
<div className={`${styles.menuIcon} ${mobileMenuOpen ? styles.hidden : ''}`}> | ||
<MenuIcon onClick={() => setMobileMenuOpen(true)} /> | ||
</div> | ||
</div> | ||
</div> | ||
<SwipeableDrawer | ||
anchor="top" | ||
open={mobileMenuOpen} | ||
onClose={() => setMobileMenuOpen(false)} | ||
onOpen={() => setMobileMenuOpen(true)} | ||
> | ||
<div className={styles.mobileMenu}> | ||
{links.map(link => ( | ||
<Link href={link.href} className={styles.link} onClick={onLinkClick}> | ||
{link.name} | ||
</Link> | ||
))} | ||
</div> | ||
</SwipeableDrawer> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
@use '../../styles/vars.scss' as vars; | ||
|
||
.container { | ||
display: flex; | ||
flex-direction: row; | ||
justify-content: space-between; | ||
align-items: center; | ||
position: fixed; | ||
top: 0; | ||
left: 0; | ||
right: 0; | ||
z-index: 1000; | ||
padding: 2rem vars.$side-padding; | ||
background-color: vars.$black; | ||
transition: transform 0.15s ease-in-out; | ||
z-index: 2000; | ||
|
||
@media screen and (max-width: vars.$breakpoint-md) { | ||
padding: 1rem vars.$side-padding-mobile; | ||
} | ||
} | ||
|
||
.visible { | ||
transform: translateY(0); | ||
} | ||
|
||
.hidden { | ||
transform: translateY(-100%); | ||
} | ||
|
||
.logo { | ||
display: flex; | ||
flex-direction: row; | ||
align-items: center; | ||
gap: 0.5rem; | ||
|
||
@media screen and (max-width: vars.$breakpoint-md) { | ||
color: vars.$white; | ||
align-self: flex-start; | ||
} | ||
} | ||
|
||
.logoText { | ||
font-weight: 200 !important; | ||
line-height: 1.375rem !important; | ||
} | ||
|
||
.desktopLinks { | ||
display: flex; | ||
flex-direction: row; | ||
gap: 2rem; | ||
|
||
@media screen and (max-width: vars.$breakpoint-md) { | ||
display: none; | ||
} | ||
} | ||
|
||
.link { | ||
text-decoration: none; | ||
color: vars.$white; | ||
|
||
@media screen and (max-width: vars.$breakpoint-md) { | ||
background-color: vars.$black; | ||
text-align: center; | ||
} | ||
} | ||
|
||
.mobileIcons { | ||
display: none; | ||
position: relative; | ||
width: 24px; | ||
height: 24px; | ||
overflow: hidden; | ||
|
||
.menuIcon { | ||
position: absolute; | ||
right: 0; | ||
top: 0; | ||
opacity: 1; | ||
transition: opacity 0.3s ease-in-out; | ||
cursor: pointer; | ||
|
||
&.hidden { | ||
opacity: 0; | ||
pointer-events: none; | ||
} | ||
} | ||
|
||
@media screen and (max-width: vars.$breakpoint-md) { | ||
display: block; | ||
} | ||
} | ||
|
||
.mobileMenu { | ||
padding: 1.5rem vars.$side-padding-mobile; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
gap: 1.5rem; | ||
background-color: vars.$black; | ||
padding-top: 6rem; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters