Skip to content

Commit 4311faf

Browse files
committed
Add Login Page and auth for http requests
1 parent 540b265 commit 4311faf

5 files changed

Lines changed: 882 additions & 231 deletions

File tree

src/Component/NavBar.js

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React from 'react'
22
import classNames from 'classnames'
3-
import {Link} from 'react-router-dom'
4-
import {connect} from 'react-redux'
5-
import {filterToggle} from '../Redux'
3+
import { Link } from 'react-router-dom'
4+
import { connect } from 'react-redux'
5+
import { filterToggle } from '../Redux'
66
import { withStyles } from '@material-ui/core/styles'
7-
import {withRouter} from 'react-router'
7+
import { withRouter } from 'react-router'
88
import {
99
AppBar,
1010
Toolbar,
@@ -18,19 +18,23 @@ import {
1818
ListItemText,
1919
FormControlLabel,
2020
Switch,
21-
Button,
22-
Tooltip
21+
Tooltip,
22+
Button
2323
} from '@material-ui/core'
2424
// import MenuIcon from '@material-ui/icons/Menu'
2525
import ChevronLeftIcon from '@material-ui/icons/ChevronLeft'
2626
import DoneIcon from '@material-ui/icons/Done'
27+
import axios from 'axios'
28+
29+
axios.defaults.withCredentials = true
30+
const URL = 'http://localhost:8080'
2731

2832
const drawerWidth = 240
2933

30-
const styles =(theme)=>({
34+
const styles = (theme) => ({
3135
flex: {
3236
flexGrow: 1,
33-
userSelect:'none'
37+
userSelect: 'none'
3438
},
3539
appBar: {
3640
transition: theme.transitions.create(['margin', 'width'], {
@@ -39,14 +43,14 @@ const styles =(theme)=>({
3943
}),
4044
},
4145
appBarShift: {
42-
width: `calc(100% - ${drawerWidth}px)`,
43-
transition: theme.transitions.create(['margin', 'width'], {
44-
easing: theme.transitions.easing.easeOut,
45-
duration: theme.transitions.duration.enteringScreen,
46-
}),
46+
width: `calc(100% - ${drawerWidth}px)`,
47+
transition: theme.transitions.create(['margin', 'width'], {
48+
easing: theme.transitions.easing.easeOut,
49+
duration: theme.transitions.duration.enteringScreen,
50+
}),
4751
},
4852
'appBarShift-left': {
49-
marginLeft: drawerWidth,
53+
marginLeft: drawerWidth,
5054
},
5155
menuButton: {
5256
marginLeft: -12,
@@ -73,56 +77,63 @@ const menu = (
7377
<ListItemIcon>
7478
<DoneIcon />
7579
</ListItemIcon>
76-
<ListItemText primary="已繳系學會費"/>
80+
<ListItemText primary="已繳系學會費" />
7781
</ListItem>
7882
</Link>
7983
)
8084

8185
class NavBar extends React.Component {
82-
constructor(props){
86+
constructor(props) {
8387
super(props)
8488
this.state = {
8589
open: false
8690
}
8791
this.drawerOpen = this.drawerOpen.bind(this)
8892
this.drawerClose = this.drawerClose.bind(this)
8993
}
90-
drawerOpen(){
94+
drawerOpen() {
9195
this.props.check(true)
92-
this.setState({open:true})
96+
this.setState({ open: true })
9397
}
94-
drawerClose(){
98+
drawerClose() {
9599
this.props.check(false)
96-
this.setState({open:false})
100+
this.setState({ open: false })
101+
}
102+
logout() {
103+
axios.post(`${URL}/_api/fee_logout`, {}).then(
104+
res => {
105+
window.location.href = '/login'
106+
}
107+
)
97108
}
98109
render() {
99110
const { classes } = this.props
100111
const LDrawer = (
101-
<Drawer
102-
variant="persistent"
103-
open={this.state.open}
104-
classes={{
112+
<Drawer
113+
variant="persistent"
114+
open={this.state.open}
115+
classes={{
105116
paper: classes.drawerPaper,
106-
}}
107-
>
108-
<div className={classes.drawerHeader}>
109-
<IconButton onClick={this.drawerClose}>
110-
<ChevronLeftIcon />
111-
</IconButton>
112-
</div>
113-
<Divider />
114-
<List>
115-
{menu}
116-
</List>
117-
</Drawer>)
117+
}}
118+
>
119+
<div className={classes.drawerHeader}>
120+
<IconButton onClick={this.drawerClose}>
121+
<ChevronLeftIcon />
122+
</IconButton>
123+
</div>
124+
<Divider />
125+
<List>
126+
{menu}
127+
</List>
128+
</Drawer>)
118129

119130
return (
120131
<React.Fragment>
121132
<AppBar position="sticky"
122-
className={classNames(classes.appBar, {
123-
[classes.appBarShift]: this.state.open,
124-
[classes['appBarShift-left']]: this.state.open,
125-
})}>
133+
className={classNames(classes.appBar, {
134+
[classes.appBarShift]: this.state.open,
135+
[classes['appBarShift-left']]: this.state.open,
136+
})}>
126137
<Toolbar>
127138
{/* <IconButton
128139
className={classNames(classes.menuButton, this.state.open && classes.hide)}
@@ -134,7 +145,7 @@ class NavBar extends React.Component {
134145
</Typography>
135146
{
136147
this.props.location.pathname === '/' &&
137-
<Tooltip title={this.props.filter?'僅顯示已繳系學會費':'顯示全部'}>
148+
<Tooltip title={this.props.filter ? '僅顯示已繳系學會費' : '顯示全部'}>
138149
<FormControlLabel
139150
control={
140151
<Switch
@@ -148,9 +159,9 @@ class NavBar extends React.Component {
148159
</Tooltip>
149160
}
150161
{
151-
this.props.location.pathname === '/login' &&
152-
<Button color="inherit" onClick={() => (window.location.href = 'https://csunion.nctu.me/_api/oauth')}>
153-
登入
162+
this.props.location.pathname !== '/login' &&
163+
<Button color="inherit" onClick={() => this.logout()}>
164+
登出
154165
</Button>
155166
}
156167
</Toolbar>

src/Page/Login.js

Lines changed: 103 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
import React from 'react'
22
import { withStyles } from '@material-ui/core/styles'
3+
import {
4+
InputLabel,
5+
TextField,
6+
Button
7+
} from '@material-ui/core'
8+
import axios from 'axios'
39

4-
const styles = (theme)=>({
10+
axios.defaults.withCredentials = true
11+
12+
const URL = 'http://localhost:8080'
13+
const styles = (theme) => ({
514
root: {
615
flexGrow: 1,
716
fontSize: '1.1em',
817
fontWeight: 300
918
},
1019
content: {
11-
position:'relative',
20+
position: 'relative',
1221
flexGrow: 1,
1322
padding: theme.spacing.unit * 3,
1423
transition: theme.transitions.create('margin', {
@@ -18,8 +27,8 @@ const styles = (theme)=>({
1827
},
1928
title: {
2029
position: 'absolute',
21-
top:'calc( 50vh - 2em )',
22-
left:'1.4em',
30+
top: 'calc( 50vh - 2em )',
31+
left: '1.4em',
2332
fontSize: '4em',
2433
fontWeight: '500',
2534
color: '#666',
@@ -30,28 +39,103 @@ const styles = (theme)=>({
3039
button: {
3140
display: 'block',
3241
position: 'absolute',
33-
top:'52vh',
34-
right:'23vw',
42+
top: '52vh',
43+
right: '23vw',
3544
fontSize: '1.1em',
3645
padding: '1% 3%'
46+
},
47+
container: {
48+
margin: '0 auto',
49+
width: 'fit-content',
50+
backgroundColor: '#f5f5f5',
51+
boxShadow: '1px 1px 2px #999999',
52+
padding: '20px',
53+
borderRadius: '.7rem',
54+
},
55+
column: {
56+
display: 'flex',
57+
flexDirection: 'column',
58+
alignItems: 'center',
59+
justifyContent: 'space-between',
60+
rowGap: '10px'
61+
},
62+
row: {
63+
display: 'flex',
64+
alignItems: 'center',
65+
justifyContent: 'space-between',
66+
columnGap: '5px'
3767
}
3868
})
3969

40-
const Login = (props)=>{
41-
const {classes} = props
42-
return(
43-
<div className={classes.root}>
44-
<div className={classes.content}>
45-
{/* <div className={classes.title}>
46-
NCTU CS Union
70+
class Login extends React.Component {
71+
constructor(props) {
72+
super(props)
73+
this.state = {
74+
username: '',
75+
password: ''
76+
}
77+
}
78+
79+
tryLogin() {
80+
axios.post(`${URL}/_api/fee_auth`, {
81+
username: this.state.username,
82+
password: this.state.password
83+
}).then(
84+
res => {
85+
if (res.data)
86+
window.location.href = '/'
87+
else
88+
window.location.reload()
89+
}
90+
)
91+
}
92+
93+
handleUsernameChange(evt) {
94+
const password = this.state.password
95+
this.setState({
96+
username: evt.target.value,
97+
password: password
98+
})
99+
}
100+
101+
handlePasswordChange(evt) {
102+
const username = this.state.username
103+
this.setState({
104+
username: username,
105+
password: evt.target.value
106+
})
107+
}
108+
109+
render() {
110+
axios.post(`${URL}/_api/fee_check`, {}).then(
111+
res => {
112+
if (res.data)
113+
window.location.href = '/'
114+
}
115+
)
116+
const { classes } = this.props
117+
return (
118+
<div className={classes.root}>
119+
<div className={classes.content}>
120+
<div className={classes.container}>
121+
<div className={classes.column}>
122+
<div className={classes.row}>
123+
<InputLabel htmlFor="username">Username</InputLabel>
124+
<TextField id="username" name="username" aria-describedby="Username" onChange={evt => this.handleUsernameChange(evt)} />
125+
</div>
126+
<div className={classes.row}>
127+
<InputLabel htmlFor="password">Password</InputLabel>
128+
<TextField id="password" name="password" aria-describedby="Password" type="password" onChange={evt => this.handlePasswordChange(evt)} />
129+
</div>
130+
<Button type="button" variant="outlined" color="primary" onClick={() => this.tryLogin()}>
131+
登入
132+
</Button>
133+
</div>
47134
</div>
48-
<Button variant="contained" size="large" color="primary" className={classes.button}>
49-
交大單一入口登入
50-
</Button> */}
51-
登入已查看繳費情形...
135+
</div>
52136
</div>
53-
</div>
54-
)
137+
)
138+
}
55139
}
56140

57141
export default withStyles(styles)(Login)

0 commit comments

Comments
 (0)