Skip to content

Commit

Permalink
fix: fix linting and styling issues and refactor navbar logic
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronchan32 committed May 30, 2024
1 parent 44e1d7e commit 8317796
Show file tree
Hide file tree
Showing 12 changed files with 202 additions and 113 deletions.
1 change: 0 additions & 1 deletion src/app/Home.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
}

section {

scroll-snap-align: center;
padding-block: $main-padding-mobile-block;
padding-inline: $main-padding-mobile-inline;
Expand Down
14 changes: 11 additions & 3 deletions src/app/components/Navbar/Navbar.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
nav {
nav {
a {
text-decoration: none;
}
Expand Down Expand Up @@ -96,7 +96,7 @@ nav {
transition: width 0.3s ease-in;
}

&:hover:before {
&:is(:hover, :focus-visible):before {
width: 100%;
left: 0;
}
Expand All @@ -114,11 +114,19 @@ nav {
color: #212121;
opacity: 0.45;
max-width: 310px;
height: 1em;
// &::before {
// content: '********************************************************************************';
// display: block;
// white-space: nowrap;
// width: 100%;
// height: 100%;
// overflow: hidden;
// }
}

.nav-footer {
margin-top: auto;
//margin-bottom: 86px;
display: flex;
justify-content: center;
flex-direction: column;
Expand Down
104 changes: 28 additions & 76 deletions src/app/components/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
'use client';
import Link from 'next/link';
import './Navbar.scss';
import { useState, useEffect, useRef } from 'react';
import { useState, useRef, RefObject } from 'react';
import Hamburger from './Hamburger/Hamburger';
import FocusTrap from 'focus-trap-react';
import FAQ from '@/pages/FAQ/FAQ';
import { handleToggle } from './hooks/handleToggle';
import { useHandleHamburger } from './hooks/useHandleHamburger';
import { useHandleAsterisks } from './hooks/useHandleAsterisks';
import { useHandleScroll } from './hooks/useHandleScroll';

type NavbarProps = {
pageRefs: {
mainRef: React.RefObject<HTMLElement>;
landingRef: React.RefObject<HTMLElement>;
overviewRef: React.RefObject<HTMLElement>;
themesRef: React.RefObject<HTMLElement>;
faqRef: React.RefObject<HTMLElement>;
applyRef: React.RefObject<HTMLElement>;
}
}
mainRef: RefObject<HTMLElement>;
landingRef: RefObject<HTMLElement>;
overviewRef: RefObject<HTMLElement>;
themesRef: RefObject<HTMLElement>;
faqRef: RefObject<HTMLElement>;
applyRef: RefObject<HTMLElement>;
};
};

const NAV_LINKS = [
{ href: '#landing', text: 'Home' },
Expand All @@ -26,74 +27,21 @@ const NAV_LINKS = [
{ href: '#apply', text: 'Apply' }
];

const PAGE_TYPES = ["Home", "Overview", "Themes", "FAQ", "Apply"]

const PAGE_TYPES = ['Home', 'Overview', 'Themes', 'FAQ', 'Apply'] as const;
export type PageType = (typeof PAGE_TYPES)[number];

export default function Navbar({pageRefs}: NavbarProps) {
const { mainRef, landingRef, overviewRef, themesRef, faqRef, applyRef } = pageRefs;
const [numAstericks, setNumAsterisks] = useState(0);
export default function Navbar({ pageRefs }: NavbarProps) {
const navContainerRef = useRef<HTMLDivElement | null>(null);
const asterisksRef1 = useRef<HTMLDivElement | null>(null);
const asterisksRef2 = useRef<HTMLDivElement | null>(null);
const [currPage, setCurrPage] = useState('Home');

const {toggleHamburger, isHamburgerOpen, hamburgerInnerRef} = handleToggle({navContainerRef});

useEffect(() => {
const mainElement = mainRef.current;
const landingElement = landingRef.current;
const overviewElement = overviewRef.current;
const themesElement = themesRef.current;
const faqElement = faqRef.current;
const applyElement = applyRef.current;

/**
* Sets the current page
* Current page is based on what part of scroll we are at
*/
if (!mainElement || !landingElement || !overviewElement || !themesElement || !faqElement || !applyElement) return;
const [currPage, setCurrPage] = useState<PageType>('Home');

const pagesList = [landingElement, overviewElement, themesElement, faqElement, applyElement]
const handleScroll = () => {
const scrollPosition = mainElement.scrollTop || 0;

pagesList.forEach((page, index) => {
const pageTop = page.offsetTop;
const pageBottom = pageTop + page.clientHeight;

const halfScrollPosition = scrollPosition + window.innerHeight/2;
if(halfScrollPosition > pageTop && halfScrollPosition < pageBottom){
setCurrPage(PAGE_TYPES[index]);
}
});
}
const { toggleHamburger, isHamburgerOpen, hamburgerInnerRef } =
useHandleHamburger({ navContainerRef });

mainElement.addEventListener("scroll", handleScroll)
/**
* Dynamically set the number of astricks
*/
const updateAsterisks = () => {
if (asterisksRef1.current) {
const width = asterisksRef1.current.getBoundingClientRect().width;
const calcNumAstericks = Math.floor(width / 10);
setNumAsterisks(calcNumAstericks);
}
if (asterisksRef2.current) {
const width = asterisksRef2.current.getBoundingClientRect().width;
const calcNumAstericks = Math.floor(width / 10);
setNumAsterisks(calcNumAstericks);
}
};
const { numAstericks } = useHandleAsterisks({ asterisksRef1, asterisksRef2 });


updateAsterisks();
window.addEventListener('resize', updateAsterisks);

return () => {
window.removeEventListener('resize', updateAsterisks)
mainElement.removeEventListener('scroll', handleScroll)
};
}, []);
useHandleScroll({ setCurrPage, pageRefs, PAGE_TYPES });

return (
<FocusTrap active={isHamburgerOpen}>
Expand Down Expand Up @@ -133,12 +81,16 @@ export default function Navbar({pageRefs}: NavbarProps) {
}}
>
<div className="nav-link-list">
<h3 className="nav-link" style={{backgroundColor: currPage === link.text ? '#f5ff85' : ''}}>
<h3
className="nav-link"
style={{
backgroundColor:
currPage === link.text ? '#f5ff85' : ''
}}
>
{link.text.toUpperCase()}
</h3>
<h3 style={{ marginLeft: 'auto' }}>
{`.0${index + 1}`}
</h3>
<h3 style={{ marginLeft: 'auto' }}>{`.0${index + 1}`}</h3>
</div>
</a>
</Link>
Expand Down
41 changes: 41 additions & 0 deletions src/app/components/Navbar/hooks/useHandleAsterisks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { RefObject, useEffect, useState } from 'react';

type UseHandleAsterisksProps = {
asterisksRef1: RefObject<HTMLDivElement>;
asterisksRef2: RefObject<HTMLDivElement>;
};

export const useHandleAsterisks = ({
asterisksRef1,
asterisksRef2
}: UseHandleAsterisksProps) => {
const [numAstericks, setNumAsterisks] = useState(0);

// TODO: add animation when asterisk first load in to make it less jarring (stagger effect?)
useEffect(() => {
/**
* Dynamically set the number of astricks
*/
const updateAsterisks = () => {
if (asterisksRef1.current) {
const width = asterisksRef1.current.getBoundingClientRect().width;
const calcNumAstericks = Math.floor(width / 10);
setNumAsterisks(calcNumAstericks);
}
if (asterisksRef2.current) {
const width = asterisksRef2.current.getBoundingClientRect().width;
const calcNumAstericks = Math.floor(width / 10);
setNumAsterisks(calcNumAstericks);
}
};

updateAsterisks();
window.addEventListener('resize', updateAsterisks);

return () => {
window.removeEventListener('resize', updateAsterisks);
};
});

return { numAstericks };
};
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { useState, useRef } from "react";
import { useState, useRef, RefObject } from 'react';

type handleToggleProps = {
navContainerRef: React.RefObject<HTMLDivElement>;
}
type UseHandleHamburgerProps = {
navContainerRef: RefObject<HTMLDivElement>;
};

export const handleToggle = ({navContainerRef}: handleToggleProps) => {
export const useHandleHamburger = ({
navContainerRef
}: UseHandleHamburgerProps) => {
const hamburgerInnerRef = useRef<HTMLSpanElement>(null);
const [isHamburgerOpen, setIsHamburgerOpen] = useState(false);

const toggleHamburger = () => {
console.log(navContainerRef.current?.classList)
navContainerRef.current?.classList.toggle("slideTransition")
console.log(navContainerRef.current?.classList)
// Toggle slide transition to account for mobile to desktop resize
navContainerRef.current?.classList.toggle('slideTransition');
setIsHamburgerOpen(!isHamburgerOpen);

if (!isHamburgerOpen) {
Expand Down Expand Up @@ -40,5 +41,5 @@ export const handleToggle = ({navContainerRef}: handleToggleProps) => {
}
};

return {toggleHamburger, isHamburgerOpen, hamburgerInnerRef}
}
return { toggleHamburger, isHamburgerOpen, hamburgerInnerRef };
};
81 changes: 81 additions & 0 deletions src/app/components/Navbar/hooks/useHandleScroll.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { Dispatch, RefObject, SetStateAction, useEffect } from 'react';
import { PageType } from '../Navbar';

type UseHandleScrollType = {
setCurrPage: Dispatch<SetStateAction<PageType>>;
pageRefs: {
mainRef: RefObject<HTMLElement>;
landingRef: RefObject<HTMLElement>;
overviewRef: RefObject<HTMLElement>;
themesRef: RefObject<HTMLElement>;
faqRef: RefObject<HTMLElement>;
applyRef: RefObject<HTMLElement>;
};
PAGE_TYPES: readonly ['Home', 'Overview', 'Themes', 'FAQ', 'Apply'];
};

export const useHandleScroll = ({
setCurrPage,
pageRefs,
PAGE_TYPES
}: UseHandleScrollType) => {
const { mainRef, landingRef, overviewRef, themesRef, faqRef, applyRef } =
pageRefs;
useEffect(() => {
const mainElement = mainRef.current;
const landingElement = landingRef.current;
const overviewElement = overviewRef.current;
const themesElement = themesRef.current;
const faqElement = faqRef.current;
const applyElement = applyRef.current;

/**
* Sets the current page
* Current page is based on what part of scroll we are at
*/
if (
!mainElement ||
!landingElement ||
!overviewElement ||
!themesElement ||
!faqElement ||
!applyElement
)
return;

const pagesList = [
landingElement,
overviewElement,
themesElement,
faqElement,
applyElement
];
const handleScroll = () => {
const scrollPosition = mainElement.scrollTop || 0;

pagesList.forEach((page, index) => {
const pageTop = page.offsetTop;
const pageBottom = pageTop + page.clientHeight;

const halfScrollPosition = scrollPosition + window.innerHeight / 2;
if (halfScrollPosition > pageTop && halfScrollPosition < pageBottom) {
setCurrPage(PAGE_TYPES[index]);
}
});
};

mainElement.addEventListener('scroll', handleScroll);
return () => {
mainElement.removeEventListener('scroll', handleScroll);
};
}, [
PAGE_TYPES,
applyRef,
faqRef,
landingRef,
mainRef,
overviewRef,
setCurrPage,
themesRef
]);
};
22 changes: 15 additions & 7 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"use client";
'use client';

import React, { useRef } from 'react';
import './Home.scss';
Expand All @@ -10,8 +10,7 @@ import FAQ from './pages/FAQ/FAQ';
import Apply from './pages/Apply/Apply';
import Navbar from './components/Navbar/Navbar';

export type PageRef = React.RefObject<HTMLElement>

export type PageRef = React.RefObject<HTMLElement>;

export default function Home() {
const mainRef = useRef<HTMLDivElement>(null);
Expand All @@ -23,14 +22,23 @@ export default function Home() {

return (
<main className="home_page">
<Navbar pageRefs={{mainRef, landingRef, overviewRef, themesRef, faqRef, applyRef}}/>
<Navbar
pageRefs={{
mainRef,
landingRef,
overviewRef,
themesRef,
faqRef,
applyRef
}}
/>
<div ref={mainRef} className="main-content">
<Landing landingRef={landingRef} />
<Overview overviewRef={overviewRef}/>
<Overview overviewRef={overviewRef} />
<Themes themesRef={themesRef} />
<FAQ faqRef={faqRef}/>
<FAQ faqRef={faqRef} />
{/* Footer is inside Apply */}
<Apply applyRef={applyRef}/>
<Apply applyRef={applyRef} />
</div>
</main>
);
Expand Down
Loading

0 comments on commit 8317796

Please sign in to comment.