4030 website header for tablet (#4274)

* add use device types

* add header file

* remove use device type

* add tablet view styles

* remove eslint comment

* create shared folder and add header.ts file for all styled elements which used in app header

* refactor header files structure

* Hide linklist on mobile

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
Ahmad 2024-03-05 13:37:09 +03:30 committed by GitHub
parent 9035762d43
commit 0a2d8056bd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 186 additions and 219 deletions

View File

@ -1,123 +0,0 @@
'use client';
import React from 'react';
import styled from '@emotion/styled';
import { ExternalArrow } from '@/app/_components/ui/icons/SvgIcons';
import { GithubIcon } from '../icons/SvgIcons';
import { Logo } from './Logo';
const Nav = styled.nav`
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
overflow: visible;
padding: 12px 16px 12px 16px;
position: relative;
transform-origin: 50% 50% 0px;
border-bottom: 1px solid rgba(20, 20, 20, 0.08);
@media (max-width: 809px) {
display: none;
}
`;
const LinkList = styled.div`
display: flex;
flex-direction: row;
gap: 2px;
`;
const ListItem = styled.a`
color: rgb(71, 71, 71);
text-decoration: none;
display: flex;
gap: 4px;
align-items: center;
border-radius: 8px;
height: 40px;
padding-left: 16px;
padding-right: 16px;
&:hover {
background-color: #f1f1f1;
}
`;
const LogoContainer = styled.div`
display: flex;
align-items: center;
gap: 8px;
width: 202px;
`;
const StyledButton = styled.div`
display: flex;
height: 40px;
padding-left: 16px;
padding-right: 16px;
align-items: center;
background-color: #000;
color: #fff;
border-radius: 8px;
font-weight: 500;
border: none;
outline: inherit;
cursor: pointer;
`;
const CallToActionContainer = styled.div`
display: flex;
align-items: center;
gap: 8px;
a {
text-decoration: none;
}
`;
const LinkNextToCTA = styled.a`
display: flex;
align-items: center;
color: rgb(71, 71, 71);
padding: 0px 16px 0px 16px;
span {
text-decoration: underline;
}
`;
const CallToAction = () => {
return (
<CallToActionContainer>
<LinkNextToCTA href="https://github.com/twentyhq/twenty">
Sign in
</LinkNextToCTA>
<a href="https://twenty.com/stripe-redirection">
<StyledButton>Get Started</StyledButton>
</a>
</CallToActionContainer>
);
};
export const HeaderDesktop = () => {
return (
<Nav>
<LogoContainer>
<Logo />
</LogoContainer>
<LinkList>
<ListItem href="/pricing">Pricing</ListItem>
<ListItem href="/story">Story</ListItem>
<ListItem href="https://docs.twenty.com">
Docs <ExternalArrow />
</ListItem>
<ListItem href="https://github.com/twentyhq/twenty">
<GithubIcon color="rgb(71,71,71)" /> 8.3k <ExternalArrow />
</ListItem>
</LinkList>
<CallToAction />
</Nav>
);
};

View File

@ -0,0 +1,34 @@
'use client';
import React from 'react';
import { ExternalArrow, GithubIcon } from '@/app/_components/ui/icons/SvgIcons';
import { CallToAction } from '@/app/_components/ui/layout/header/callToAction';
import {
DesktopNav,
LinkList,
ListItem,
LogoContainer,
} from '@/app/_components/ui/layout/header/styled';
import { Logo } from '@/app/_components/ui/layout/Logo';
export const HeaderDesktop = () => {
return (
<DesktopNav>
<LogoContainer>
<Logo />
</LogoContainer>
<LinkList>
<ListItem href="/story">Story</ListItem>
<ListItem href="/pricing">Pricing</ListItem>
<ListItem href="https://docs.twenty.com">
Docs <ExternalArrow />
</ListItem>
<ListItem href="https://github.com/twentyhq/twenty">
<GithubIcon color="rgb(71,71,71)" /> 8.3k <ExternalArrow />
</ListItem>
</LinkList>
<CallToAction />
</DesktopNav>
);
};

View File

@ -0,0 +1,73 @@
'use client';
import { useState } from 'react';
import { IBM_Plex_Mono } from 'next/font/google';
import { ExternalArrow, GithubIcon } from '@/app/_components/ui/icons/SvgIcons';
import { CallToAction } from '@/app/_components/ui/layout/header/callToAction';
import {
HamburgerContainer,
HamburgerLine1,
HamburgerLine2,
ListItem,
LogoAddon,
LogoContainer,
MobileLinkList,
MobileMenu,
MobileNav,
NavOpen,
} from '@/app/_components/ui/layout/header/styled';
import { Logo } from '@/app/_components/ui/layout/Logo';
const IBMPlexMono = IBM_Plex_Mono({
weight: '500',
subsets: ['latin'],
display: 'swap',
});
export const HeaderMobile = () => {
const isTwentyDev = false;
const [menuOpen, setMenuOpen] = useState(false);
const toggleMenu = () => {
setMenuOpen(!menuOpen);
};
return (
<MobileMenu>
<MobileNav>
<LogoContainer>
<Logo />
{isTwentyDev && (
<LogoAddon className={IBMPlexMono.className}>
for Developers
</LogoAddon>
)}
</LogoContainer>
<HamburgerContainer>
<input type="checkbox" id="menu-input" onChange={toggleMenu} />
<HamburgerLine1 id="line1" />
<HamburgerLine2 id="line2" />
</HamburgerContainer>
</MobileNav>
<NavOpen
style={{
transform: `scaleY(${menuOpen ? '1' : '0'})`,
}}
>
<MobileLinkList>
<ListItem href="/story">Story</ListItem>
<ListItem href="/pricing">Pricing</ListItem>
<ListItem href="https://docs.twenty.com">
Docs <ExternalArrow />
</ListItem>
<ListItem href="https://github.com/twentyhq/twenty">
<GithubIcon color="rgb(71,71,71)" /> 8.3k <ExternalArrow />
</ListItem>
</MobileLinkList>
<CallToAction />
</NavOpen>
</MobileMenu>
);
};

View File

@ -0,0 +1,18 @@
import {
CallToActionContainer,
LinkNextToCTA,
StyledButton,
} from '@/app/_components/ui/layout/header/styled';
export const CallToAction = () => {
return (
<CallToActionContainer>
<LinkNextToCTA href="https://github.com/twentyhq/twenty">
Sign in
</LinkNextToCTA>
<a href="https://twenty.com/stripe-redirection">
<StyledButton>Get Started</StyledButton>
</a>
</CallToActionContainer>
);
};

View File

@ -0,0 +1,13 @@
'use client';
import { HeaderDesktop } from '@/app/_components/ui/layout/header/HeaderDesktop';
import { HeaderMobile } from '@/app/_components/ui/layout/header/HeaderMobile';
export const AppHeader = () => {
return (
<>
<HeaderDesktop />
<HeaderMobile />
</>
);
};

View File

@ -1,22 +1,27 @@
'use client'; 'use client';
import { useState } from 'react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { IBM_Plex_Mono } from 'next/font/google';
import { ExternalArrow } from '@/app/_components/ui/icons/SvgIcons'; import mq from '@/app/_components/ui/theme/mq';
import { GithubIcon } from '../icons/SvgIcons'; export const DesktopNav = styled.nav`
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
overflow: visible;
padding: 12px 16px 12px 16px;
position: relative;
transform-origin: 50% 50% 0px;
border-bottom: 1px solid rgba(20, 20, 20, 0.08);
import { Logo } from './Logo'; @media (max-width: 809px) {
display: none;
}
`;
const IBMPlexMono = IBM_Plex_Mono({ export const MobileNav = styled.nav`
weight: '500',
subsets: ['latin'],
display: 'swap',
});
const Nav = styled.nav`
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
@ -28,26 +33,32 @@ const Nav = styled.nav`
border-bottom: 1px solid rgba(20, 20, 20, 0.08); border-bottom: 1px solid rgba(20, 20, 20, 0.08);
height: 64px; height: 64px;
width: 100%; width: 100%;
@media (min-width: 810px) {
display: none;
}
`; `;
const LinkList = styled.div` export const LinkList = styled.div`
display: flex;
flex-direction: row;
gap: 2px;
${mq({
marginRight: ['auto', 'auto', '0'],
})}
`;
export const MobileLinkList = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 16px; gap: 16px;
align-items: center; align-items: center;
`; `;
const ListItem = styled.a` export const ListItem = styled.a`
color: rgb(71, 71, 71); color: rgb(71, 71, 71);
text-decoration: none; text-decoration: none;
display: flex; display: flex;
gap: 4px; gap: 4px;
align-items: center; align-items: center;
border-radius: 8px; border-radius: 8px;
height: 48px; height: 40px;
padding-left: 16px; padding-left: 16px;
padding-right: 16px; padding-right: 16px;
&:hover { &:hover {
@ -55,21 +66,23 @@ const ListItem = styled.a`
} }
`; `;
const LogoContainer = styled.div` export const LogoContainer = styled.div`
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
width: 202px; ${mq({
width: ['auto', 'auto', '202px'],
})}
`; `;
const LogoAddon = styled.div` export const LogoAddon = styled.div`
font-size: 12px; font-size: 12px;
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
line-height: 150%; line-height: 150%;
`; `;
const StyledButton = styled.div` export const StyledButton = styled.div`
display: flex; display: flex;
height: 40px; height: 40px;
padding-left: 16px; padding-left: 16px;
@ -84,7 +97,7 @@ const StyledButton = styled.div`
cursor: pointer; cursor: pointer;
`; `;
const CallToActionContainer = styled.div` export const CallToActionContainer = styled.div`
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
@ -93,7 +106,7 @@ const CallToActionContainer = styled.div`
} }
`; `;
const LinkNextToCTA = styled.a` export const LinkNextToCTA = styled.a`
display: flex; display: flex;
align-items: center; align-items: center;
color: rgb(71, 71, 71); color: rgb(71, 71, 71);
@ -103,20 +116,7 @@ const LinkNextToCTA = styled.a`
} }
`; `;
const CallToAction = () => { export const HamburgerContainer = styled.div`
return (
<CallToActionContainer>
<LinkNextToCTA href="https://github.com/twentyhq/twenty">
Sign in
</LinkNextToCTA>
<a href="#">
<StyledButton>Get Started</StyledButton>
</a>
</CallToActionContainer>
);
};
const HamburgerContainer = styled.div`
height: 44px; height: 44px;
width: 44px; width: 44px;
cursor: pointer; cursor: pointer;
@ -146,7 +146,7 @@ const HamburgerContainer = styled.div`
} }
`; `;
const HamburgerLine1 = styled.div` export const HamburgerLine1 = styled.div`
height: 2px; height: 2px;
left: calc(50.00000000000002% - 20px / 2); left: calc(50.00000000000002% - 20px / 2);
position: absolute; position: absolute;
@ -156,7 +156,7 @@ const HamburgerLine1 = styled.div`
background-color: rgb(179, 179, 179); background-color: rgb(179, 179, 179);
`; `;
const HamburgerLine2 = styled.div` export const HamburgerLine2 = styled.div`
height: 2px; height: 2px;
left: calc(50.00000000000002% - 20px / 2); left: calc(50.00000000000002% - 20px / 2);
position: absolute; position: absolute;
@ -166,7 +166,7 @@ const HamburgerLine2 = styled.div`
background-color: rgb(179, 179, 179); background-color: rgb(179, 179, 179);
`; `;
const NavOpen = styled.div` export const NavOpen = styled.div`
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
position: fixed; position: fixed;
@ -181,55 +181,11 @@ const NavOpen = styled.div`
transform-origin: top; transform-origin: top;
`; `;
const MobileMenu = styled.div` export const MobileMenu = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 100%; width: 100%;
@media (min-width: 810px) {
display: none;
}
`; `;
export const HeaderMobile = () => {
const isTwentyDev = false;
const [menuOpen, setMenuOpen] = useState(false);
const toggleMenu = () => {
setMenuOpen(!menuOpen);
};
return (
<MobileMenu>
<Nav>
<LogoContainer>
<Logo />
{isTwentyDev && (
<LogoAddon className={IBMPlexMono.className}>
for Developers
</LogoAddon>
)}
</LogoContainer>
<HamburgerContainer>
<input type="checkbox" id="menu-input" onChange={toggleMenu} />
<HamburgerLine1 id="line1" />
<HamburgerLine2 id="line2" />
</HamburgerContainer>
</Nav>
<NavOpen
style={{
transform: `scaleY(${menuOpen ? '1' : '0'})`,
}}
>
<LinkList>
<ListItem href="/story">Story</ListItem>
<ListItem href="/pricing">Pricing</ListItem>
<ListItem href="https://docs.twenty.com">
Docs <ExternalArrow />
</ListItem>
<ListItem href="https://github.com/twentyhq/twenty">
<GithubIcon color="rgb(71,71,71)" /> 8.3k <ExternalArrow />
</ListItem>
</LinkList>
<CallToAction />
</NavOpen>
</MobileMenu>
);
};

View File

@ -1,10 +1,9 @@
import { Metadata } from 'next'; import { Metadata } from 'next';
import { Gabarito, Inter } from 'next/font/google'; import { Gabarito, Inter } from 'next/font/google';
import { HeaderMobile } from '@/app/_components/ui/layout/HeaderMobile'; import { AppHeader } from '@/app/_components/ui/layout/header';
import { FooterDesktop } from './_components/ui/layout/FooterDesktop'; import { FooterDesktop } from './_components/ui/layout/FooterDesktop';
import { HeaderDesktop } from './_components/ui/layout/HeaderDesktop';
import EmotionRootStyleRegistry from './emotion-root-style-registry'; import EmotionRootStyleRegistry from './emotion-root-style-registry';
import './layout.css'; import './layout.css';
@ -40,11 +39,8 @@ export default function RootLayout({
<html lang="en" className={`${gabarito.variable} ${inter.variable}`}> <html lang="en" className={`${gabarito.variable} ${inter.variable}`}>
<body> <body>
<EmotionRootStyleRegistry> <EmotionRootStyleRegistry>
<HeaderDesktop /> <AppHeader />
<div className="container"> <div className="container">{children}</div>
<HeaderMobile />
{children}
</div>
<FooterDesktop /> <FooterDesktop />
</EmotionRootStyleRegistry> </EmotionRootStyleRegistry>
</body> </body>