Skip to content

Commit 0b6fb9d

Browse files
committed
Login page
1 parent e08ce86 commit 0b6fb9d

File tree

6 files changed

+269
-0
lines changed

6 files changed

+269
-0
lines changed

src/components/App.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
55
import themes from '../themes';
66
import Layout from './Layout';
77
import Error from '../pages/error';
8+
import Login from '../pages/login';
89

910
const theme = createMuiTheme(themes.default.theme);
1011

@@ -15,6 +16,7 @@ const App = () => (
1516
<Route exact path="/" render={() => <Redirect to="/app/dashboard" />} />
1617
<Route exact path="/app" render={() => <Redirect to="/app/dashboard" />} />
1718
<Route path="/app" component={Layout} />
19+
<Route path="/login" component={Login} />
1820
<Route component={Error} />
1921
</Switch>
2022
</BrowserRouter>

src/images/google.svg

Lines changed: 47 additions & 0 deletions
Loading

src/pages/login/LoginContainer.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { compose, withState, withHandlers } from 'recompose';
2+
3+
import LoginView from './LoginView';
4+
5+
export default compose(
6+
withState('activeTabId', 'setActiveTabId', 0),
7+
withState('loginValue', 'setLoginValue', ''),
8+
withState('passwordValue', 'setPasswordValue', ''),
9+
withHandlers({
10+
handleTabChange: props => (e, id) => {
11+
props.setActiveTabId(id);
12+
},
13+
handleInput: props => (e, input = 'login') => {
14+
if (input === 'login') {
15+
props.setLoginValue(e.target.value);
16+
} else {
17+
props.setPasswordValue(e.target.value);
18+
}
19+
}
20+
}),
21+
)(LoginView);

src/pages/login/LoginView.js

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
import React from 'react';
2+
import { Link } from 'react-router-dom';
3+
import { Grid, Paper, Typography, withStyles, Button, Tabs, Tab, TextField } from '@material-ui/core';
4+
import classnames from 'classnames';
5+
6+
import logo from './logo.svg';
7+
import google from '../../images/google.svg';
8+
9+
const Login = ({ classes, ...props }) => (
10+
<Grid container className={classes.container}>
11+
<div className={classes.logotypeContainer}>
12+
<img src={logo} alt="logo" className={classes.logotypeImage} />
13+
<Typography className={classes.logotypeText}>Material Admin</Typography>
14+
</div>
15+
<div className={classes.formContainer}>
16+
<div className={classes.form}>
17+
<Tabs
18+
value={props.activeTabId}
19+
onChange={props.handleTabChange}
20+
indicatorColor="primary"
21+
textColor="primary"
22+
centered
23+
>
24+
<Tab label="Login" classes={{ root: classes.tab }} />
25+
<Tab label="New User" classes={{ root: classes.tab }} />
26+
</Tabs>
27+
<Typography variant="h3" className={classes.greeting}>Good Morning, User</Typography>
28+
<Button size="large" className={classes.googleButton}><img src={google} alt="google" className={classes.googleIcon} />&nbsp;Sign in with Google</Button>
29+
<div className={classes.formDividerContainer}>
30+
<div className={classes.formDivider} />
31+
<Typography className={classes.formDividerWord}>or</Typography>
32+
<div className={classes.formDivider} />
33+
</div>
34+
<TextField
35+
id="email"
36+
InputProps={{ classes: { underline: classes.textFieldUnderline, input: classes.textField }}}
37+
value={props.loginValue}
38+
onChange={e => props.handleInput(e, 'login')}
39+
margin="normal"
40+
placeholder="Email Adress"
41+
type="email"
42+
fullWidth
43+
/>
44+
<TextField
45+
id="password"
46+
InputProps={{ classes: { underline: classes.textFieldUnderline, input: classes.textField }}}
47+
value={props.passwordValue}
48+
onChange={e => props.handleInput(e, 'password')}
49+
margin="normal"
50+
placeholder="Password"
51+
type="password"
52+
fullWidth
53+
/>
54+
<div className={classes.formButtons}>
55+
<Button disabled={props.loginValue.length === 0 || props.passwordValue.length === 0} variant="contained" color="primary" size="large">Login</Button>
56+
<Typography color="primary">Forget Password</Typography>
57+
</div>
58+
</div>
59+
<Typography color="primary" className={classes.copyright}>
60+
© 2014-2019 Flatlogic, LLC. All rights reserved.
61+
</Typography>
62+
</div>
63+
</Grid>
64+
);
65+
66+
const styles = theme => ({
67+
container: {
68+
height: '100vh',
69+
width: '100vw',
70+
display: 'flex',
71+
justifyContent: 'center',
72+
alignItems: 'center',
73+
position: 'absolute',
74+
top: 0,
75+
left: 0,
76+
},
77+
logotypeContainer: {
78+
backgroundColor: theme.palette.primary.main,
79+
width: '60%',
80+
height: '100%',
81+
display: 'flex',
82+
flexDirection: 'column',
83+
justifyContent: 'center',
84+
alignItems: 'center',
85+
[theme.breakpoints.down("md")]: {
86+
width: '50%',
87+
},
88+
[theme.breakpoints.down("md")]: {
89+
display: 'none',
90+
}
91+
},
92+
logotypeImage: {
93+
width: 165,
94+
marginBottom: theme.spacing.unit * 4,
95+
},
96+
logotypeText: {
97+
color: 'white',
98+
fontWeight: 500,
99+
fontSize: 84,
100+
[theme.breakpoints.down("md")]: {
101+
fontSize: 48,
102+
}
103+
},
104+
formContainer: {
105+
width: '40%',
106+
height: '100%',
107+
display: 'flex',
108+
flexDirection: 'column',
109+
justifyContent: 'center',
110+
alignItems: 'center',
111+
[theme.breakpoints.down("md")]: {
112+
width: '50%',
113+
}
114+
},
115+
form: {
116+
width: 320,
117+
},
118+
tab: {
119+
fontWeight: 400,
120+
fontSize: 18,
121+
},
122+
greeting: {
123+
fontWeight: 500,
124+
textAlign: 'center',
125+
marginTop: theme.spacing.unit * 4,
126+
},
127+
googleButton: {
128+
marginTop: theme.spacing.unit * 6,
129+
boxShadow: theme.customShadows.widget,
130+
backgroundColor: 'white',
131+
width: '100%',
132+
textTransform: 'none',
133+
},
134+
googleIcon: {
135+
width: 30,
136+
marginRight: theme.spacing.unit * 2,
137+
},
138+
formDividerContainer: {
139+
marginTop: theme.spacing.unit * 4,
140+
marginBottom: theme.spacing.unit * 4,
141+
display: 'flex',
142+
alignItems: 'center',
143+
},
144+
formDividerWord: {
145+
paddingLeft: theme.spacing.unit * 2,
146+
paddingRight: theme.spacing.unit * 2,
147+
},
148+
formDivider: {
149+
flexGrow: 1,
150+
height: 1,
151+
backgroundColor: theme.palette.text.hint + '40',
152+
},
153+
textFieldUnderline: {
154+
'&:before': {
155+
borderBottomColor: theme.palette.primary.light,
156+
},
157+
'&:after': {
158+
borderBottomColor: theme.palette.primary.main,
159+
},
160+
'&:hover:before': {
161+
borderBottomColor: `${theme.palette.primary.light} !important`,
162+
}
163+
},
164+
textField: {
165+
borderBottomColor: theme.palette.primary.light,
166+
},
167+
formButtons: {
168+
width: '100%',
169+
marginTop: theme.spacing.unit * 4,
170+
display: 'flex',
171+
justifyContent: 'space-between',
172+
alignItems: 'center',
173+
},
174+
copyright: {
175+
position: 'absolute',
176+
bottom: theme.spacing.unit * 2,
177+
}
178+
});
179+
180+
export default withStyles(styles, { withTheme: true })(Login);

src/pages/login/logo.svg

Lines changed: 13 additions & 0 deletions
Loading

src/pages/login/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "Login",
3+
"version": "0.0.0",
4+
"main": "LoginContainer.js",
5+
"private": true
6+
}

0 commit comments

Comments
 (0)