Merge pull request #393 from omnivore-app/OMN-382

[Omn-382] - Updated landing page
This commit is contained in:
Jackson Harper 2022-04-19 11:15:31 -07:00 committed by GitHub
commit 48e36c8635
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 563 additions and 0 deletions

View file

@ -82,6 +82,7 @@ const RESERVED_NAMES = new Set([
'jobs',
'join',
'json',
'landing',
'language',
'languages',
'lists',

View file

@ -0,0 +1,25 @@
type CurvedUnderlineIconProps = {
size?: string
fillColor?: string
}
export function CurvedUnderlineIcon({
fillColor = '#FF9B3E',
size,
}: CurvedUnderlineIconProps): JSX.Element {
return (
<svg
width={size}
height={size}
viewBox="0 0 174 8"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1.4074 4.53965C0.600867 4.72886 0.100435 5.53608 0.28965 6.3426C0.478865 7.14913 1.28608 7.64957 2.0926 7.46035L1.4074 4.53965ZM171.907 7.46035C172.714 7.64957 173.521 7.14913 173.71 6.3426C173.9 5.53608 173.399 4.72886 172.593 4.53965L171.907 7.46035ZM161.594 3.5L161.251 4.96035L161.594 3.5ZM2.0926 7.46035L12.7489 4.96035L12.0636 2.03965L1.4074 4.53965L2.0926 7.46035ZM161.251 4.96035L171.907 7.46035L172.593 4.53965L161.936 2.03965L161.251 4.96035ZM140.624 4.96035C147.408 3.36887 154.467 3.36887 161.251 4.96035L161.936 2.03965C154.702 0.34244 147.173 0.342439 139.939 2.03965L140.624 4.96035ZM97.9989 4.96035C104.783 3.36887 111.842 3.36887 118.626 4.96035L119.311 2.03965C112.077 0.342439 104.548 0.342439 97.3136 2.03965L97.9989 4.96035ZM55.3739 4.96035C62.1575 3.36887 69.2175 3.36887 76.0011 4.96035L76.6864 2.03965C69.452 0.342439 61.923 0.342439 54.6886 2.03965L55.3739 4.96035ZM12.7489 4.96035C19.5325 3.36887 26.5925 3.36887 33.3761 4.96035L34.0614 2.03965C26.827 0.342439 19.298 0.342439 12.0636 2.03965L12.7489 4.96035ZM118.626 4.96035C125.861 6.65756 133.389 6.65756 140.624 4.96035L139.939 2.03965C133.155 3.63113 126.095 3.63113 119.311 2.03965L118.626 4.96035ZM33.3761 4.96035C40.6105 6.65756 48.1395 6.65756 55.3739 4.96035L54.6886 2.03965C47.905 3.63113 40.845 3.63113 34.0614 2.03965L33.3761 4.96035ZM76.0011 4.96035C83.2355 6.65756 90.7645 6.65756 97.9989 4.96035L97.3136 2.03965C90.53 3.63113 83.47 3.63113 76.6864 2.03965L76.0011 4.96035Z"
fill={fillColor}
/>
</svg>
)
}

View file

@ -0,0 +1,136 @@
import { OmnivoreNameLogo } from '../../elements/images/OmnivoreNameLogo';
import Link from 'next/link'
import Image from 'next/image'
import { Box, HStack } from '../../elements/LayoutPrimitives';
import { GithubLogo, DiscordLogo, TwitterLogo } from 'phosphor-react'
const containerStyles = {
padding: '5vw',
background: '#252525',
py: 60,
pb: 105,
width: '100%',
'@md': {
paddingLeft: '6vw',
},
'@xl': {
paddingLeft: '140px',
}
}
const titleStyles = {
maxWidth: 330,
fontWeight: 'normal',
fontSize: 18,
lineHeight: '27px',
color: '#FFFFFF',
mb: 45,
'@mdDown': {
fontSize: '3vw'
}
}
const socialsContainerStyles = {
maxWidth: 140,
marginBottom: 79
}
const copyrightStyles = {
maxWidth: 330,
fontWeight: 'normal',
fontSize: 18,
lineHeight: '27px',
color: '#5F5E58'
}
const sectionOne = {
width: '60%'
}
const sectionTwo = {
width: '40%',
pt: 10
}
const contactStyles = {
fontWeight: '700',
fontSize: 36,
lineHeight: '39px',
color: 'white',
'@mdDown': {
fontSize: 26,
}
}
const supportStyles = {
fontSize: 24,
lineHeight: '36px',
color: 'white',
'@mdDown': {
fontSize: '3vw'
}
}
const imageStyles = {
maxWidth: 190,
width: '100%',
}
const socialIconContainerStyles = {
maxWidth: 32,
maxHeight: 32,
}
export function LandingFooter(): JSX.Element {
return (
<HStack css={containerStyles}>
<Box css={sectionOne}>
<Box css={titleStyles}>Everything you read. Safe, organized, and easy to share.</Box>
<HStack distribution='between' css={socialsContainerStyles}>
<Box style={socialIconContainerStyles}>
<Link passHref href="https://twitter.com/OmnivoreApp">
<a>
<TwitterLogo width={32} height={32} color='white' />
</a>
</Link>
</Box>
<Box style={socialIconContainerStyles}>
<Link passHref href="https://github.com/omnivore-app/omnivore">
<a>
<GithubLogo width={32} height={32} color='white' />
</a>
</Link>
</Box>
<Box style={socialIconContainerStyles}>
<Link passHref href="https://discord.gg/h2z5rppzz9">
<a>
<DiscordLogo width={32} height={32} color='white' />
</a>
</Link>
</Box>
</HStack>
<Box css={copyrightStyles}>© 2022 Omnivore</Box>
</Box>
<Box css={sectionTwo}>
<Box css={{height: 215}}>
<Box style={{marginBottom: 5, ...imageStyles}}>
<a href="https://omnivore.app/install/ios" target="_blank" rel="noreferrer" style={{ display: 'inlineBlock', overflow: 'hidden' }}>
<img src="https://tools.applemediaservices.com/api/badges/download-on-the-app-store/black/en-us?size=90x37&amp;releaseDate=1628121600&h=2bbc629b0455dbea136257c9f518e4b3" alt="Download on the App Store" style={{ }} />
</a>
</Box>
{/* <Box style={imageStyles}>
<Link passHref href="#">
<a>
<Image src='/static/media/googlePlayBadge.png' alt='app-store' width={190} height={60} layout='intrinsic'/>
</a>
</Link>
</Box> */}
</Box>
<Box css={contactStyles}>
Contact
</Box>
<Box css={supportStyles}>
<a href="mailto:support@omnivore.app">support@omnivore.app</a>
</Box>
</Box>
</HStack>
)
}

View file

@ -0,0 +1,50 @@
import Link from 'next/link'
import { Box, SpanBox } from '../../elements/LayoutPrimitives'
import { OmnivoreNameLogo } from '../../elements/images/OmnivoreNameLogo'
const containerStyles = {
position: 'absolute',
top: 0,
left: 0,
p: '0px 15px 0px 15px',
height: '68px',
minHeight: '68px',
display: 'flex',
alignItems: 'center',
'@md': { width: '50%' },
'@xsDown': { height: '48px' },
justifyContent: 'space-between',
width: '100%',
}
const linkStyles = {
marginLeft: 'auto',
verticalAlign: 'middle',
cursor: 'pointer',
lineHeight: '100%',
}
const textStyles = {
pt: '5px',
pr: '6px',
fontSize: 24,
lineHeight: '24px',
fontWeight: 'normal'
}
export function LandingHeader(): JSX.Element {
return (
<Box css={containerStyles}>
<OmnivoreNameLogo color={'#3D3D3D'} href='/login' />
<Box css={linkStyles}>
<Box>
<Link passHref href="/login">
<a style={{textDecoration: 'none', color: '#3D3D3D', fontFamily: 'Inter', fontWeight: 500 }}>
<SpanBox css={textStyles}>Log in</SpanBox>
</a>
</Link>
</Box>
</Box>
</Box>
)
}

View file

@ -0,0 +1,90 @@
import { HStack, VStack, Box } from '../../elements/LayoutPrimitives'
import { CSS, styled } from '@stitches/react'
type LandingSectionProps = {
titleText: string,
descriptionText: string,
icon: React.ReactElement,
image: React.ReactElement,
containerStyles?: CSS,
}
const MainContainer = styled(HStack, {
width: '100%',
})
const titleTextStyles = {
fontWeight: '700',
color: '#3D3D3D',
lineHeight: '53px',
'@mdDown': {
fontSize: 24,
},
'@md': {
fontSize: '$5',
},
'@xl': {
fontSize: 45,
}
}
const descriptionTextStyles = {
color: 'rgb(125, 125, 125)',
}
const iconContainerStyles = {
width: 56,
height: 56,
background: 'white',
border: '1px solid rgba(61, 61, 61, 0.08)',
boxSizing: 'border-box',
borderRadius: '50%',
'@mdDown': {
width: 32,
height: 32,
padding: 5,
},
}
const imageContainerStyles = {
width: '50%',
'@mdDown': {
width: 0,
display: 'none',
}
}
const layoutStyles = {
width: '50%',
padding: 10,
'@mdDown': {
width: '100%',
}
}
const innerLayoutStyles = {
maxWidth: 480,
alignSelf: 'center',
'@mdDown': {
alignItems: 'center',
},
}
export function LandingSection(props: LandingSectionProps): JSX.Element {
return (
<MainContainer distribution='start' alignment='center' css={props.containerStyles}>
<VStack distribution='center' css={layoutStyles}>
<VStack css={innerLayoutStyles}>
<VStack distribution='center' alignment='center' css={iconContainerStyles}>
{props.icon}
</VStack>
<Box css={titleTextStyles}>{props.titleText}</Box>
<Box css={descriptionTextStyles}>{props.descriptionText}</Box>
</VStack>
</VStack>
<HStack distribution='center' css={imageContainerStyles}>
{props.image}
</HStack>
</MainContainer>
)
}

View file

@ -0,0 +1,210 @@
import Link from 'next/link'
import { VStack, Box, SpanBox } from '../../elements/LayoutPrimitives'
import { CurvedUnderlineIcon } from '../../elements/images/CurvedUnderlineIcon'
import { Button } from '../../elements/Button'
import { MagnifyingGlass, Palette, MegaphoneSimple, Binoculars, ArrowRight } from 'phosphor-react'
import { LandingSection } from './LandingSection'
const buttonStyles = {
display: 'flex',
borderRadius: 4,
px: 30,
background: 'rgb(255, 210, 52)',
color: '#3D3D3D'
}
const arrowStyles = {
marginLeft: 10,
padding: 2,
}
export function GetStartedButton(): JSX.Element {
return (
<Button style='ctaDarkYellow' css={buttonStyles}>
<Link passHref href='/login'>
<a style={{textDecoration: 'none', color: '#3D3D3D'}}>
Get Started
</a>
</Link>
<ArrowRight size={18} style={arrowStyles} color='white' fontWeight='700' />
</Button>
)
}
const containerStyles = {
px: '2vw',
pt: 100,
pb: 100,
width: '100%',
background: 'linear-gradient(0deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2)), linear-gradient(0deg, rgba(253, 250, 236, 0.7), rgba(253, 250, 236, 0.7))',
'@mdDown': {
pt: 50,
},
'@md': {
px: '6vw',
},
'@xl': {
px: '100px',
}
}
const titleStyles = {
fontWeight: '600',
fontSize: '24',
textAlign: 'center',
lineHeight: '36px',
color: '#FF9B3E',
'@mdDown': {
fontSize: 16,
letterSpacing: '0.02em'
}
}
const subTitleText = {
fontSize: 64,
maxWidth: 590,
fontWeight: '700',
textAlign: 'center',
lineHeight: '70px',
mb: 30,
'@mdDown': {
maxWidth: 295,
fontSize: 32,
lineHeight: '40px',
}
}
const reversedSectionStyles = {
flexDirection: 'row-reverse',
marginBottom: 20
}
const callToActionStyles = {
background: 'white',
borderRadius: '24px',
boxSizing: 'border-box',
border: '1px solid #D8D7D5',
boxShadow: '0px 7px 8px rgba(32, 31, 29, 0.03), 0px 18px 24px rgba(32, 31, 29, 0.03)',
padding: 40,
height: 330,
'@mdDown': {
display: 'none',
},
'@md': {
width: '100%',
},
'@xl': {
width: '95%',
},
}
const callToActionText = {
color: '#3D3D3D',
fontWeight: '700',
fontSize: 64,
lineHeight: '70px',
textAlign: 'center',
maxWidth: 500
}
const underlineIconStyles = {
height: '5px',
alignSelf: 'normal',
position: 'relative',
bottom: 20,
}
type LandingSectionsContainerProps = {
hideFirst?: boolean,
hideSecond?: boolean,
hideThird?: boolean,
hideFourth?: boolean,
}
export function LandingSectionsContainer({
hideFirst = false,
hideSecond = false,
hideThird = true,
hideFourth = true,
}: LandingSectionsContainerProps): JSX.Element {
const iconColor = 'rgb(255, 210, 52)'
return (
<VStack alignment='center' distribution='start' css={containerStyles}>
<VStack distribution='center'>
<Box css={titleStyles}>
This is Omnivore
</Box>
<SpanBox css={underlineIconStyles}>
<CurvedUnderlineIcon />
</SpanBox>
</VStack>
<Box css={subTitleText}>
Collect and share the best of the web
</Box>
{!hideFirst && (
<LandingSection
titleText='Simply reader-friendly'
descriptionText='With a single click using Omnivores extension or mobile app, save any link you come across on the Internet. Your links are saved forever, so you will never lose anything. We also strip out the unnecessary content to give you a reader-friendly view of your saved pages.'
image={
<img
srcSet="/static/landing/landing-1.png, /static/landing/landing-1@2x.png 2x"
alt='landing-1'
style={{height: '50vw', maxHeight: 560}}
/>
}
icon={<MagnifyingGlass size={32} color={iconColor} weight='duotone' />}
/>
)}
{!hideSecond && (
<LandingSection
titleText='Make it your own'
descriptionText='Curate your own personal collection of saved links and annotate these links with your thoughts. Omnivore lets you highlight any text you find inspiring and attach personal notes to these highlights.'
image={
<img
srcSet="/static/landing/landing-2.png, /static/landing/landing-2@2x.png 2x"
alt='landing-2'
style={{width: '100%', marginRight: 40}}
/>
}
icon={<Palette size={32} color={iconColor} weight='duotone' />}
containerStyles={reversedSectionStyles}
/>
)}
{!hideThird && (
<LandingSection
titleText='A better way to share'
descriptionText='With Omnivores highlight and notes feature, you can share specific snippets from a link with your friends. Our share feature is integrated with top social media sites so sharing with your friends is just one click away.'
image={
<img
srcSet="/static/landing/landing-3.png, /static/landing/landing-3@2x.png 2x"
alt='landing-3'
style={{height: '50vw', maxHeight: 560}}
/>
}
icon={<MegaphoneSimple size={32} color={iconColor} weight='duotone' />}
/>
)}
{!hideFourth && (
<LandingSection
titleText='Discover new content'
descriptionText='Follow friends and people you admire and see what they are reading. With our highlight and notes feature, you can read through the eyes of others and see what others have highlighted and commented.'
image={
<img
srcSet="/static/landing/landing-4.png, /static/landing/landing-4@2x.png 2x"
alt='landing-4'
style={{width: '100%', marginRight: 40}}
/>
}
icon={<Binoculars size={32} color={iconColor} weight='duotone' />}
containerStyles={reversedSectionStyles}
/>
)}
<VStack alignment='center' css={callToActionStyles}>
<Box css={callToActionText}>
Get started with Omnivore today
</Box>
<GetStartedButton />
</VStack>
</VStack>
)
}

View file

@ -0,0 +1,51 @@
import { VStack, Box } from './../components/elements/LayoutPrimitives'
import { LandingSectionsContainer, GetStartedButton } from '../components/templates/landing/LandingSectionsContainer'
import { LandingHeader } from '../components/templates/landing/LandingHeader'
import { LandingFooter } from '../components/templates/landing/LandingFooter'
const mobileContainerStyles = {
maxWidth: 430,
alignSelf: 'center',
px: 10,
display: 'none',
marginTop: 60,
'@mdDown': {
display: 'flex',
}
}
const headingStyles = {
fontWeight: '700',
fontSize: 42,
lineHeight: '46px',
mb: 16
}
const subHeadingStyles = {
fontWeight: '700',
fontSize: 24,
lineHeight: '36px',
color: '#5F5E58',
mb: 32,
}
export default function LandingPage(): JSX.Element {
return (
<>
<LandingHeader />
<VStack css={{ background: '#FEFCF5', color: '#3D3D3D' }}>
<VStack css={mobileContainerStyles}>
<Box css={headingStyles}>Collect and share the best of the web</Box>
<Box css={subHeadingStyles}>
Everything you read. Safe, organized, and easy to share.
</Box>
<Box css={{mb: 40}}>
<GetStartedButton />
</Box>
</VStack>
<LandingSectionsContainer />
</VStack>
<LandingFooter />
</>
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB