mirror of
https://github.com/nickzuber/meteorite.git
synced 2024-08-16 23:10:38 +03:00
Design overhaul for home and login
This commit is contained in:
parent
5d0eb96836
commit
76e518e4bc
3
src/components/Curve/curve.svg
Normal file
3
src/components/Curve/curve.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="320" height="24" shape-rendering="geometricPrecision">
|
||||
<path fill="#FFF" fill-rule="evenodd" d="M320 0v24H0V0c53.3333333 16 106.666667 24 160 24 53.333333 0 106.666667-8 160-24z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 237 B |
20
src/components/Curve/index.js
Normal file
20
src/components/Curve/index.js
Normal file
@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import curve from './curve.svg';
|
||||
|
||||
export default function Curve ({ ...props }) {
|
||||
return (
|
||||
<div style={{
|
||||
background: `url(${curve}) center bottom`,
|
||||
position: 'absolute',
|
||||
bottom: '0',
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
width: '190vw',
|
||||
paddingBottom: '4.5%',
|
||||
backgroundSize: 'cover',
|
||||
marginBottom: '-1px',
|
||||
'-webkit-transform': 'translateX(-50%)',
|
||||
'-ms-transform': 'translateX(-50%)',
|
||||
}} />
|
||||
);
|
||||
}
|
15
src/components/LoadingIcon/index.js
Normal file
15
src/components/LoadingIcon/index.js
Normal file
@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
import loader from './loader.svg';
|
||||
|
||||
export default function LoadingIcon ({ style, ...props }) {
|
||||
return (
|
||||
<div style={{
|
||||
background: `url(${loader}) center center no-repeat`,
|
||||
position: 'relative',
|
||||
height: 100,
|
||||
width: 100,
|
||||
margin: '0 auto',
|
||||
...style
|
||||
}} {...props} />
|
||||
);
|
||||
}
|
17
src/components/LoadingIcon/loader.svg
Normal file
17
src/components/LoadingIcon/loader.svg
Normal file
@ -0,0 +1,17 @@
|
||||
<!-- By Sam Herbert (@sherb), for everyone. More @ http://goo.gl/7AJzbL -->
|
||||
<svg width="22" height="22" viewBox="-1 -1 22 22" xmlns="http://www.w3.org/2000/svg" stroke="#e4e4e4">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(1 1)" stroke-width="2.6">
|
||||
<circle stroke-opacity=".5" cx="9" cy="9" r="9"/>
|
||||
<path stroke="#7247ff" d="M18,9 C18,4.03 13.97,0 9,0">
|
||||
<animateTransform
|
||||
attributeName="transform"
|
||||
type="rotate"
|
||||
from="0 9 9"
|
||||
to="360 9 9"
|
||||
dur=".75s"
|
||||
repeatCount="indefinite"/>
|
||||
</path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 714 B |
@ -1,41 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Link } from "@reach/router";
|
||||
import { compose } from 'recompose';
|
||||
import { withAuthProvider } from '../providers/Auth';
|
||||
import { withCookiesProvider } from '../providers/Cookies';
|
||||
import { routes } from '../constants';
|
||||
import { OAUTH_TOKEN_COOKIE } from '../constants/cookies';
|
||||
|
||||
class HomePage extends React.Component {
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
Home!
|
||||
{this.props.authApi.token ? (
|
||||
<React.Fragment>
|
||||
<p><Link to={routes.INBOX}>inbox</Link></p>
|
||||
<p><a
|
||||
href="javascript:void(0);"
|
||||
onClick={() => {
|
||||
// Remove cookie and invalidate token on client.
|
||||
this.props.cookiesApi.removeCookie(OAUTH_TOKEN_COOKIE);
|
||||
this.props.authApi.invalidateToken();
|
||||
}}
|
||||
>
|
||||
soft logout
|
||||
</a></p>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<p><Link to={routes.LOGIN}>login</Link></p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const enhance = compose(
|
||||
withAuthProvider,
|
||||
withCookiesProvider
|
||||
);
|
||||
|
||||
export default enhance(HomePage);
|
78
src/pages/Home/Scene.js
Normal file
78
src/pages/Home/Scene.js
Normal file
@ -0,0 +1,78 @@
|
||||
import React from 'react';
|
||||
import { Link as RouterLink } from "@reach/router";
|
||||
import styled from 'react-emotion';
|
||||
import { routes } from '../../constants';
|
||||
import Curve from '../../components/Curve';
|
||||
import '../../styles/gradient.css';
|
||||
|
||||
const Header = styled('h1')({
|
||||
color: '#fff',
|
||||
padding: '0 20px',
|
||||
margin: '0 auto 16px'
|
||||
});
|
||||
|
||||
const SubHeader = styled(Header)({
|
||||
fontWeight: 500,
|
||||
color: '#fff',
|
||||
fontSize: 24
|
||||
});
|
||||
|
||||
const LandingHeader = styled('div')({
|
||||
width: '100%',
|
||||
margin: '54px 20px',
|
||||
maxWidth: 1000,
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
});
|
||||
|
||||
const LandingMessage = styled(LandingHeader)({
|
||||
flexDirection: 'column',
|
||||
textAlign: 'center',
|
||||
maxWidth: 1000,
|
||||
'h1': {
|
||||
display: 'block'
|
||||
}
|
||||
});
|
||||
|
||||
const LinksContainer = styled('div')({
|
||||
|
||||
});
|
||||
|
||||
const Logo = styled('div')({
|
||||
marginLeft: 15,
|
||||
background: 'green',
|
||||
width: 50,
|
||||
height: 50,
|
||||
});
|
||||
|
||||
const LinkButton = styled('a')({});
|
||||
|
||||
export default function Scene ({loggedIn, onLogout, ...props}) {
|
||||
return (
|
||||
<div className="container-gradient" style={{
|
||||
width: '100%',
|
||||
height: 600,
|
||||
position: 'relative',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
<LandingHeader>
|
||||
<Logo />
|
||||
{loggedIn ? (
|
||||
<LinksContainer>
|
||||
<RouterLink to={routes.INBOX}>inbox</RouterLink>
|
||||
<LinkButton href="javascript:void(0);" onClick={onLogout}>logout</LinkButton>
|
||||
</LinksContainer>
|
||||
) : (
|
||||
<RouterLink to={routes.LOGIN}>login</RouterLink>
|
||||
)}
|
||||
</LandingHeader>
|
||||
<LandingMessage>
|
||||
<Header>Conquer your notifications</Header>
|
||||
<SubHeader>Take back control over your GitHub notifications</SubHeader>
|
||||
</LandingMessage>
|
||||
<Curve />
|
||||
</div>
|
||||
);
|
||||
};
|
30
src/pages/Home/index.js
Normal file
30
src/pages/Home/index.js
Normal file
@ -0,0 +1,30 @@
|
||||
import React from 'react';
|
||||
import { compose } from 'recompose';
|
||||
import { withAuthProvider } from '../../providers/Auth';
|
||||
import { withCookiesProvider } from '../../providers/Cookies';
|
||||
import { OAUTH_TOKEN_COOKIE } from '../../constants/cookies';
|
||||
import Scene from './Scene';
|
||||
|
||||
class HomePage extends React.Component {
|
||||
onLogout = () => {
|
||||
// Remove cookie and invalidate token on client.
|
||||
this.props.cookiesApi.removeCookie(OAUTH_TOKEN_COOKIE);
|
||||
this.props.authApi.invalidateToken();
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<Scene
|
||||
loggedIn={!!this.props.authApi.token}
|
||||
onLogout={this.onLogout}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const enhance = compose(
|
||||
withAuthProvider,
|
||||
withCookiesProvider
|
||||
);
|
||||
|
||||
export default enhance(HomePage);
|
@ -3,31 +3,69 @@ import { Link } from "@reach/router";
|
||||
import styled from 'react-emotion';
|
||||
import { routes } from '../../constants';
|
||||
import { AuthenticationButton } from '../../components/buttons';
|
||||
import LoadingIcon from '../../components/LoadingIcon';
|
||||
import '../../styles/gradient.css';
|
||||
|
||||
const Container = styled('div')({
|
||||
background: '#f4f4f4',
|
||||
width: '100%',
|
||||
height: 100
|
||||
position: 'relative',
|
||||
background: '#fff',
|
||||
borderRadius: 4,
|
||||
margin: '0 auto',
|
||||
padding: '24px 48px',
|
||||
width: 300,
|
||||
height: 300
|
||||
});
|
||||
|
||||
const ButtonsContainer = styled('div')({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
position: 'absolute',
|
||||
bottom: 24,
|
||||
left: 48,
|
||||
right: 48,
|
||||
'a': {
|
||||
margin: 0
|
||||
}
|
||||
});
|
||||
|
||||
export default function Scene ({ loading, error, loggedOut, ...props }) {
|
||||
return (
|
||||
<Container>
|
||||
<Link to={routes.HOME}>home</Link>
|
||||
<div>
|
||||
<div className="container-gradient" style={{
|
||||
width: '100%',
|
||||
height: 600,
|
||||
position: 'relative',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
height: '100vh',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
<Container>
|
||||
<h3>Authenticate with GitHub</h3>
|
||||
{error ? (
|
||||
<div>
|
||||
error, try again?
|
||||
<AuthenticationButton />
|
||||
</div>
|
||||
<React.Fragment>
|
||||
<p>Log in with GitHub and we'll start organizing and sorting all of your notifications.</p>
|
||||
<ButtonsContainer>
|
||||
<Link to={routes.HOME}>go back</Link>
|
||||
<AuthenticationButton />
|
||||
</ButtonsContainer>
|
||||
</React.Fragment>
|
||||
) : loading ? (
|
||||
<span>loading...</span>
|
||||
<LoadingIcon />
|
||||
) : loggedOut ? (
|
||||
<AuthenticationButton />
|
||||
<React.Fragment>
|
||||
<p>Log in with GitHub and we'll start organizing and sorting all of your notifications.</p>
|
||||
<ButtonsContainer>
|
||||
<Link to={routes.HOME}>go back</Link>
|
||||
<AuthenticationButton />
|
||||
</ButtonsContainer>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<span>logged in!</span>
|
||||
)}
|
||||
</div>
|
||||
</Container>
|
||||
</Container>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
56
src/styles/gradient.css
Normal file
56
src/styles/gradient.css
Normal file
@ -0,0 +1,56 @@
|
||||
|
||||
.container-gradient {
|
||||
background: radial-gradient(farthest-corner at -0% 100%, #7247ff 30%, #00ffbe 95%);
|
||||
background-size: 400% 400%;
|
||||
|
||||
-webkit-animation: gradientTransition 30s ease infinite;
|
||||
-moz-animation: gradientTransition 30s ease infinite;
|
||||
animation: gradientTransition 30s ease infinite;
|
||||
}
|
||||
|
||||
.container-gradient a {
|
||||
cursor: pointer;
|
||||
color: #7247ff;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
padding: 0 16px;
|
||||
margin-right: 15px;
|
||||
height: 48px;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
-webkit-text-decoration: none;
|
||||
text-decoration: none;
|
||||
-webkit-transition: all 0.12s ease-in-out;
|
||||
transition: all 0.12s ease-in-out;
|
||||
display: -webkit-inline-box;
|
||||
display: -webkit-inline-flex;
|
||||
display: -ms-inline-flexbox;
|
||||
display: inline-flex;
|
||||
}
|
||||
.container-gradient a:hover {
|
||||
background: #f9f9f9
|
||||
}
|
||||
.container-gradient a:active {
|
||||
background: #e4e4e4
|
||||
}
|
||||
|
||||
@-webkit-keyframes gradientTransition {
|
||||
0% {background-position: 0% 50%}
|
||||
50% {background-position: 60% 50%}
|
||||
100% {background-position: 0% 50%}
|
||||
}
|
||||
@-moz-keyframes gradientTransition {
|
||||
0% {background-position: 0% 50%}
|
||||
50% {background-position: 60% 50%}
|
||||
100% {background-position: 0% 50%}
|
||||
}
|
||||
@keyframes gradientTransition {
|
||||
0% {background-position: 0% 50%}
|
||||
50% {background-position: 60% 50%}
|
||||
100% {background-position: 0% 50%}
|
||||
}
|
@ -1,7 +1,12 @@
|
||||
@import url('https://rsms.me/inter/inter-ui.css');
|
||||
|
||||
::selection {
|
||||
color: #fff;
|
||||
background: #7247ff;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #f4f4f4;
|
||||
background: #ffffff;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Inter UI', -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||
@ -11,7 +16,42 @@ body {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
||||
monospace;
|
||||
h1 {
|
||||
font-weight: 500;
|
||||
font-size: 48px;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 500;
|
||||
font-size: 38px;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 500;
|
||||
font-size: 28px;
|
||||
letter-spacing: -0.5px;
|
||||
margin: 10px 0 20px;
|
||||
}
|
||||
|
||||
p {
|
||||
font: 15px/22px 'Inter UI', system-ui, sans-serif;
|
||||
color: #111;
|
||||
font: 15px/22px 'Inter UI', system-ui, sans-serif;
|
||||
font-size: 15px;
|
||||
line-height: 1.5;
|
||||
letter-spacing: -0.002em;
|
||||
font-weight: 400;
|
||||
margin: 20px 0;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scroll-behavior: smooth;
|
||||
font-kerning: normal;
|
||||
-moz-font-feature-settings: "calt" 1, "kern" 1, "liga" 1;
|
||||
-ms-font-feature-settings: "calt" 1, "kern" 1, "liga" 1;
|
||||
-o-font-feature-settings: "calt" 1, "kern" 1, "liga" 1;
|
||||
-webkit-font-feature-settings: "calt" 1, "kern" 1, "liga" 1;
|
||||
font-feature-settings: "calt" 1, "kern" 1, "liga" 1;
|
||||
}
|
||||
|
4
src/utils/svg.js
Normal file
4
src/utils/svg.js
Normal file
@ -0,0 +1,4 @@
|
||||
export function inlineSvg (svg) {
|
||||
const b64 = btoa(svg);
|
||||
return `"data:image/svg+xml;base64,${b64}"`;
|
||||
}
|
Loading…
Reference in New Issue
Block a user