diff --git a/api-server/server/boot/settings.js b/api-server/server/boot/settings.js
index 3f0c25a431..b2911bedef 100644
--- a/api-server/server/boot/settings.js
+++ b/api-server/server/boot/settings.js
@@ -1,8 +1,12 @@
+import debug from 'debug';
import { check } from 'express-validator/check';
+
import { ifNoUser401, createValidatorErrorHandler } from '../utils/middleware';
import { themes } from '../../common/utils/themes.js';
import { alertTypes } from '../../common/utils/flash.js';
+const log = debug('fcc:boot:settings');
+
export default function settingsController(app) {
const api = app.loopback.Router();
@@ -47,6 +51,7 @@ export default function settingsController(app) {
createValidatorErrorHandler(alertTypes.danger),
updateMyTheme
);
+ api.put('/update-my-about', ifNoUser401, updateMyAbout);
api.put('/update-my-username', ifNoUser401, updateMyUsername);
app.use('/internal', api);
@@ -59,6 +64,11 @@ const standardErrorMessage = {
'Something went wrong updating your account. Please check and try again'
};
+const standardSuccessMessage = {
+ type: 'success',
+ message: 'We have updated your preferences'
+};
+
const toggleUserFlag = (flag, req, res, next) => {
const { user } = req;
const currentValue = user[flag];
@@ -180,6 +190,21 @@ function updateMyProjects(req, res, next) {
.subscribe(message => res.json({ message }), next);
}
+function updateMyAbout(req, res, next) {
+ const {
+ user,
+ body: { name, location, about, picture }
+ } = req;
+ log(name, location, picture, about)
+ return user.updateAttributes({ name, location, about, picture }, err => {
+ if (err) {
+ res.status(500).json(standardErrorMessage);
+ return next(err);
+ }
+ return res.status(200).json(standardSuccessMessage);
+ });
+}
+
function createUpdateMyUsername(app) {
const { User } = app.models;
return async function updateMyUsername(req, res, next) {
diff --git a/client/src/components/settings/About.js b/client/src/components/settings/About.js
index 21d3e4564b..ad7d6c07ab 100644
--- a/client/src/components/settings/About.js
+++ b/client/src/components/settings/About.js
@@ -1,25 +1,24 @@
-import React, { Component, Fragment } from 'react';
+import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import {
- Nav,
- NavItem,
FormGroup,
ControlLabel,
FormControl
} from '@freecodecamp/react-bootstrap';
+import { submitNewAbout } from '../../redux/settings';
+
import { FullWidthRow, Spacer } from '../helpers';
import ThemeSettings from './Theme';
-import Camper from './Camper';
import UsernameSettings from './Username';
import BlockSaveButton from '../helpers/form/BlockSaveButton';
-import BlockSaveWrapper from '../helpers/form/BlockSaveWrapper';
const mapStateToProps = () => ({});
-const mapDispatchToProps = dispatch => bindActionCreators({}, dispatch);
+const mapDispatchToProps = dispatch =>
+ bindActionCreators({ submitNewAbout }, dispatch);
const propTypes = {
about: PropTypes.string,
@@ -28,6 +27,7 @@ const propTypes = {
name: PropTypes.string,
picture: PropTypes.string,
points: PropTypes.number,
+ submitNewAbout: PropTypes.func.isRequired,
username: PropTypes.string
};
@@ -36,33 +36,58 @@ class AboutSettings extends Component {
super(props);
const { name = '', location = '', picture = '', about = '' } = props;
-
- this.state = {
- view: 'edit',
- formValues: {
- name,
- location,
- picture,
- about
- },
- isFormPristine: true
+ const values = {
+ name,
+ location,
+ picture,
+ about
};
-
- this.handleSubmit = this.handleSubmit.bind(this);
- this.handleTabSelect = this.handleTabSelect.bind(this);
- this.renderEdit = this.renderEdit.bind(this);
- this.renderPreview = this.renderPreview.bind(this);
- this.show = {
- edit: this.renderEdit,
- preview: this.renderPreview
+ this.state = {
+ formValues: { ...values },
+ originalValues: { ...values },
+ formClicked: false
};
}
- handleSubmit(e) {
+ componentDidUpdate() {
+ const { name, location, picture, about } = this.props;
+ const { formValues, formClicked } = this.state;
+ if (
+ formClicked &&
+ name === formValues.name &&
+ location === formValues.location &&
+ picture === formValues.picture &&
+ about === formValues.about
+ ) {
+ /* eslint-disable-next-line react/no-did-update-set-state */
+ return this.setState({
+ originalValues: {
+ name,
+ location,
+ picture,
+ about
+ },
+ formClicked: false
+ });
+ }
+ return null;
+ }
+
+ isFormPristine = () => {
+ const { formValues, originalValues } = this.state;
+ return Object.keys(originalValues)
+ .map(key => originalValues[key] === formValues[key])
+ .every(bool => bool);
+ };
+
+ handleSubmit = e => {
e.preventDefault();
const { formValues } = this.state;
- console.log(formValues)
- }
+ const { submitNewAbout } = this.props;
+ return this.setState({ formClicked: true }, () =>
+ submitNewAbout(formValues)
+ );
+ };
handleNameChange = e => {
const value = e.target.value.slice(0);
@@ -104,106 +129,60 @@ class AboutSettings extends Component {
}));
};
- handleTabSelect(key) {
- return this.setState(state => ({
- ...state,
- view: key
- }));
- }
-
- renderEdit() {
+ render() {
const {
formValues: { name, location, picture, about }
} = this.state;
- return (
-