Add settings page.
--- a/client/src/APIClient.js Mon Jun 19 15:36:52 2017 +0200
+++ b/client/src/APIClient.js Mon Jun 19 17:56:41 2017 +0200
@@ -31,8 +31,7 @@
var headers = new Headers(),
token = localStorage.getItem('token') || '';
- headers.append("Authorization", "Bearer " + token);
- headers.append("Content-Type", "application/json");
+ headers.append("Authorization", "JWT " + token);
return this.createRequest(method, uri, data, headers);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/actions/userActions.js Mon Jun 19 17:56:41 2017 +0200
@@ -0,0 +1,10 @@
+import * as types from '../constants/actionTypes';
+
+export const updateSettings = (username, firstname, lastname) => {
+ return {
+ type: types.USER_UPDATE_SETTINGS_ASYNC,
+ username,
+ firstname,
+ lastname
+ };
+}
--- a/client/src/components/Navbar.js Mon Jun 19 15:36:52 2017 +0200
+++ b/client/src/components/Navbar.js Mon Jun 19 17:56:41 2017 +0200
@@ -1,3 +1,4 @@
+
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
@@ -23,6 +24,11 @@
this.props.history.push('/login');
}
+ onClickSettings = (e) => {
+ e.preventDefault();
+ this.props.history.push('/settings');
+ }
+
onClickLogout = (e) => {
e.preventDefault();
this.props.authActions.logout();
@@ -33,7 +39,7 @@
if (this.props.currentUser) {
return (
<NavDropdown title={ this.props.currentUser.username } id="user-dropdown">
- <MenuItem>Settings</MenuItem>
+ <MenuItem onClick={this.onClickSettings}>Settings</MenuItem>
<MenuItem onClick={this.onClickLogout}>Logout</MenuItem>
</NavDropdown>
);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/components/Settings.js Mon Jun 19 17:56:41 2017 +0200
@@ -0,0 +1,71 @@
+import React, { Component } from 'react';
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+import { Grid, Row, Col, Button, FormGroup, ControlLabel, FormControl } from 'react-bootstrap';
+import '../App.css';
+import Navbar from './Navbar';
+import * as userActions from '../actions/userActions';
+
+class Settings extends Component {
+
+ updateSettings = () => {
+ const username = this.props.currentUser.username;
+ const firstname = this.firstname.value;
+ const lastname = this.lastname.value;
+
+ this.props.userActions.updateSettings(username, firstname, lastname);
+ }
+
+ render() {
+
+ const firstname = this.props.currentUser ? this.props.currentUser.first_name : '';
+ const lastname = this.props.currentUser ? this.props.currentUser.last_name : '';
+
+ return (
+ <div>
+ <Navbar history={this.props.history} />
+ <Grid fluid>
+ <Row>
+ <Col md={6} mdOffset={3}>
+ <form>
+ <FormGroup>
+ <ControlLabel>First name</ControlLabel>
+ <FormControl
+ name="firstname"
+ defaultValue={ firstname }
+ placeholder="John"
+ inputRef={ ref => { this.firstname = ref; } }
+ />
+ </FormGroup>
+ <FormGroup>
+ <ControlLabel>Last name</ControlLabel>
+ <FormControl
+ name="lastname"
+ defaultValue={ lastname }
+ placeholder="Doe"
+ inputRef={ ref => { this.lastname = ref; } }
+ />
+ </FormGroup>
+ </form>
+ <Button block bsStyle="success" onClick={this.updateSettings}>Save settings</Button>
+ </Col>
+ </Row>
+ </Grid>
+ </div>
+ );
+ }
+}
+
+function mapStateToProps(state, props) {
+ return {
+ currentUser: state.get('currentUser'),
+ };
+}
+
+function mapDispatchToProps(dispatch) {
+ return {
+ userActions: bindActionCreators(userActions, dispatch)
+ }
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(Settings);
--- a/client/src/constants/actionTypes.js Mon Jun 19 15:36:52 2017 +0200
+++ b/client/src/constants/actionTypes.js Mon Jun 19 17:56:41 2017 +0200
@@ -17,3 +17,6 @@
export const AUTH_STORE_TOKEN_ASYNC = 'AUTH_STORE_TOKEN_ASYNC';
export const AUTH_STORE_TOKEN = 'AUTH_STORE_TOKEN';
export const AUTH_LOGOUT = 'AUTH_LOGOUT';
+
+export const USER_UPDATE_SETTINGS_ASYNC = 'USER_UPDATE_SETTINGS_ASYNC';
+export const USER_UPDATE_SETTINGS = 'USER_UPDATE_SETTINGS'
--- a/client/src/index.js Mon Jun 19 15:36:52 2017 +0200
+++ b/client/src/index.js Mon Jun 19 17:56:41 2017 +0200
@@ -9,6 +9,7 @@
import Sessions from './components/Sessions';
import Session from './components/Session';
import Login from './components/Login';
+import Settings from './components/Settings';
import './index.css';
import registerServiceWorker from './registerServiceWorker';
import configureStore from './store/configureStore';
@@ -20,6 +21,7 @@
<Provider store={store}>
<ConnectedRouter history={history}>
<div>
+ <Route exact path="/settings" component={Settings} />
<Route exact path="/sessions/:id" component={Session} />
<Route exact path="/sessions" component={Sessions} />
<Route exact path="/login" component={Login} />
--- a/client/src/reducers/authReducer.js Mon Jun 19 15:36:52 2017 +0200
+++ b/client/src/reducers/authReducer.js Mon Jun 19 17:56:41 2017 +0200
@@ -14,6 +14,11 @@
return null;
case types.AUTH_LOGIN_SUCCESS:
return action.user;
+ case types.USER_UPDATE_SETTINGS:
+ state.first_name = action.firstname;
+ state.last_name = action.lastname;
+ localStorage.setItem('currentUser', JSON.stringify(state));
+ return state;
default:
return state;
}
--- a/client/src/sagas/index.js Mon Jun 19 15:36:52 2017 +0200
+++ b/client/src/sagas/index.js Mon Jun 19 17:56:41 2017 +0200
@@ -137,6 +137,22 @@
}
}
+function* watchUpdateSettings() {
+ while (true) {
+ const { username, firstname, lastname } = yield take(types.USER_UPDATE_SETTINGS_ASYNC);
+ try {
+ yield client.put('/api/auth/user/', {
+ username,
+ first_name: firstname,
+ last_name: lastname
+ });
+ yield put({ type: types.USER_UPDATE_SETTINGS, firstname, lastname });
+ } catch (e) {
+
+ }
+ }
+}
+
// ---
export default function* rootSaga() {
@@ -149,5 +165,6 @@
watchLoginSubmit(),
watchLoginRequest(),
watchStoreToken(),
+ watchUpdateSettings(),
])
}
--- a/src/irinotes/settings.py Mon Jun 19 15:36:52 2017 +0200
+++ b/src/irinotes/settings.py Mon Jun 19 17:56:41 2017 +0200
@@ -234,3 +234,4 @@
CORS_ORIGIN_ALLOW_ALL = True
CORS_URLS_REGEX = r'^/api/.*$'
+