diff --git a/api-server/server/boot/settings.js b/api-server/server/boot/settings.js
index b2911bedef..87e6e9c4ca 100644
--- a/api-server/server/boot/settings.js
+++ b/api-server/server/boot/settings.js
@@ -19,14 +19,6 @@ export default function settingsController(app) {
ifNoUser401,
refetchCompletedChallenges
);
- api.post('/update-flags', ifNoUser401, updateFlags);
- api.put(
- '/update-my-email',
- ifNoUser401,
- updateMyEmailValidators,
- createValidatorErrorHandler(alertTypes.danger),
- updateMyEmail
- );
api.post(
'/update-my-current-challenge',
ifNoUser401,
@@ -51,8 +43,16 @@ export default function settingsController(app) {
createValidatorErrorHandler(alertTypes.danger),
updateMyTheme
);
+ api.put(
+ '/update-my-email',
+ ifNoUser401,
+ updateMyEmailValidators,
+ createValidatorErrorHandler(alertTypes.danger),
+ updateMyEmail
+ );
api.put('/update-my-about', ifNoUser401, updateMyAbout);
api.put('/update-my-username', ifNoUser401, updateMyUsername);
+ api.put('/update-user-flag', ifNoUser401, updateUserFlag);
app.use('/internal', api);
app.use(api);
@@ -69,19 +69,6 @@ const standardSuccessMessage = {
message: 'We have updated your preferences'
};
-const toggleUserFlag = (flag, req, res, next) => {
- const { user } = req;
- const currentValue = user[flag];
- return user.update$({ [flag]: !currentValue }).subscribe(
- () =>
- res.status(200).json({
- flag,
- value: !currentValue
- }),
- next
- );
-};
-
function refetchCompletedChallenges(req, res, next) {
const { user } = req;
return user
@@ -142,20 +129,6 @@ function updateMyTheme(req, res, next) {
);
}
-function updateFlags(req, res, next) {
- const {
- user,
- body: { values }
- } = req;
- const keys = Object.keys(values);
- if (keys.length === 1 && typeof keys[0] === 'boolean') {
- return toggleUserFlag(keys[0], req, res, next);
- }
- return user
- .requestUpdateFlags(values)
- .subscribe(message => res.json({ message }), next);
-}
-
function updateMyPortfolio(req, res, next) {
const {
user,
@@ -195,7 +168,7 @@ function updateMyAbout(req, res, next) {
user,
body: { name, location, about, picture }
} = req;
- log(name, location, picture, about)
+ log(name, location, picture, about);
return user.updateAttributes({ name, location, about, picture }, err => {
if (err) {
res.status(500).json(standardErrorMessage);
@@ -240,7 +213,7 @@ function createUpdateMyUsername(app) {
};
}
-const updatePrivacyTerms = (req, res) => {
+const updatePrivacyTerms = (req, res, next) => {
const {
user,
body: { quincyEmails }
@@ -251,7 +224,8 @@ const updatePrivacyTerms = (req, res) => {
};
return user.updateAttributes(update, err => {
if (err) {
- return res.status(500).json(standardErrorMessage);
+ res.status(500).json(standardErrorMessage);
+ return next(err);
}
return res.status(200).json({
type: 'success',
@@ -261,3 +235,14 @@ const updatePrivacyTerms = (req, res) => {
});
});
};
+
+function updateUserFlag(req, res, next) {
+ const { user, body: update } = req;
+ user.updateAttributes(update, err => {
+ if (err) {
+ res.status(500).json(standardErrorMessage);
+ return next(err);
+ }
+ return res.status(200).json(standardSuccessMessage);
+ });
+}
diff --git a/client/src/client-only-routes/ShowSettings.js b/client/src/client-only-routes/ShowSettings.js
index 94b49fd9d7..962cef94e7 100644
--- a/client/src/client-only-routes/ShowSettings.js
+++ b/client/src/client-only-routes/ShowSettings.js
@@ -6,7 +6,7 @@ import { createSelector } from 'reselect';
import { Grid, Button } from '@freecodecamp/react-bootstrap';
import { signInLoadingSelector, userSelector } from '../redux';
-import { submitNewAbout } from '../redux/settings';
+import { submitNewAbout, updateUserFlag } from '../redux/settings';
import Layout from '../components/Layout';
import Spacer from '../components/helpers/Spacer';
@@ -23,6 +23,7 @@ const propTypes = {
showLoading: PropTypes.bool,
submitNewAbout: PropTypes.func.isRequired,
theme: PropTypes.string,
+ toggleNightMode: PropTypes.func.isRequired,
username: PropTypes.string
};
@@ -45,7 +46,10 @@ const mapStateToProps = createSelector(
);
const mapDispatchToProps = dispatch =>
- bindActionCreators({ submitNewAbout }, dispatch);
+ bindActionCreators(
+ { submitNewAbout, toggleNightMode: theme => updateUserFlag({theme}) },
+ dispatch
+ );
function ShowSettings(props) {
const {
@@ -57,7 +61,8 @@ function ShowSettings(props) {
theme,
location,
name,
- submitNewAbout
+ submitNewAbout,
+ toggleNightMode
} = props;
if (showLoading) {
@@ -104,6 +109,7 @@ function ShowSettings(props) {
picture={picture}
points={points}
submitNewAbout={submitNewAbout}
+ toggleNightMode={toggleNightMode}
username={username}
/>
diff --git a/client/src/components/settings/About.js b/client/src/components/settings/About.js
index 59ca790dfe..d4d79b7b05 100644
--- a/client/src/components/settings/About.js
+++ b/client/src/components/settings/About.js
@@ -19,6 +19,7 @@ const propTypes = {
picture: PropTypes.string,
points: PropTypes.number,
submitNewAbout: PropTypes.func.isRequired,
+ toggleNightMode: PropTypes.func.isRequired,
username: PropTypes.string
};
@@ -124,8 +125,7 @@ class AboutSettings extends Component {
const {
formValues: { name, location, picture, about }
} = this.state;
- const { currentTheme, username } = this.props;
- const toggleTheme = () => {};
+ const { currentTheme, username, toggleNightMode } = this.props;
return (
@@ -180,7 +180,7 @@ class AboutSettings extends Component {
diff --git a/client/src/components/settings/Theme.js b/client/src/components/settings/Theme.js
index adf6975103..32d88a4d2e 100644
--- a/client/src/components/settings/Theme.js
+++ b/client/src/components/settings/Theme.js
@@ -19,7 +19,9 @@ export default function ThemeSettings({ currentTheme, toggleNightMode }) {
toggleNightMode(currentTheme)}
+ onChange={() =>
+ toggleNightMode(currentTheme === 'night' ? 'default' : 'night')
+ }
value={currentTheme === 'night'}
/>
diff --git a/client/src/redux/index.js b/client/src/redux/index.js
index 4e26ca7895..f7c18f58a9 100644
--- a/client/src/redux/index.js
+++ b/client/src/redux/index.js
@@ -161,17 +161,32 @@ export const reducer = handleActions(
}
}
: state,
- [settingsTypes.submitNewAboutComplete]: (state, {payload}) => payload ? {
- ...state,
- user: {
- ...state.user,
- [state.appUsername]: {
- ...state.user[state.appUsername],
- ...payload
- }
- }
- }
- : state
+ [settingsTypes.submitNewAboutComplete]: (state, { payload }) =>
+ payload
+ ? {
+ ...state,
+ user: {
+ ...state.user,
+ [state.appUsername]: {
+ ...state.user[state.appUsername],
+ ...payload
+ }
+ }
+ }
+ : state,
+ [settingsTypes.updateUserFlagComplete]: (state, { payload }) =>
+ payload
+ ? {
+ ...state,
+ user: {
+ ...state.user,
+ [state.appUsername]: {
+ ...state.user[state.appUsername],
+ ...payload
+ }
+ }
+ }
+ : state
},
initialState
);
diff --git a/client/src/redux/settings/index.js b/client/src/redux/settings/index.js
index 69b50f8e1c..41f2dd3706 100644
--- a/client/src/redux/settings/index.js
+++ b/client/src/redux/settings/index.js
@@ -23,17 +23,20 @@ export const types = createTypes(
[
...createAsyncTypes('validateUsername'),
...createAsyncTypes('submitNewAbout'),
- ...createAsyncTypes('submitNewUsername')
+ ...createAsyncTypes('submitNewUsername'),
+ ...createAsyncTypes('updateUserFlag')
],
ns
);
+const checkForSuccessPayload = ({ type, payload }) =>
+ type === 'success' ? payload : null;
export const sagas = [...createSettingsSagas(types)];
export const submitNewAbout = createAction(types.submitNewAbout);
export const submitNewAboutComplete = createAction(
types.submitNewAboutComplete,
- ({ type, payload }) => (type === 'success' ? payload : null)
+ checkForSuccessPayload
);
export const submitNewAboutError = createAction(types.submitNewAboutError);
@@ -46,6 +49,13 @@ export const submitNewUsernameError = createAction(
types.submitNewUsernameError
);
+export const updateUserFlag = createAction(types.updateUserFlag);
+export const updateUserFlagComplete = createAction(
+ types.updateUserFlagComplete,
+ checkForSuccessPayload
+);
+export const updateUserFlagError = createAction(types.updateUserFlagError);
+
export const validateUsername = createAction(types.validateUsername);
export const validateUsernameComplete = createAction(
types.validateUsernameComplete
diff --git a/client/src/redux/settings/settings-sagas.js b/client/src/redux/settings/settings-sagas.js
index 6488a92ce7..3cf07c98e3 100644
--- a/client/src/redux/settings/settings-sagas.js
+++ b/client/src/redux/settings/settings-sagas.js
@@ -1,7 +1,9 @@
import { delay } from 'redux-saga';
-import { call, put, takeLatest } from 'redux-saga/effects';
+import { call, put, takeLatest, takeEvery } from 'redux-saga/effects';
import {
+ updateUserFlagComplete,
+ updateUserFlagError,
validateUsernameComplete,
validateUsernameError,
submitNewAboutComplete,
@@ -12,7 +14,8 @@ import {
import {
getUsernameExists,
putUpdateMyAbout,
- putUpdateMyUsername
+ putUpdateMyUsername,
+ putUpdateUserFlag
} from '../../utils/ajax';
import { createFlashMessage } from '../../components/Flash/redux';
@@ -36,6 +39,16 @@ function* submitNewUsernameSaga({ payload: username }) {
}
}
+function* updateUserFlagSaga({ payload: update }) {
+ try {
+ const { data: response } = yield call(putUpdateUserFlag, update);
+ yield put(updateUserFlagComplete({ ...response, payload: update }));
+ yield put(createFlashMessage(response));
+ } catch (e) {
+ yield put(updateUserFlagError(e));
+ }
+}
+
function* validateUsernameSaga({ payload }) {
try {
yield delay(500);
@@ -50,6 +63,7 @@ function* validateUsernameSaga({ payload }) {
export function createSettingsSagas(types) {
return [
+ takeEvery(types.updateUserFlag, updateUserFlagSaga),
takeLatest(types.submitNewAbout, submitNewAboutSaga),
takeLatest(types.submitNewUsername, submitNewUsernameSaga),
takeLatest(types.validateUsername, validateUsernameSaga)
diff --git a/client/src/utils/ajax.js b/client/src/utils/ajax.js
index b12a3121d5..841c7b41d1 100644
--- a/client/src/utils/ajax.js
+++ b/client/src/utils/ajax.js
@@ -48,6 +48,10 @@ export function putUpdateMyUsername(username) {
return put('/update-my-username', { username });
}
+export function putUpdateUserFlag(update) {
+ return put('/update-user-flag', update);
+}
+
export function putUserAcceptsTerms(quincyEmails) {
return put('/update-privacy-terms', { quincyEmails });
}