diff --git a/server/boot/settings.js b/server/boot/settings.js
index f2d67628f4..64b695fab3 100644
--- a/server/boot/settings.js
+++ b/server/boot/settings.js
@@ -1,8 +1,5 @@
import { check } from 'express-validator/check';
-import {
- ifNoUser401,
- createValidatorErrorHandler
-} from '../utils/middleware';
+import { ifNoUser401, createValidatorErrorHandler } from '../utils/middleware';
import { themes } from '../../common/utils/themes.js';
import { alertTypes } from '../../common/utils/flash.js';
@@ -10,25 +7,22 @@ export default function settingsController(app) {
const api = app.loopback.Router();
const toggleUserFlag = (flag, req, res, next) => {
const { user } = req;
- const currentValue = user[ flag ];
- return user
- .update$({ [ flag ]: !currentValue })
- .subscribe(
- () => res.status(200).json({
+ const currentValue = user[flag];
+ return user.update$({ [flag]: !currentValue }).subscribe(
+ () =>
+ res.status(200).json({
flag,
value: !currentValue
}),
- next
- );
+ next
+ );
};
function refetchCompletedChallenges(req, res, next) {
const { user } = req;
- return user.requestCompletedChallenges()
- .subscribe(
- completedChallenges => res.json({ completedChallenges }),
- next
- );
+ return user
+ .requestCompletedChallenges()
+ .subscribe(completedChallenges => res.json({ completedChallenges }), next);
}
const updateMyEmailValidators = [
@@ -38,12 +32,13 @@ export default function settingsController(app) {
];
function updateMyEmail(req, res, next) {
- const { user, body: { email } } = req;
- return user.requestUpdateEmail(email)
- .subscribe(
- message => res.json({ message }),
- next
- );
+ const {
+ user,
+ body: { email }
+ } = req;
+ return user
+ .requestUpdateEmail(email)
+ .subscribe(message => res.json({ message }), next);
}
const updateMyCurrentChallengeValidators = [
@@ -53,48 +48,52 @@ export default function settingsController(app) {
];
function updateMyCurrentChallenge(req, res, next) {
- const { user, body: { currentChallengeId } } = req;
+ const {
+ user,
+ body: { currentChallengeId }
+ } = req;
return user.update$({ currentChallengeId }).subscribe(
- () => res.json({
- message:
- `your current challenge has been updated to ${currentChallengeId}`
- }),
+ () =>
+ res.json({
+ message: `your current challenge has been updated to ${currentChallengeId}`
+ }),
next
);
}
const updateMyThemeValidators = [
check('theme')
- .isIn(Object.keys(themes))
- .withMessage('Theme is invalid.')
+ .isIn(Object.keys(themes))
+ .withMessage('Theme is invalid.')
];
function updateMyTheme(req, res, next) {
- const { body: { theme } } = req;
+ const {
+ body: { theme }
+ } = req;
if (req.user.theme === theme) {
return res.sendFlash(alertTypes.info, 'Theme already set');
}
- return req.user.updateTheme(theme)
- .then(
- () => res.sendFlash(alertTypes.info, 'Your theme has been updated'),
- next
- );
+ return req.user
+ .updateTheme(theme)
+ .then(
+ () => res.sendFlash(alertTypes.info, 'Your theme has been updated'),
+ next
+ );
}
function updateFlags(req, res, next) {
- const { user, body: { values } } = req;
+ const {
+ user,
+ body: { values }
+ } = req;
const keys = Object.keys(values);
- if (
- keys.length === 1 &&
- typeof keys[0] === 'boolean'
- ) {
+ 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
- );
+ return user
+ .requestUpdateFlags(values)
+ .subscribe(message => res.json({ message }), next);
}
function updateMyPortfolio(req, res, next) {
@@ -106,23 +105,19 @@ export default function settingsController(app) {
// user cannot send only one key to this route
// other than to remove a portfolio item
const requestDelete = Object.keys(portfolio).length === 1;
- return user.updateMyPortfolio(portfolio, requestDelete)
- .subscribe(
- message => res.json({ message }),
- next
- );
- }
+ return user
+ .updateMyPortfolio(portfolio, requestDelete)
+ .subscribe(message => res.json({ message }), next);
+ }
function updateMyProfileUI(req, res, next) {
const {
user,
body: { profileUI }
} = req;
- return user.updateMyProfileUI(profileUI)
- .subscribe(
- message => res.json({ message }),
- next
- );
+ return user
+ .updateMyProfileUI(profileUI)
+ .subscribe(message => res.json({ message }), next);
}
function updateMyProjects(req, res, next) {
@@ -130,62 +125,56 @@ export default function settingsController(app) {
user,
body: { projects: project }
} = req;
- return user.updateMyProjects(project)
- .subscribe(
- message => res.json({ message }),
- next
- );
+ return user
+ .updateMyProjects(project)
+ .subscribe(message => res.json({ message }), next);
}
function updateMyUsername(req, res, next) {
- const { user, body: { username } } = req;
- return user.updateMyUsername(username)
- .subscribe(
- message => res.json({ message }),
- next
- );
- }
-
- const updatePrivacyTerms = (req, res, next) => {
const {
user,
- body: { quincyemails }
+ body: { username }
+ } = req;
+ return user
+ .updateMyUsername(username)
+ .subscribe(message => res.json({ message }), next);
+ }
+
+ const updatePrivacyTerms = (req, res) => {
+ const {
+ user,
+ body: { quincyEmails }
} = req;
const update = {
acceptedPrivacyTerms: true,
- sendQuincyEmail: !!quincyemails
+ sendQuincyEmail: !!quincyEmails
};
- return user.update$(update)
- .do(() => {
- req.user = Object.assign(req.user, update);
- })
- .subscribe(
- () => {
- res.status(200).json({
- message: 'We have updated your preferences. ' +
- 'You can now continue using freeCodeCamp.'
- });
- },
- next
- );
+ return user.updateAttributes(update, err => {
+ if (err) {
+ return res.status(500).json({
+ type: 'warning',
+ message:
+ 'Something went wrong updating your preferences. ' +
+ 'Please try again.'
+ });
+ }
+ return res.status(200).json({
+ type: 'success',
+ message:
+ 'We have updated your preferences. ' +
+ 'You can now continue using freeCodeCamp.'
+ });
+ });
};
- api.post(
- '/update-privacy-terms',
- ifNoUser401,
- updatePrivacyTerms
- );
+ api.put('/update-privacy-terms', ifNoUser401, updatePrivacyTerms);
api.post(
'/refetch-user-completed-challenges',
ifNoUser401,
refetchCompletedChallenges
);
- api.post(
- '/update-flags',
- ifNoUser401,
- updateFlags
- );
+ api.post('/update-flags', ifNoUser401, updateFlags);
api.post(
'/update-my-email',
ifNoUser401,
@@ -207,21 +196,9 @@ export default function settingsController(app) {
createValidatorErrorHandler(alertTypes.danger),
updateMyCurrentChallenge
);
- api.post(
- '/update-my-portfolio',
- ifNoUser401,
- updateMyPortfolio
- );
- api.post(
- '/update-my-profile-ui',
- ifNoUser401,
- updateMyProfileUI
- );
- api.post(
- '/update-my-projects',
- ifNoUser401,
- updateMyProjects
- );
+ api.post('/update-my-portfolio', ifNoUser401, updateMyPortfolio);
+ api.post('/update-my-profile-ui', ifNoUser401, updateMyProfileUI);
+ api.post('/update-my-projects', ifNoUser401, updateMyProjects);
api.post(
'/update-my-theme',
ifNoUser401,
@@ -229,11 +206,8 @@ export default function settingsController(app) {
createValidatorErrorHandler(alertTypes.danger),
updateMyTheme
);
- api.post(
- '/update-my-username',
- ifNoUser401,
- updateMyUsername
- );
+ api.post('/update-my-username', ifNoUser401, updateMyUsername);
+ app.use('/external', api);
app.use(api);
}
diff --git a/src/components/Flash/flash.css b/src/components/Flash/flash.css
new file mode 100644
index 0000000000..5cdb916d0a
--- /dev/null
+++ b/src/components/Flash/flash.css
@@ -0,0 +1,6 @@
+.flash-message {
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ flex-direction: row-reverse;
+}
diff --git a/src/components/Flash/index.js b/src/components/Flash/index.js
new file mode 100644
index 0000000000..13917ad679
--- /dev/null
+++ b/src/components/Flash/index.js
@@ -0,0 +1,36 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { Alert } from 'react-bootstrap';
+
+import './flash.css';
+
+function createDismissHandler(fn, id) {
+ return () => fn(id);
+}
+
+function Flash({ messages, onClose }) {
+ return messages.map(({ type, message, id }) => (
+
Welcome to page 2
- Go back to the homepage -