diff --git a/src/components/AppBar/AppBar.tsx b/src/components/AppBar/AppBar.tsx index ddd57ed..1554b91 100644 --- a/src/components/AppBar/AppBar.tsx +++ b/src/components/AppBar/AppBar.tsx @@ -2,7 +2,12 @@ import { Searchbar } from '@/components/Searchbar' import { uiConfigs } from '@/configs/ui.configs' import { useSearchBarContext } from '@/context/searchbar.context' import { useScrollDirection } from '@/utils/ui.utils' -import { IconButton, SearchIcon } from '@acid-info/lsd-react' +import { + IconButton, + MenuIcon, + SearchIcon, + Typography, +} from '@acid-info/lsd-react' import styled from '@emotion/styled' import Link from 'next/link' import { useRouter } from 'next/router' @@ -10,199 +15,156 @@ import { useEffect, useState } from 'react' import { LogosIcon } from '../Icons/LogosIcon' import { MoonIcon } from '../Icons/MoonIcon' import { SunIcon } from '../Icons/SunIcon' +import { useThemeState } from '@/states/themeState' +import { NavbarLinks } from '@/components/AppBar/Navbar.Links' +import { NavLinksItems } from '@/configs/data.configs' +import { NavbarMobileMenu } from '@/components/AppBar/Navbar.MobileMenu' +import { ThemeSwitch } from '@/components/ThemeSwitch/ThemeSwitch' -interface AppBarProps { - isDark: boolean - toggle: () => void - onSearch?: (query: string, tags: string[]) => void - onReset?: () => void -} +interface AppBarProps {} -export default function AppBar({ - isDark, - toggle, - onReset, - onSearch, -}: AppBarProps) { - const { resultsNumber } = useSearchBarContext() +export default function AppBar({}: AppBarProps) { + const themeState = useThemeState() const { pathname } = useRouter() const isSearchPage = pathname === '/search' - - const [hideSearch, setHideSearch] = useState( - resultsNumber === null && !isSearchPage, - ) const [hide, setHide] = useState(false) const scrollDirection = useScrollDirection() - const onSearchIconClick = () => { - setHideSearch(!hideSearch) - } - - useEffect(() => { - if (scrollDirection) { - setHide(scrollDirection === 'down') - if (!hideSearch && resultsNumber === null) { - setHideSearch(scrollDirection === 'down') - } - } - setHideSearch(resultsNumber === null) - }, [scrollDirection, resultsNumber]) + const [showMobileMenu, setShowMobileMenu] = useState(false) const className = pathname.split('/')[1] + '_page' + const onSearchIconClick = () => {} + + const toggleMobileMenu = () => { + setShowMobileMenu(!showMobileMenu) + } + return ( - - + + - - - toggle()}> - - - - onSearchIconClick()} - > - - - - - - - + + Press Engine + + + + + + +
+ +
+
+ + + +
+ {/* onSearchIconClick()}*/} + {/*>*/} + {/* */} + {/**/} +
+ {showMobileMenu && } + + {/**/} + {/* */} + {/**/}
) } -const Container = styled.div` +const PressLogoType = styled(Typography)`` + +const Container = styled.header` width: 100%; - transition: top 0.2s; + height: 44px; + position: fixed; top: 0; + left: 0; z-index: 101; - left: calc(calc(100% - ${uiConfigs.maxContainerWidth}px) / 2); - &._page { - @media (min-width: 768px) { - .searchBar { - display: none; - } - } - .searchIconHome { - display: none; - } - } + background: rgb(var(--lsd-surface-primary)); + transition: top 0.2s; &.article_page, &.search_page { } - - @media (max-width: ${uiConfigs.maxContainerWidth}px) { - left: 16px; - width: calc(100% - 32px); - } - - @media (max-width: 768px) { - left: 0; - width: 100%; - &.hide { - top: -44px; - } - } - - > * { - position: absolute; - top: 0; - left: 0; - } ` -const MobileSearchContainer = styled.div` - width: 100%; - transition: transform 0.3s ease-in-out; - z-index: 98; - transform: translateY(44px); - - @media (max-width: 768px) { - display: block; - &.hide { - transform: translateY(0); - } - } -` - -const NavBar = styled.nav` +const NavBarContainer = styled.nav` display: flex; padding: 8px 0; align-items: center; - justify-content: center; + justify-content: space-between; + position: relative; + border-bottom: 1px solid rgb(var(--lsd-theme-primary)); - //position: fixed; + + margin: auto; + top: 0; - width: 100%; - height: 44px; + width: calc(100% - 32px); max-width: ${uiConfigs.maxContainerWidth}px; - background: rgb(var(--lsd-surface-primary)); - z-index: 100; box-sizing: border-box; - &:last-child { - margin-left: auto; - } - - // to center-align logo - &:before { - content: 'D'; - width: 54px; - margin: 1px auto 1px 1px; - visibility: hidden; - } - - /* temporary breakpoint */ - @media (max-width: 768px) { - padding: 8px; - - &:before { - display: none; - } + > * { + display: flex; + align-items: center; } ` -const LogosIconContainer = styled(Link)` - display: flex; - align-items: center; +const NavLinksContainer = styled.div` + flex: 1; justify-content: center; - cursor: pointer; - @media (max-width: 768px) { - margin-left: unset; + @media (max-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + display: none !important; } ` -const Icons = styled.div` +const LeftContainer = styled(Link)` + flex: 0 0 auto; + text-decoration: none; + position: absolute; + left: 0; display: flex; - align-items: center; - margin-left: auto; - > *:last-of-type { - margin-left: -1px; + @media (max-width: 768px) { + position: relative; + } +` + +const ControlsContainer = styled.div` + .theme-switch { + display: block; } - .searchIcon { + .menu-button { display: none; } @media (max-width: 768px) { - .searchIcon { + .theme-switch { + // hide theme switch + display: none; + } + + .menu-button { display: block; } } diff --git a/src/components/AppBar/Navbar.Links.tsx b/src/components/AppBar/Navbar.Links.tsx new file mode 100644 index 0000000..f67849a --- /dev/null +++ b/src/components/AppBar/Navbar.Links.tsx @@ -0,0 +1,47 @@ +import Link from 'next/link' +import styled from '@emotion/styled' + +interface Props { + links: { href: string; label: string }[] +} + +export const NavbarLinks = ({ links }: Props) => { + return ( + + {links.map((link, idx) => ( + <> + + {link.label} + + {idx !== links.length - 1 && } + + ))} + + ) +} + +const Container = styled.div` + display: flex; + justify-content: center; + align-items: center; + a { + text-decoration: none; + } + + .divider { + display: block; + width: 2px; + height: 2px; + background: rgb(var(--lsd-surface-secondary)); + border-radius: 50%; + margin: 0 20px; + } + + @media (max-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + flex-direction: column; + align-items: flex-start; + .divider { + display: none; + } + } +` diff --git a/src/components/AppBar/Navbar.MobileMenu.tsx b/src/components/AppBar/Navbar.MobileMenu.tsx new file mode 100644 index 0000000..da2c7c2 --- /dev/null +++ b/src/components/AppBar/Navbar.MobileMenu.tsx @@ -0,0 +1,49 @@ +import styled from '@emotion/styled' +import { NavbarLinks } from '@/components/AppBar/Navbar.Links' +import { NavLinksItems } from '@/configs/data.configs' +import { uiConfigs } from '@/configs/ui.configs' +import { FooterOrgPanel } from '@/components/Footer/Footer.OrgPanel' +import { useThemeState } from '@/states/themeState' +import { ThemeSwitchWithLabel } from '@/components/ThemeSwitch/ThemeSwitch' + +interface Props {} + +export const NavbarMobileMenu = (props: Props) => { + const themeState = useThemeState() + return ( + + + + + + + + ) +} + +const NavbarMobileMenuContainer = styled.div` + position: fixed; + top: ${uiConfigs.navbarRenderedHeight - 1}px; + left: 0; + width: 100%; + height: calc(100vh - ${uiConfigs.navbarRenderedHeight - 2}px); + z-index: 100; + background: rgb(var(--lsd-surface-primary)); +` + +const InnerContainer = styled.div` + height: 100%; + width: calc(100% - 32px); + margin: auto; + + display: flex; + flex-direction: column; + + > * { + border-top: 1px solid rgb(var(--lsd-theme-primary)); + margin-top: 16px; + } +` diff --git a/src/components/Footer/Footer.BuPanel.tsx b/src/components/Footer/Footer.BuPanel.tsx new file mode 100644 index 0000000..934a3b4 --- /dev/null +++ b/src/components/Footer/Footer.BuPanel.tsx @@ -0,0 +1,151 @@ +import { Typography } from '@acid-info/lsd-react' +import styled from '@emotion/styled' +import { FooterLink } from '@/components/Footer/Footer.Link' +import { FooterSectionContainer } from '@/components/Footer/Footer.Section' + +const SECOND_LINK_GROUP = [ + { + title: 'Research', + links: [ + { label: 'VacP2P', href: 'https://vac.dev/' }, + { label: 'AFAIK', href: 'https://afaik.institute/' }, + ], + }, + { + title: 'Infrastructure', + links: [ + { label: 'Waku', href: 'https://waku.org/' }, + { label: 'Nimbus', href: 'https://nimbus.team/' }, + { label: 'Codex', href: 'https://codex.storage/' }, + { label: 'Nomos', href: 'https://nomos.tech/' }, + ], + }, + { + title: 'Creative Studio', + links: [{ label: 'Acid.info', href: 'https://acid.info/' }], + }, +] + +const THIRD_LINKS_GROUP = [ + { + title: 'Movement', + links: [{ label: 'Logos', href: 'https://logos.co/' }], + }, + { + title: 'User-facing Products', + links: [ + { label: 'Status', href: 'https://status.im/' }, + { label: 'Keycard', href: 'https://keycard.tech/' }, + ], + }, +] +export const FooterBuPanel = () => { + return ( + + + + {SECOND_LINK_GROUP.map(({ title, links }, idx) => ( + +
+ + {title}: + +
+ + {links.map(({ label, href }, idx) => ( + + {label} + + ))} + +
+ ))} +
+ + {THIRD_LINKS_GROUP.map(({ title, links }, idx) => ( + +
+ + {title}: + +
+ + {links.map(({ label, href }, idx) => ( + + {label} + + ))} + +
+ ))} +
+
+
+ ) +} + +const Row = styled.div` + display: flex; + gap: 8px; +` + +const Wrapper = styled.div` + display: flex; + align-items: baseline; + + /* temporary breakpoint */ + @media (max-width: 768px) { + flex-direction: column; + } +` + +const SECTION_MARGIN = 50 + +const BusinessUnits = styled(FooterSectionContainer)` + margin-top: ${SECTION_MARGIN}px; + padding: 16px 0 0 0; +` + +const SecondLinksContainer = styled.div` + flex: 2; +` + +const ThirdLinksContainer = styled.div` + flex: 1; + margin-bottom: ${SECTION_MARGIN}px; + + @media (max-width: 768px) { + margin-bottom: 80px; + } +` + +const LinkGroup = styled.div` + display: flex; + flex-direction: column; + margin-bottom: 34px; + gap: 4px; + + @media (max-width: 768px) { + margin-bottom: 24px; + } +` diff --git a/src/components/Footer/Footer.Link.tsx b/src/components/Footer/Footer.Link.tsx new file mode 100644 index 0000000..a88ba51 --- /dev/null +++ b/src/components/Footer/Footer.Link.tsx @@ -0,0 +1,14 @@ +import styled from '@emotion/styled' +import { Typography } from '@acid-info/lsd-react' + +export const FooterLink = styled(Typography)` + width: fit-content; + &:not(:last-child) { + &:after { + content: '•'; + margin-left: 8px; + text-decoration: none; + display: inline-block; + } + } +` diff --git a/src/components/Footer/Footer.OrgPanel.tsx b/src/components/Footer/Footer.OrgPanel.tsx new file mode 100644 index 0000000..a83cdfa --- /dev/null +++ b/src/components/Footer/Footer.OrgPanel.tsx @@ -0,0 +1,68 @@ +import { Typography } from '@acid-info/lsd-react' +import styled from '@emotion/styled' +import { FooterSection } from '@/components/Footer/Footer.Section' +import { FooterLink } from '@/components/Footer/Footer.Link' + +const FIRST_LINK_GRUOP = [ + { label: 'Twitter', href: 'https://twitter.com/Logos_State' }, + { label: 'Terms & Conditions', href: 'https://logos.co/terms/' }, + { label: 'Work with us', href: 'https://jobs.status.im/' }, +] +export const FooterOrgPanel = () => { + return ( + + + + Logos Press Engine ©{new Date().getFullYear()} + + + All rights reserved. + + + + {FIRST_LINK_GRUOP.map(({ label, href }, idx) => ( + + {label} + + ))} + + + ) +} + +const Wrapper = styled.div` + display: flex; + align-items: baseline; + + /* temporary breakpoint */ + @media (max-width: 768px) { + flex-direction: column; + } +` + +const OrgInfo = styled(FooterSection)` + @media (max-width: 768px) { + margin-bottom: 76px; + } +` + +const Links = styled(FooterSection)` + display: flex; + flex-direction: row; + align-items: center; + gap: 8px; +` diff --git a/src/components/Footer/Footer.Section.tsx b/src/components/Footer/Footer.Section.tsx new file mode 100644 index 0000000..07c0f78 --- /dev/null +++ b/src/components/Footer/Footer.Section.tsx @@ -0,0 +1,19 @@ +import styled from '@emotion/styled' +export const FooterSection = styled.div` + display: flex; + flex-direction: column; + flex-wrap: wrap; + width: 50%; + + @media (max-width: 768px) { + width: 100%; + } +` +export const FooterSectionContainer = styled.div` + display: flex; + position: relative; + flex-direction: column; + margin-top: 200px; + padding: 16px; + border-top: 1px solid rgb(var(--lsd-border-primary)); +` diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx index ba8fb49..c23e80f 100644 --- a/src/components/Footer/Footer.tsx +++ b/src/components/Footer/Footer.tsx @@ -1,48 +1,8 @@ import { Button, Typography } from '@acid-info/lsd-react' import styled from '@emotion/styled' - -const FIRST_LINK_GRUOP = [ - { label: 'Twitter', href: 'https://twitter.com/Logos_State' }, - { label: 'Terms & Conditions', href: 'https://logos.co/terms/' }, - { label: 'Work with us', href: 'https://jobs.status.im/' }, -] - -const SECOND_LINK_GROUP = [ - { - title: 'Research', - links: [ - { label: 'VacP2P', href: 'https://vac.dev/' }, - { label: 'AFAIK', href: 'https://afaik.institute/' }, - ], - }, - { - title: 'Infrastructure', - links: [ - { label: 'Waku', href: 'https://waku.org/' }, - { label: 'Nimbus', href: 'https://nimbus.team/' }, - { label: 'Codex', href: 'https://codex.storage/' }, - { label: 'Nomos', href: 'https://nomos.tech/' }, - ], - }, - { - title: 'Creative Studio', - links: [{ label: 'Acid.info', href: 'https://acid.info/' }], - }, -] - -const THIRD_LINKS_GROUP = [ - { - title: 'Movement', - links: [{ label: 'Logos', href: 'https://logos.co/' }], - }, - { - title: 'User-facing Products', - links: [ - { label: 'Status', href: 'https://status.im/' }, - { label: 'Keycard', href: 'https://keycard.tech/' }, - ], - }, -] +import { FooterOrgPanel } from '@/components/Footer/Footer.OrgPanel' +import { FooterSectionContainer } from '@/components/Footer/Footer.Section' +import { FooterBuPanel } from '@/components/Footer/Footer.BuPanel' export default function Footer() { const handleScrollToTop = () => { @@ -53,212 +13,16 @@ export default function Footer() { } return ( - - - - - Logos Press Engine ©{new Date().getFullYear()} - - - All rights reserved. - - - - {FIRST_LINK_GRUOP.map(({ label, href }, idx) => ( - - {label} - - ))} - - - - - - - Logos - - - Business Units: - - - - {SECOND_LINK_GROUP.map(({ title, links }, idx) => ( - -
- - {title}: - -
- - {links.map(({ label, href }, idx) => ( - - {label} - - ))} - -
- ))} -
- - {THIRD_LINKS_GROUP.map(({ title, links }, idx) => ( - -
- - {title}: - -
- - {links.map(({ label, href }, idx) => ( - - {label} - - ))} - -
- ))} -
-
-
+ + + Back to up ↑ -
+ ) } -const SECTION_MARGIN = 50 - -const Container = styled.div` - display: flex; - position: relative; - flex-direction: column; - margin-top: 200px; - padding: 16px; - border-top: 1px solid rgb(var(--lsd-border-primary)); -` - -const Section = styled.div` - display: flex; - flex-direction: column; - flex-wrap: wrap; - width: 50%; - - @media (max-width: 768px) { - width: 100%; - } -` - -const OrgInfo = styled(Section)` - @media (max-width: 768px) { - margin-bottom: 76px; - } -` - -const Links = styled(Section)` - display: flex; - flex-direction: row; - align-items: center; - gap: 8px; -` - -const Link = styled(Typography)` - width: fit-content; - &:not(:last-child) { - &:after { - content: '•'; - margin-left: 8px; - text-decoration: none; - display: inline-block; - } - } -` - -const Row = styled.div` - display: flex; - gap: 8px; -` - -const Wrapper = styled.div` - display: flex; - align-items: baseline; - - /* temporary breakpoint */ - @media (max-width: 768px) { - flex-direction: column; - } -` - -const BusinessUnits = styled(Container)` - margin-top: ${SECTION_MARGIN}px; - padding: 16px 0 0 0; -` - -const SecondLinksContainer = styled.div` - flex: 2; -` - -const ThirdLinksContainer = styled.div` - flex: 1; - margin-bottom: ${SECTION_MARGIN}px; - - @media (max-width: 768px) { - margin-bottom: 80px; - } -` - -const LinkGroup = styled.div` - display: flex; - flex-direction: column; - margin-bottom: 34px; - gap: 4px; - - @media (max-width: 768px) { - margin-bottom: 24px; - } -` - const ScrollToTop = styled(Button)` width: fit-content; position: absolute; diff --git a/src/components/Icons/CrossIcon/CrossIcon.tsx b/src/components/Icons/CrossIcon/CrossIcon.tsx new file mode 100644 index 0000000..fb9880e --- /dev/null +++ b/src/components/Icons/CrossIcon/CrossIcon.tsx @@ -0,0 +1,20 @@ +import { LsdIcon } from '@acid-info/lsd-react' + +export const CrossIcon = LsdIcon( + (props) => ( + + + + ), + { filled: true }, +) diff --git a/src/components/Icons/CrossIcon/index.ts b/src/components/Icons/CrossIcon/index.ts new file mode 100644 index 0000000..9941d14 --- /dev/null +++ b/src/components/Icons/CrossIcon/index.ts @@ -0,0 +1 @@ +export * from './CrossIcon' diff --git a/src/components/ThemeSwitch/ThemeSwitch.tsx b/src/components/ThemeSwitch/ThemeSwitch.tsx new file mode 100644 index 0000000..5e23b84 --- /dev/null +++ b/src/components/ThemeSwitch/ThemeSwitch.tsx @@ -0,0 +1,39 @@ +import { SunIcon } from '@/components/Icons/SunIcon' +import { MoonIcon } from '@/components/Icons/MoonIcon' +import { Button, IconButton } from '@acid-info/lsd-react' +import React from 'react' +import { ThemeState } from '@/states/themeState' +interface Props { + toggle: () => void + mode?: ThemeState['mode'] +} + +export const ThemeSwitch = ({ toggle, mode }: Props) => { + return ( + toggle()}> + {mode === 'light' ? ( + + ) : ( + + )} + + ) +} +export const ThemeSwitchWithLabel = ({ toggle, mode }: Props) => { + return ( + + ) +} diff --git a/src/configs/data.configs.ts b/src/configs/data.configs.ts index ff381a3..5ea3902 100644 --- a/src/configs/data.configs.ts +++ b/src/configs/data.configs.ts @@ -6,3 +6,9 @@ export const ArticleBlocksOrders = { mentions: 4, cover: 5, } + +export const NavLinksItems = [ + { label: 'Articles', href: '/search?postType=article' }, + { label: 'Podcasts', href: '/podcasts' }, + { label: 'About', href: '/about' }, +] diff --git a/src/containers/LSDThemeProvider/themes.ts b/src/containers/LSDThemeProvider/themes.ts index 3e57366..e050ea8 100644 --- a/src/containers/LSDThemeProvider/themes.ts +++ b/src/containers/LSDThemeProvider/themes.ts @@ -37,7 +37,17 @@ export const useLSDTheme = () => { const themes = useMemo(() => { const options: CreateThemeProps = { - breakpoints: {}, + breakpoints: { + sm: { + width: 768, + }, + md: { + width: 1024, + }, + lg: { + width: 1280, + }, + }, palette: {}, typography: {}, typographyGlobal: { diff --git a/src/layouts/DefaultLayout/Default.layout.tsx b/src/layouts/DefaultLayout/Default.layout.tsx index 42b2b35..86e3e6a 100644 --- a/src/layouts/DefaultLayout/Default.layout.tsx +++ b/src/layouts/DefaultLayout/Default.layout.tsx @@ -9,33 +9,11 @@ import { AppBar } from '../../components/AppBar' import { useThemeState } from '../../states/themeState' export default function DefaultLayout(props: PropsWithChildren) { - const themeState = useThemeState() - return ( <> - -
- - -
- -
+
{props.children}