# HG changeset patch # User Alexandre Segura # Date 1497887801 -7200 # Node ID d8588379529e1b5112721c633cae9d82c683973f # Parent 96f8a4a59bd92996768bbc0a87ad78132c671689 Add settings page. diff -r 96f8a4a59bd9 -r d8588379529e client/src/APIClient.js --- 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); } diff -r 96f8a4a59bd9 -r d8588379529e client/src/actions/userActions.js --- /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 + }; +} diff -r 96f8a4a59bd9 -r d8588379529e client/src/components/Navbar.js --- 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 ( - Settings + Settings Logout ); diff -r 96f8a4a59bd9 -r d8588379529e client/src/components/Settings.js --- /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 ( +
+ + + + +
+ + First name + { this.firstname = ref; } } + /> + + + Last name + { this.lastname = ref; } } + /> + +
+ + +
+
+
+ ); + } +} + +function mapStateToProps(state, props) { + return { + currentUser: state.get('currentUser'), + }; +} + +function mapDispatchToProps(dispatch) { + return { + userActions: bindActionCreators(userActions, dispatch) + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(Settings); diff -r 96f8a4a59bd9 -r d8588379529e client/src/constants/actionTypes.js --- 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' diff -r 96f8a4a59bd9 -r d8588379529e client/src/index.js --- 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 @@
+ diff -r 96f8a4a59bd9 -r d8588379529e client/src/reducers/authReducer.js --- 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; } diff -r 96f8a4a59bd9 -r d8588379529e client/src/sagas/index.js --- 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(), ]) } diff -r 96f8a4a59bd9 -r d8588379529e src/irinotes/settings.py --- 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/.*$' +