Improved homepage 🙏
This commit is contained in:
parent
95c4574549
commit
19a328ebeb
Binary file not shown.
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 253 KiB |
Binary file not shown.
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 400 KiB |
|
@ -6,12 +6,12 @@ import Grid from 'styled-components-grid';
|
||||||
import breakpoint from 'styled-components-breakpoint';
|
import breakpoint from 'styled-components-breakpoint';
|
||||||
import Notice from '../../shared/components/Notice';
|
import Notice from '../../shared/components/Notice';
|
||||||
import Hero from './components/Hero';
|
import Hero from './components/Hero';
|
||||||
|
import Centered from './components/Centered';
|
||||||
import SigninButtons from './components/SigninButtons';
|
import SigninButtons from './components/SigninButtons';
|
||||||
import {
|
import SlackLogo from '../../shared/components/SlackLogo';
|
||||||
developers,
|
import GithubLogo from '../../shared/components/GithubLogo';
|
||||||
githubUrl,
|
import Flex from '../../shared/components/Flex';
|
||||||
slackAppStoreUrl,
|
import { githubUrl, slackAppStoreUrl } from '../../shared/utils/routeHelpers';
|
||||||
} from '../../shared/utils/routeHelpers';
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
notice?: 'google-hd' | 'auth-error' | 'hd-not-allowed',
|
notice?: 'google-hd' | 'auth-error' | 'hd-not-allowed',
|
||||||
|
@ -55,77 +55,107 @@ function Home(props: Props) {
|
||||||
</Notice>
|
</Notice>
|
||||||
)}
|
)}
|
||||||
</Hero>
|
</Hero>
|
||||||
<Features reverse={{ mobile: true, tablet: false, desktop: false }}>
|
<Mask>
|
||||||
<Grid.Unit size={{ desktop: 1 / 3, tablet: 1 / 2 }}>
|
<Features>
|
||||||
<Feature>
|
<Centered>
|
||||||
<h2>Blazing Fast Wiki</h2>
|
<Grid reverse={{ mobile: true, tablet: false, desktop: false }}>
|
||||||
|
<Grid.Unit size={{ tablet: 1 / 3 }}>
|
||||||
|
<Feature>
|
||||||
|
<h2>Improve Communication</h2>
|
||||||
|
<p>
|
||||||
|
Easily structure your teams information in one central,
|
||||||
|
structured location. No more hunting through folders or
|
||||||
|
scanning pages of search results and chat conversations.
|
||||||
|
</p>
|
||||||
|
</Feature>
|
||||||
|
<Feature>
|
||||||
|
<h2>Safe & Secure</h2>
|
||||||
|
<p>
|
||||||
|
Outline provides a secure place for your teams
|
||||||
|
documentation on our hosted platform, stored in portable
|
||||||
|
Markdown format. Or, you can run your own copy – it's open
|
||||||
|
source!
|
||||||
|
</p>
|
||||||
|
</Feature>
|
||||||
|
</Grid.Unit>
|
||||||
|
<Feature size={{ tablet: 2 / 3 }}>
|
||||||
|
<Screenshot
|
||||||
|
srcset="screenshot.png, screenshot@2x.png 2x"
|
||||||
|
src="/screenshot@2x.png"
|
||||||
|
alt="Outline Screenshot"
|
||||||
|
/>
|
||||||
|
</Feature>
|
||||||
|
</Grid>
|
||||||
|
</Centered>
|
||||||
|
</Features>
|
||||||
|
</Mask>
|
||||||
|
<Centered>
|
||||||
|
<Grid>
|
||||||
|
<Feature size={{ desktop: 1 / 3 }}>
|
||||||
|
<h2>Blazing Fast</h2>
|
||||||
<p>
|
<p>
|
||||||
Outline is fast, really fast. We’ve worked hard to ensure
|
Outline is fast, really fast. We’ve worked hard to ensure
|
||||||
millisecond response times, documents load instantly, search is
|
millisecond response times – documents load instantly, search is
|
||||||
speedy and navigating the UI is delightful.
|
speedy and navigating the UI is delightful.
|
||||||
</p>
|
</p>
|
||||||
</Feature>
|
</Feature>
|
||||||
<Feature>
|
<Feature size={{ desktop: 1 / 3 }} />
|
||||||
<h2># Markdown Support</h2>
|
<Feature size={{ desktop: 1 / 3 }}>
|
||||||
|
<h2>Markdown Support</h2>
|
||||||
<p>
|
<p>
|
||||||
Documents are stored in plain Markdown making editing, import
|
Documents are stored in plain Markdown making editing, import
|
||||||
and export painless. Shortcuts are also built right into the
|
and export painless. Shortcuts are also built right into the
|
||||||
editor so you can easily format using{' '}
|
editor so you can easily format using **markdown syntax** if you
|
||||||
<strong>**markdown syntax**</strong> if you like.
|
like.
|
||||||
</p>
|
</p>
|
||||||
</Feature>
|
</Feature>
|
||||||
</Grid.Unit>
|
<Feature size={{ desktop: 1 / 3 }}>
|
||||||
<Feature size={{ desktop: 2 / 3, tablet: 1 / 2 }}>
|
<h2>
|
||||||
<Screenshot
|
<SlackLogo fill="#000" size={30} /> Slack & API
|
||||||
srcset="screenshot.png, screenshot@2x.png 2x"
|
</h2>
|
||||||
src="/screenshot@2x.png"
|
<p>
|
||||||
alt="Outline Screenshot"
|
Get Slack notifications about changes and search Outline
|
||||||
/>
|
directly within Slack using the{' '}
|
||||||
</Feature>
|
<code>/outline <keyword></code> command. Access your
|
||||||
</Features>
|
information programatically through the modern API.
|
||||||
<Highlights id="features">
|
</p>
|
||||||
<Feature size={{ desktop: 1 / 3 }}>
|
<p>
|
||||||
<h2>Slack Integration</h2>
|
<a href={slackAppStoreUrl()}>Slack App</a>
|
||||||
<p>
|
</p>
|
||||||
Get Slack notifications about newly updated documents. You can
|
</Feature>
|
||||||
also search Outline directly within Slack using{' '}
|
<Feature size={{ desktop: 1 / 3 }} />
|
||||||
<code>/outline <keyword></code> command.
|
<Feature size={{ desktop: 1 / 3 }}>
|
||||||
</p>
|
<h2>
|
||||||
<p>
|
<GithubLogo fill="#000" size={30} /> Open Source
|
||||||
<a href={slackAppStoreUrl()}>Slack App</a>
|
</h2>
|
||||||
</p>
|
<p>
|
||||||
</Feature>
|
Outline is open source, so the community can help improve it
|
||||||
<Feature size={{ desktop: 1 / 3 }}>
|
too. You get new features, interface improvements, bug fixes,
|
||||||
<h2>Open Source</h2>
|
and a transparent roadmap for free.
|
||||||
<p>
|
</p>
|
||||||
Outline is open source, so the community can help improve it too.
|
<p>
|
||||||
You get new features, interface improvements, bug fixes, and a
|
<a href={githubUrl()}>GitHub</a>
|
||||||
transparent roadmap for free.
|
</p>
|
||||||
</p>
|
</Feature>
|
||||||
<p>
|
</Grid>
|
||||||
<a href={githubUrl()}>GitHub</a>
|
</Centered>
|
||||||
</p>
|
|
||||||
</Feature>
|
|
||||||
<Feature size={{ desktop: 1 / 3 }}>
|
|
||||||
<h2>Integrations & API</h2>
|
|
||||||
<p>
|
|
||||||
All of Outline’s functionality is available through the API.
|
|
||||||
Migrating Markdown documents or setting up automations is a breeze
|
|
||||||
with a few lines of code.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a href={developers()}>Documentation</a>
|
|
||||||
</p>
|
|
||||||
</Feature>
|
|
||||||
</Highlights>
|
|
||||||
<Footer>
|
<Footer>
|
||||||
<h2>Create an account</h2>
|
<Centered>
|
||||||
<p>
|
<Grid>
|
||||||
On the same page as us? Create a free account to give Outline a try.
|
<Grid.Unit size={{ desktop: 1 / 3 }}>
|
||||||
</p>
|
<h2>Create an account</h2>
|
||||||
<FooterCTA>
|
<p>
|
||||||
<SigninButtons {...props} />
|
On the same page as us? Create a free account to give Outline
|
||||||
</FooterCTA>
|
a try with your team.
|
||||||
|
</p>
|
||||||
|
</Grid.Unit>
|
||||||
|
<Grid.Unit size={{ desktop: 2 / 3 }}>
|
||||||
|
<Flex justify="center" align="center">
|
||||||
|
<SigninButtons {...props} />
|
||||||
|
</Flex>
|
||||||
|
</Grid.Unit>
|
||||||
|
</Grid>
|
||||||
|
</Centered>
|
||||||
</Footer>
|
</Footer>
|
||||||
</Grid>
|
</Grid>
|
||||||
</span>
|
</span>
|
||||||
|
@ -139,25 +169,36 @@ const Screenshot = styled.img`
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
|
||||||
${breakpoint('desktop')`
|
${breakpoint('desktop')`
|
||||||
width: 150%;
|
margin-top: -120px;
|
||||||
|
margin-left: 120px;
|
||||||
|
width: 135%;
|
||||||
`};
|
`};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Highlights = styled(Grid)`
|
const Mask = styled.div`
|
||||||
background: ${props => props.theme.primary};
|
width: 100%;
|
||||||
margin: 0 1em;
|
overflow: hidden;
|
||||||
padding: 0 1em;
|
padding: 8em 0;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Features = styled(Grid)`
|
const Features = styled.div`
|
||||||
|
background: hsl(180, 58%, 85%);
|
||||||
padding: 0 2em;
|
padding: 0 2em;
|
||||||
overflow: hidden;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Feature = styled(Grid.Unit)`
|
const Feature = styled(Grid.Unit)`
|
||||||
padding: 3em 0;
|
padding: 2em 0;
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-weight: 500;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
|
display: flex;
|
||||||
|
font-size: 1.8em;
|
||||||
|
align-items: center;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,29 +211,33 @@ const Feature = styled(Grid.Unit)`
|
||||||
}
|
}
|
||||||
|
|
||||||
${breakpoint('tablet')`
|
${breakpoint('tablet')`
|
||||||
padding: 4em 3em;
|
padding: 4em 0;
|
||||||
`};
|
`};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Footer = styled.div`
|
const Footer = styled.div`
|
||||||
text-align: center;
|
background: hsl(127, 58%, 85%);
|
||||||
|
text-align: left;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 4em 2em;
|
padding: 4em 2em;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.8em;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
${breakpoint('tablet')`
|
${breakpoint('tablet')`
|
||||||
|
margin: 2em 0;
|
||||||
padding: 6em 4em;
|
padding: 6em 4em;
|
||||||
`};
|
`};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const FooterCTA = styled.p`
|
|
||||||
padding-top: 1em;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const HeroText = styled.p`
|
const HeroText = styled.p`
|
||||||
font-size: 18px;
|
font-size: 22px;
|
||||||
|
color: #666;
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: left;
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
margin-bottom: 2em;
|
margin-bottom: 2em;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
// @flow
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const Centered = styled.div`
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 1000px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Centered;
|
|
@ -1,16 +1,15 @@
|
||||||
// @flow
|
// @flow
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import Centered from './Centered';
|
||||||
|
|
||||||
const Hero = styled.div`
|
const Hero = styled(Centered)`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 70vh;
|
min-height: 500px;
|
||||||
min-height: 400px;
|
padding: 4em 0 0;
|
||||||
max-height: 600px;
|
|
||||||
padding: 6em 2em 0;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 2.5em;
|
font-size: 3.5em;
|
||||||
|
line-height: 1em;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Helmet } from 'react-helmet';
|
import { Helmet } from 'react-helmet';
|
||||||
|
import styled from 'styled-components';
|
||||||
import { TopNavigation, BottomNavigation } from './Navigation';
|
import { TopNavigation, BottomNavigation } from './Navigation';
|
||||||
import Analytics from '../../../shared/components/Analytics';
|
import Analytics from '../../../shared/components/Analytics';
|
||||||
import globalStyles from '../../../shared/styles/globals';
|
import globalStyles from '../../../shared/styles/globals';
|
||||||
|
@ -15,7 +16,7 @@ type Props = {
|
||||||
children?: React.Node,
|
children?: React.Node,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Layout({ children }: Props) {
|
function Layout({ children }: Props) {
|
||||||
globalStyles();
|
globalStyles();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -63,11 +64,17 @@ export default function Layout({ children }: Props) {
|
||||||
{'{{HEAD}}'}
|
{'{{HEAD}}'}
|
||||||
{'{{CSS}}'}
|
{'{{CSS}}'}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<Body>
|
||||||
<TopNavigation />
|
<TopNavigation />
|
||||||
{children}
|
{children}
|
||||||
<BottomNavigation />
|
<BottomNavigation />
|
||||||
</body>
|
</Body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Body = styled.body`
|
||||||
|
padding: 0 30px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Layout;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import breakpoint from 'styled-components-breakpoint';
|
import breakpoint from 'styled-components-breakpoint';
|
||||||
|
import Centered from './Centered';
|
||||||
import {
|
import {
|
||||||
developers,
|
developers,
|
||||||
changelog,
|
changelog,
|
||||||
|
@ -102,9 +103,9 @@ const MenuItemDesktop = styled(MenuItem)`
|
||||||
`};
|
`};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Nav = styled.nav`
|
const Nav = styled(Centered)`
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 20px 30px;
|
padding: 20px 0;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
`;
|
`;
|
||||||
|
@ -114,7 +115,7 @@ const BottomNav = styled.nav`
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin-bottom: 40px;
|
margin: 4em 0;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -124,6 +125,7 @@ const BottomNav = styled.nav`
|
||||||
|
|
||||||
${breakpoint('tablet')`
|
${breakpoint('tablet')`
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
margin: 0 0 4em;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
margin: 0 0 0 40px;
|
margin: 0 0 0 40px;
|
||||||
|
|
|
@ -21,7 +21,7 @@ const SigninButtons = ({
|
||||||
return (
|
return (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
{slackSigninEnabled && (
|
{slackSigninEnabled && (
|
||||||
<Flex column>
|
<Column column>
|
||||||
<Button href={signin('slack')}>
|
<Button href={signin('slack')}>
|
||||||
<SlackLogo />
|
<SlackLogo />
|
||||||
<Spacer>Sign In with Slack</Spacer>
|
<Spacer>Sign In with Slack</Spacer>
|
||||||
|
@ -29,11 +29,10 @@ const SigninButtons = ({
|
||||||
<LastLogin>
|
<LastLogin>
|
||||||
{lastSignedIn === 'slack' && 'You signed in with Slack previously'}
|
{lastSignedIn === 'slack' && 'You signed in with Slack previously'}
|
||||||
</LastLogin>
|
</LastLogin>
|
||||||
</Flex>
|
</Column>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{googleSigninEnabled && (
|
{googleSigninEnabled && (
|
||||||
<Flex column>
|
<Column column>
|
||||||
<Button href={signin('google')}>
|
<Button href={signin('google')}>
|
||||||
<GoogleLogo />
|
<GoogleLogo />
|
||||||
<Spacer>Sign In with Google</Spacer>
|
<Spacer>Sign In with Google</Spacer>
|
||||||
|
@ -42,19 +41,28 @@ const SigninButtons = ({
|
||||||
{lastSignedIn === 'google' &&
|
{lastSignedIn === 'google' &&
|
||||||
'You signed in with Google previously'}
|
'You signed in with Google previously'}
|
||||||
</LastLogin>
|
</LastLogin>
|
||||||
</Flex>
|
</Column>
|
||||||
)}
|
)}
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Column = styled(Flex)`
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const Wrapper = styled(Flex)`
|
const Wrapper = styled(Flex)`
|
||||||
display: block;
|
display: block;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
${breakpoint('tablet')`
|
${breakpoint('tablet')`
|
||||||
display: flex;
|
display: flex;
|
||||||
`};
|
justify-content: flex-start;
|
||||||
|
`};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Spacer = styled.span`
|
const Spacer = styled.span`
|
||||||
|
@ -73,8 +81,9 @@ const Button = styled.a`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const LastLogin = styled.p`
|
const LastLogin = styled.p`
|
||||||
font-size: 12px;
|
font-size: 13px;
|
||||||
color: ${props => props.theme.slate};
|
font-weight: 500;
|
||||||
|
color: rgba(20, 23, 26, 0.5);
|
||||||
padding-top: 4px;
|
padding-top: 4px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,11 @@ import webpackConfig from '../../webpack.config';
|
||||||
const PUBLIC_PATH = webpackConfig.output.publicPath;
|
const PUBLIC_PATH = webpackConfig.output.publicPath;
|
||||||
|
|
||||||
const prefetchTags = [
|
const prefetchTags = [
|
||||||
<link rel="dns-prefetch" href={process.env.AWS_S3_UPLOAD_BUCKET_URL} />,
|
<link
|
||||||
|
rel="dns-prefetch"
|
||||||
|
href={process.env.AWS_S3_UPLOAD_BUCKET_URL}
|
||||||
|
key="dns"
|
||||||
|
/>,
|
||||||
];
|
];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
// @flow
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
size?: number,
|
||||||
|
fill?: string,
|
||||||
|
className?: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
function GithubLogo({ size = 34, fill = '#FFF', className }: Props) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
fill={fill}
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox="0 0 36 36"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className={className}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
fill="#191717"
|
||||||
|
d="M18,1.4C9,1.4,1.7,8.7,1.7,17.7c0,7.2,4.7,13.3,11.1,15.5 c0.8,0.1,1.1-0.4,1.1-0.8c0-0.4,0-1.4,0-2.8c-4.5,1-5.5-2.2-5.5-2.2c-0.7-1.9-1.8-2.4-1.8-2.4c-1.5-1,0.1-1,0.1-1 c1.6,0.1,2.5,1.7,2.5,1.7c1.5,2.5,3.8,1.8,4.7,1.4c0.1-1.1,0.6-1.8,1-2.2c-3.6-0.4-7.4-1.8-7.4-8.1c0-1.8,0.6-3.2,1.7-4.4 c-0.2-0.4-0.7-2.1,0.2-4.3c0,0,1.4-0.4,4.5,1.7c1.3-0.4,2.7-0.5,4.1-0.5c1.4,0,2.8,0.2,4.1,0.5c3.1-2.1,4.5-1.7,4.5-1.7 c0.9,2.2,0.3,3.9,0.2,4.3c1,1.1,1.7,2.6,1.7,4.4c0,6.3-3.8,7.6-7.4,8c0.6,0.5,1.1,1.5,1.1,3c0,2.2,0,3.9,0,4.5 c0,0.4,0.3,0.9,1.1,0.8c6.5-2.2,11.1-8.3,11.1-15.5C34.3,8.7,27,1.4,18,1.4z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GithubLogo;
|
Reference in New Issue