Fix(settings): Add separate delete page
This commit is contained in:
@ -8,7 +8,6 @@ import {
|
||||
reducer as challengesApp,
|
||||
projectNormalizer
|
||||
} from './routes/challenges/redux';
|
||||
import { reducer as settingsApp } from './routes/settings/redux';
|
||||
|
||||
export default function createReducer(sideReducers = {}) {
|
||||
return combineReducers({
|
||||
@ -17,7 +16,6 @@ export default function createReducer(sideReducers = {}) {
|
||||
app,
|
||||
toasts,
|
||||
challengesApp,
|
||||
settingsApp,
|
||||
form: formReducer.normalize({ ...projectNormalizer })
|
||||
});
|
||||
}
|
||||
|
@ -1,61 +0,0 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import { Modal, Button } from 'react-bootstrap';
|
||||
|
||||
export default function DeleteModal({ isOpen }) {
|
||||
return (
|
||||
<div>
|
||||
<Button
|
||||
block={ true }
|
||||
bsSize='lg'
|
||||
bsStyle='danger'
|
||||
className='btn-link-social'
|
||||
>
|
||||
Delete my Free Code Camp account
|
||||
</Button>
|
||||
<Modal
|
||||
backdrop={ true }
|
||||
show={ isOpen }
|
||||
>
|
||||
<Modal.Header>
|
||||
<h3>You don't really want to delete your account, do you?</h3>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<p>
|
||||
This will really delete all your data, including
|
||||
all your progress and brownie points.
|
||||
</p>
|
||||
<p>
|
||||
We won't be able to recover any of it for you later,
|
||||
even if you change your mind.
|
||||
</p>
|
||||
<p>
|
||||
If there's something we could do better, send
|
||||
us an email instead and we'll do our best:  
|
||||
<a href='mailto:team@freecodecamp.com'>
|
||||
team@freecodecamp.com
|
||||
</a>.
|
||||
</p>
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button
|
||||
block={ true }
|
||||
bsStyle='success'
|
||||
>
|
||||
Nevermind, I don't want to delete all of my progress
|
||||
</Button>
|
||||
<div className='spacer' />
|
||||
<Button
|
||||
block={ true }
|
||||
bsStyle='danger'
|
||||
>
|
||||
I am 100% sure I want to delete my account and all of my progress
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
DeleteModal.propTypes = {
|
||||
isOpen: PropTypes.bool
|
||||
};
|
@ -7,23 +7,13 @@ import LockedSettings from './Locked-Settings.jsx';
|
||||
import SocialSettings from './Social-Settings.jsx';
|
||||
import EmailSettings from './Email-Setting.jsx';
|
||||
import LangaugeSettings from './Language-Settings.jsx';
|
||||
import DeleteModal from './Delete-Modal.jsx';
|
||||
|
||||
import {
|
||||
toggleUserFlag,
|
||||
openDeleteModal,
|
||||
hideDeleteModal
|
||||
} from '../redux/actions';
|
||||
import {
|
||||
toggleNightMode,
|
||||
updateTitle
|
||||
} from '../../../redux/actions';
|
||||
import { toggleUserFlag } from '../redux/actions';
|
||||
import { toggleNightMode, updateTitle } from '../../../redux/actions';
|
||||
|
||||
const actions = {
|
||||
updateTitle,
|
||||
toggleNightMode,
|
||||
openDeleteModal,
|
||||
hideDeleteModal,
|
||||
toggleIsLocked: () => toggleUserFlag('isLocked'),
|
||||
toggleQuincyEmail: () => toggleUserFlag('sendQuincyEmail'),
|
||||
toggleNotificationEmail: () => toggleUserFlag('sendNotificationEmail'),
|
||||
@ -33,8 +23,7 @@ const actions = {
|
||||
const mapStateToProps = state => {
|
||||
const {
|
||||
app: { user: username },
|
||||
entities: { user: userMap },
|
||||
settingsApp: { isDeleteOpen }
|
||||
entities: { user: userMap }
|
||||
} = state;
|
||||
const {
|
||||
email,
|
||||
@ -49,7 +38,6 @@ const mapStateToProps = state => {
|
||||
return {
|
||||
username,
|
||||
email,
|
||||
isDeleteOpen,
|
||||
isLocked,
|
||||
isGithubCool,
|
||||
isTwitter,
|
||||
@ -69,7 +57,6 @@ export class Settings extends React.Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.element,
|
||||
username: PropTypes.string,
|
||||
isDeleteOpen: PropTypes.bool,
|
||||
isLocked: PropTypes.bool,
|
||||
isGithubCool: PropTypes.bool,
|
||||
isTwitter: PropTypes.bool,
|
||||
@ -84,8 +71,6 @@ export class Settings extends React.Component {
|
||||
toggleQuincyEmail: PropTypes.func.isRequired,
|
||||
toggleMonthlyEmail: PropTypes.func.isRequired,
|
||||
toggleNotificationEmail: PropTypes.func.isRequired,
|
||||
openDeleteModal: PropTypes.func.isRequired,
|
||||
hideDeleteModal: PropTypes.func.isRequired,
|
||||
lang: PropTypes.string,
|
||||
initialLang: PropTypes.string,
|
||||
updateMyLang: PropTypes.func
|
||||
@ -105,7 +90,6 @@ export class Settings extends React.Component {
|
||||
const {
|
||||
children,
|
||||
username,
|
||||
isDeleteOpen,
|
||||
isLocked,
|
||||
isGithubCool,
|
||||
isTwitter,
|
||||
@ -118,9 +102,7 @@ export class Settings extends React.Component {
|
||||
toggleIsLocked,
|
||||
toggleQuincyEmail,
|
||||
toggleMonthlyEmail,
|
||||
toggleNotificationEmail,
|
||||
openDeleteModal,
|
||||
hideDeleteModal
|
||||
toggleNotificationEmail
|
||||
} = this.props;
|
||||
if (children) {
|
||||
return (
|
||||
@ -267,11 +249,15 @@ export class Settings extends React.Component {
|
||||
smOffset={ 2 }
|
||||
xs={ 12 }
|
||||
>
|
||||
<DeleteModal
|
||||
hide={ hideDeleteModal }
|
||||
isOpen={ isDeleteOpen }
|
||||
open={ openDeleteModal }
|
||||
/>
|
||||
<Button
|
||||
block={ true }
|
||||
bsSize='lg'
|
||||
bsStyle='danger'
|
||||
className='btn-link-social'
|
||||
href='/delete-my-account'
|
||||
>
|
||||
Delete my Free Code Camp account
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
@ -1,37 +1,16 @@
|
||||
import { createAction, handleActions } from 'redux-actions';
|
||||
import { createAction } from 'redux-actions';
|
||||
|
||||
import createTypes from '../../../utils/create-types';
|
||||
|
||||
const initialState = {
|
||||
showDeleteModal: false
|
||||
};
|
||||
export const types = createTypes([
|
||||
'toggleUserFlag',
|
||||
'openDeleteModal',
|
||||
'hideDeleteModal',
|
||||
'updateMyEmail',
|
||||
'updateMyLang'
|
||||
], 'settings');
|
||||
|
||||
export const toggleUserFlag = createAction(types.toggleUserFlag);
|
||||
export const openDeleteModal = createAction(types.openDeleteModal);
|
||||
export const hideDeleteModal = createAction(types.hideDeleteModal);
|
||||
export const updateMyEmail = createAction(types.updateMyEmail);
|
||||
export const updateMyLang = createAction(
|
||||
types.updateMyLang,
|
||||
(values) => values.lang
|
||||
);
|
||||
|
||||
export default handleActions(
|
||||
{
|
||||
[openDeleteModal]: state => ({
|
||||
...state,
|
||||
isDeleteOpen: true
|
||||
}),
|
||||
[hideDeleteModal]: state => ({
|
||||
...state,
|
||||
isDeleteOpen: false
|
||||
})
|
||||
},
|
||||
initialState
|
||||
);
|
||||
|
@ -2,7 +2,6 @@ import userUpdateSaga from './update-user-saga';
|
||||
|
||||
export { types } from './actions';
|
||||
export * as actions from './actions';
|
||||
export { default as reducer } from './actions';
|
||||
|
||||
export const sagas = [
|
||||
userUpdateSaga
|
||||
|
@ -167,6 +167,7 @@ module.exports = function(app) {
|
||||
router.get('/email-signin', getEmailSignin);
|
||||
router.get('/deprecated-signin', getDepSignin);
|
||||
router.get('/update-email', getUpdateEmail);
|
||||
router.get('/delete-my-account', showDelete);
|
||||
api.post(
|
||||
'/account/delete',
|
||||
ifNoUser401,
|
||||
@ -431,6 +432,10 @@ module.exports = function(app) {
|
||||
);
|
||||
}
|
||||
|
||||
function showDelete(req, res) {
|
||||
return res.render('account/delete', { title: 'Delete My Account!' });
|
||||
}
|
||||
|
||||
function postDeleteAccount(req, res, next) {
|
||||
User.destroyById(req.user.id, function(err) {
|
||||
if (err) { return next(err); }
|
||||
|
28
server/views/account/delete.jade
Normal file
28
server/views/account/delete.jade
Normal file
@ -0,0 +1,28 @@
|
||||
extends ../layout
|
||||
block content
|
||||
include ../partials/flyer
|
||||
#modal-dialog.modal.animated.wobble
|
||||
.modal-dialog
|
||||
.modal-content
|
||||
.modal-header
|
||||
a.close(href='#', data-dismiss='modal', aria-hidden='true') ×
|
||||
h3 You don't really want to delete your account, do you?
|
||||
.modal-body
|
||||
p This will really delete all your data, including all your progress and brownie points.
|
||||
p We won't be able to recover any of it for you later, even if you change your mind.
|
||||
p If there's something we could do better, send us an email instead and we'll do our best:  
|
||||
a(href="mailto:team@freecodecamp.com") team@freecodecamp.com
|
||||
| .
|
||||
.modal-footer
|
||||
a.btn.btn-success.btn-block(href='/map', data-dismiss='modal', aria-hidden='true')
|
||||
| Nevermind, I don't want to delete all of my progress
|
||||
.spacer
|
||||
form(action='/account/delete', method='POST')
|
||||
input(type='hidden', name='_csrf', value=_csrf)
|
||||
button.btn.btn-danger.btn-block(type='submit')
|
||||
| I am 100% sure I want to delete my account and all of my progress
|
||||
script.
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const modal$ = document.getElementById('modal-dialog');
|
||||
modal$.classList.add('show');
|
||||
});
|
Reference in New Issue
Block a user