diff --git a/components/footer.tsx b/components/footer.tsx index 4b8550f..9af8993 100644 --- a/components/footer.tsx +++ b/components/footer.tsx @@ -1,4 +1,4 @@ -import { Footer } from "../components/styles/generic" +import { Footer, MobileFooter } from "../components/styles/generic" const PageFooter = () => { return ( @@ -7,5 +7,13 @@ const PageFooter = () => { ); } + +const NavMenuFooter = () => { + return ( + + Built using Next.js + + ); +} export default PageFooter; \ No newline at end of file diff --git a/components/layout.tsx b/components/layout.tsx index 8482b63..cb416d6 100644 --- a/components/layout.tsx +++ b/components/layout.tsx @@ -2,40 +2,80 @@ import PageFooter from './footer'; import PageNavbar from './navbar'; import Script from 'next/script'; import { Page, Main } from './styles/generic'; +import useWindowSize from './windowsize'; const Layout = ({ children }: { children: React.ReactNode }) => { - return ( - - - + const isMobile = useWindowSize(); - -
- {children} -
- -
- ); + let ret: JSX.Element; + if(isMobile) { + ret = ( + + + + + +
+ {children} +
+
+ ); + } + else { + ret = ( + + + + + +
+ {children} +
+ +
+ ); + } + return ret; } export default Layout; \ No newline at end of file diff --git a/components/navbar.tsx b/components/navbar.tsx index 6994205..6d3dbe7 100644 --- a/components/navbar.tsx +++ b/components/navbar.tsx @@ -1,27 +1,74 @@ import { usePathname } from 'next/navigation' -import { NavBar, NavLink, NavWrap } from './styles/navbar'; +import { NavBar, NavBarMobile, NavIndicator, NavIndicators, NavLink, NavSideMenu, NavSideMenuButton, NavSideMenuPanel, NavSideMenuButtonPlaceholder, NavWrap, NavWrapMobile, NavWrapMobileGhost, NavSideMenuGhost } from './styles/navbar'; import { StyleSelector, StyleSelectorPlaceholder } from './themeselector'; import Links from '../public/data/navbar.json'; +import { useState } from 'react'; +import NavMenuFooter from './footer'; -const PageNavbar = () => { +const PageNavbar = ({ mobile }: { mobile: number }) => { const path = usePathname(); + const [sideBarActive, setSideBarActive] = useState(true); //DEBUG: set to false - return ( - - - - {Links.links.map((item) => ( - - {item.name} + function handleSidebar(event: any) { + if (!event.currentTarget.contains(event.relatedTarget)) { + setSideBarActive(false); + console.log(event.relatedTarget); // DEBUG + } + else { console.log("nah") } // DEBUG + } + + let navbar: JSX.Element; + if (mobile) { + navbar = ( + <> + handleSidebar(event)} active={+sideBarActive}> + + {Links.links.map((item) => ( + + {item.name} + + ))} + + Mastodon + + + + + + + + + setSideBarActive(!sideBarActive)} active={+sideBarActive}>Menu + + {Links.links.map((item) => ( + + ))} + + + + + + ); + } + else { + navbar = ( + + + + {Links.links.map((item) => ( + + {item.name} + + ))} + + Mastodon - ))} - - Mastodon - - - - - ); + + + + ); + } + return navbar; } export default PageNavbar; \ No newline at end of file diff --git a/components/styles/generic.tsx b/components/styles/generic.tsx index b74877c..3aa4db4 100644 --- a/components/styles/generic.tsx +++ b/components/styles/generic.tsx @@ -43,3 +43,8 @@ export const Footer = styled.footer` flex-grow: 1; } ` + +export const MobileFooter = styled(Footer)` + position: absolute; + bottom: 100%; +` diff --git a/components/styles/navbar.tsx b/components/styles/navbar.tsx index 4b9f0d3..4eade9d 100644 --- a/components/styles/navbar.tsx +++ b/components/styles/navbar.tsx @@ -13,6 +13,61 @@ export const NavWrap = styled.div` border-bottom: 1px solid ${({ theme }) => theme.colors.primary}; ` + +export const NavWrapMobile = styled(NavWrap)` + width: 100%; + flex-direction: row; + position: fixed; + z-index: 100; +` + +export const NavWrapMobileGhost = styled.div` + position: relative; + width: 100%; + height: 57px; +` + +export const NavSideMenu = styled.div ` + position: fixed; + top: 0%; left: 0%; right: 0%; bottom: 0%; + max-width: ${ props => props.active ? "60%" : "0%"}; + display: flex; + justify-content: space-between; + flex-direction: column; + align-items: center; + height: 100%; + z-index: 100; + + background-color: ${({ theme }) => theme.colors.background}; + visibility: ${ props => props.active ? "visible" : "hidden"}; + width: ${ props => props.active ? "360px" : "0%"}; + transition-delay: ${ props => props.active ? "0s, 0s" : "0s, 0.3s"}; +` + +export const NavSideMenuPanel = styled.div ` + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + +` + +export const NavSideMenuButton = styled.button ` + z-index: 100; + margin: 16px; + color: ${ props => props.active ? ({ theme }) => theme.colors.background : ({ theme }) => theme.colors.primary }; + background-color: ${ props => props.active ? ({ theme }) => theme.colors.secondary : ({ theme }) => theme.colors.background }; +` + +export const NavSideMenuButtonPlaceholder = styled.div` + width: 48px; + margin: 16px; +` + +export const NavSideMenuGhost = styled.div` + +` + export const NavBar = styled.nav` margin-right: 1%; display: flex; @@ -23,6 +78,10 @@ export const NavBar = styled.nav` align-items: center; ` +export const NavBarMobile = styled(NavBar)` + flex-direction: column; +` + export const NavLink = styled(Link) ` color: ${props => props.active ? ({ theme }) => theme.invertButtons ? @@ -44,6 +103,39 @@ export const NavLink = styled(Link) ` align-items: center; transition: all 0.1s ease; + &:hover { + color: ${({ theme }) => theme.invertButtons ? + theme.colors.text ? theme.colors.text : theme.colors.primary : + theme.colors.secondary}; + + background-color: ${({ theme }) => theme.invertButtons ? + theme.colors.secondary : + theme.colors.background}; + } +` + +export const NavIndicators = styled.nav` + width: 100%; + display: flex; + flex: 1; + padding: 1rem 0; + flex-wrap: nowrap; + justify-content: center; + align-items: center; +` + +export const NavIndicator = styled(Link) ` + margin: 0.2rem; + border-radius: 50%; + aspect-ratio: 1; + width: 10px; + border: 1px solid ${({ theme }) => theme.colors.primary}; + + background-color: ${props => props.active ? + ({ theme }) => theme.invertButtons ? + theme.colors.secondary : theme.colors.background : + ({ theme }) => theme.colors.background}; + &:hover { color: ${({ theme }) => theme.invertButtons ? theme.colors.text ? theme.colors.text : theme.colors.primary : diff --git a/components/windowsize.tsx b/components/windowsize.tsx new file mode 100644 index 0000000..61f6ca7 --- /dev/null +++ b/components/windowsize.tsx @@ -0,0 +1,34 @@ +import { useEffect, useState } from "react"; + +interface ScreenSize { + width: number | undefined; + height: number | undefined; +} + +export default function useWindowSize(): number { + const [windowSize, setWindowSize] = useState({ + width: undefined, + height: undefined, + }); + + useEffect(() => { + function handleResize() { + setWindowSize({ + width: window.innerWidth, + height: window.innerHeight, + }); + } + + window.addEventListener("resize", handleResize); + + handleResize(); + + return () => window.removeEventListener("resize", handleResize); + }, []); + if(typeof(windowSize.width) === "number") { + return windowSize.width <= 1080 ? 1 : 0; + } + else { + return 0; + } +} \ No newline at end of file