Skip to content

Commit 55a17e9

Browse files
Merge pull request #140 from blackjackkent/AccountDeletion
Adding account deletion feature
2 parents 5dcc2e8 + f3e549e commit 55a17e9

File tree

17 files changed

+414
-353
lines changed

17 files changed

+414
-353
lines changed

package-lock.json

Lines changed: 212 additions & 346 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"jest-when": "^2.3.1",
4747
"mini-css-extract-plugin": "^0.4.5",
4848
"mkdirp": "^0.5.1",
49-
"node-sass": "^4.10.0",
49+
"node-sass": "^4.14.1",
5050
"prettier": "^2.0.2",
5151
"react-test-renderer": "^16.8.6",
5252
"redux-saga-test-plan": "^3.7.0",
@@ -73,9 +73,9 @@
7373
"dot-prop-immutable": "^1.5.0",
7474
"history": "^4.7.2",
7575
"immutable": "^4.0.0-rc.12",
76-
"jquery": "^3.3.1",
76+
"jquery": "^3.5.1",
7777
"local-storage": "^1.4.2",
78-
"lodash": "^4.17.11",
78+
"lodash": "^4.17.20",
7979
"promise": "^8.0.2",
8080
"prop-types": "^15.6.2",
8181
"query-string": "^6.2.0",
@@ -99,7 +99,7 @@
9999
"simple-line-icons": "^2.4.1",
100100
"styled-components": "^4.1.2",
101101
"webpack": "^4.26.1",
102-
"webpack-dev-server": "^3.2.1"
102+
"webpack-dev-server": "^3.11.0"
103103
},
104104
"scripts": {
105105
"start": "webpack-dev-server --history-api-fallback --config webpack.dev.js",

src/display/shared/modals/ModalContainer.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const propTypes = {
2828
closeUpsertCharacterModal: PropTypes.func.isRequired,
2929
closeUpsertPublicViewModal: PropTypes.func.isRequired,
3030
closeUpsertThreadModal: PropTypes.func.isRequired,
31+
closeDeleteAccountConfirmationModal: PropTypes.func.isRequired,
3132
deletePublicView: PropTypes.func.isRequired,
3233
isBulkUntrackThreadsModalOpen: PropTypes.bool.isRequired,
3334
isBulkUpdateTagModalOpen: PropTypes.bool.isRequired,
@@ -38,6 +39,7 @@ const propTypes = {
3839
isUpsertCharacterModalOpen: PropTypes.bool.isRequired,
3940
isUpsertPublicViewModalOpen: PropTypes.bool.isRequired,
4041
isUpsertThreadModalOpen: PropTypes.bool.isRequired,
42+
isDeleteAccountConfirmationModalOpen: PropTypes.bool.isRequired,
4143
sortedCharacters: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
4244
sortedTags: PropTypes.arrayOf(PropTypes.string).isRequired,
4345
threadToEdit: PropTypes.shape({
@@ -48,6 +50,7 @@ const propTypes = {
4850
upsertCharacter: PropTypes.func.isRequired,
4951
upsertPublicView: PropTypes.func.isRequired,
5052
upsertThread: PropTypes.func.isRequired,
53+
submitUserAccountDeletion: PropTypes.func.isRequired,
5154
tagToEdit: PropTypes.shape({
5255
selectedTag: PropTypes.string,
5356
updatedValue: PropTypes.string
@@ -71,6 +74,7 @@ function mapStateToProps(state) {
7174
isDeletePublicViewModalOpen: ui.isDeletePublicViewModalOpen,
7275
isBulkUpdateTagModalOpen: ui.isBulkUpdateTagModalOpen,
7376
isBulkDeleteTagModalOpen: ui.isBulkDeleteTagModalOpen,
77+
isDeleteAccountConfirmationModalOpen: ui.isDeleteAccountConfirmationModalOpen,
7478
characterToEdit,
7579
threadToEdit,
7680
bulkThreadsToEdit,
@@ -97,6 +101,7 @@ const ModalContainer = (props) => {
97101
closeUpsertCharacterModal,
98102
closeUpsertPublicViewModal,
99103
closeUpsertThreadModal,
104+
closeDeleteAccountConfirmationModal,
100105
deletePublicView,
101106
isBulkUntrackThreadsModalOpen,
102107
isBulkUpdateTagModalOpen,
@@ -107,6 +112,7 @@ const ModalContainer = (props) => {
107112
isUpsertCharacterModalOpen,
108113
isUpsertPublicViewModalOpen,
109114
isUpsertThreadModalOpen,
115+
isDeleteAccountConfirmationModalOpen,
110116
sortedCharacters,
111117
sortedTags,
112118
threadToEdit,
@@ -116,7 +122,8 @@ const ModalContainer = (props) => {
116122
upsertPublicView,
117123
upsertThread,
118124
viewToEdit,
119-
tagToEdit
125+
tagToEdit,
126+
submitUserAccountDeletion
120127
} = props;
121128
return (
122129
<div>
@@ -231,6 +238,23 @@ const ModalContainer = (props) => {
231238
</span>
232239
}
233240
/>
241+
<GenericConfirmationModal
242+
isModalOpen={isDeleteAccountConfirmationModalOpen}
243+
submitCallback={submitUserAccountDeletion}
244+
submitButtonText="Confirm Deletion"
245+
closeCallback={closeDeleteAccountConfirmationModal}
246+
closeButtonText="Cancel"
247+
data={null}
248+
headerText="Really Delete Account?"
249+
bodyText={
250+
<span>
251+
Are you sure you want to delete your account?{' '}
252+
<strong>This action cannot be undone.</strong> You will be unable to access
253+
any tracked characters or threads in the future, unless you create a new
254+
account and re-add them.
255+
</span>
256+
}
257+
/>
234258
</div>
235259
);
236260
};
@@ -249,7 +273,9 @@ export default connect(mapStateToProps, {
249273
closeUpsertCharacterModal: actions.closeUpsertCharacterModal,
250274
closeUpsertPublicViewModal: actions.closeUpsertPublicViewModal,
251275
closeUpsertThreadModal: actions.closeUpsertThreadModal,
276+
closeDeleteAccountConfirmationModal: actions.closeDeleteAccountConfirmationModal,
252277
deletePublicView: actions.deletePublicView,
278+
submitUserAccountDeletion: actions.submitUserAccountDeletion,
253279
untrackCharacter: actions.untrackCharacter,
254280
untrackThread: actions.untrackThread,
255281
upsertCharacter: actions.upsertCharacter,

src/display/shared/modals/__tests__/__snapshots__/ModalContainer.spec.js.snap

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,22 @@ exports[`rendering snapshots should render valid snapshot 1`] = `
212212
submitButtonText="Delete Tag"
213213
submitCallback={[MockFunction]}
214214
/>
215+
<GenericConfirmationModal
216+
bodyText={
217+
<span>
218+
Are you sure you want to delete your account?
219+
220+
<strong>
221+
This action cannot be undone.
222+
</strong>
223+
You will be unable to access any tracked characters or threads in the future, unless you create a new account and re-add them.
224+
</span>
225+
}
226+
closeButtonText="Cancel"
227+
data={null}
228+
headerText="Really Delete Account?"
229+
submitButtonText="Confirm Deletion"
230+
/>
215231
</div>
216232
`;
217233

@@ -427,5 +443,21 @@ exports[`rendering snapshots should render valid snapshot with missing character
427443
submitButtonText="Delete Tag"
428444
submitCallback={[MockFunction]}
429445
/>
446+
<GenericConfirmationModal
447+
bodyText={
448+
<span>
449+
Are you sure you want to delete your account?
450+
451+
<strong>
452+
This action cannot be undone.
453+
</strong>
454+
You will be unable to access any tracked characters or threads in the future, unless you create a new account and re-add them.
455+
</span>
456+
}
457+
closeButtonText="Cancel"
458+
data={null}
459+
headerText="Really Delete Account?"
460+
submitButtonText="Confirm Deletion"
461+
/>
430462
</div>
431463
`;

src/display/views/settings/Settings.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
44
import { connect } from 'react-redux';
55
import ChangePasswordPane from './components/ChangePasswordPane';
66
import UpdateAccountInfoPane from './components/UpdateAccountInfoPane';
7+
import DeleteAccountPane from './components/DeleteAccountPane';
78
import * as actions from '../../../infrastructure/actions';
89
import TabContent from '../../shared/styled/TabContent';
910
import StaticTabNav from '../../shared/static/StaticTabNav';
@@ -14,6 +15,7 @@ const propTypes = {
1415
user: PropTypes.shape({}).isRequired,
1516
submitUserChangePassword: PropTypes.func.isRequired,
1617
submitUserAccountInfo: PropTypes.func.isRequired,
18+
openDeleteAccountConfirmationModal: PropTypes.func.isRequired,
1719
match: PropTypes.shape({
1820
url: PropTypes.string,
1921
params: PropTypes.shape({
@@ -32,6 +34,10 @@ function mapStateToProps(state) {
3234
const Settings = (props) => {
3335
const { user, submitUserChangePassword, submitUserAccountInfo, match } = props;
3436
const options = Object.values(tabs.SETTINGS);
37+
const onDeleteAccountClicked = (e) => {
38+
e.preventDefault();
39+
props.openDeleteAccountConfirmationModal();
40+
};
3541
return (
3642
<div className="animated fadeIn static-container settings-container">
3743
<Row>
@@ -54,6 +60,7 @@ const Settings = (props) => {
5460
submitAccountInfoForm={submitUserAccountInfo}
5561
user={user}
5662
/>
63+
<DeleteAccountPane onDeleteAccountClicked={onDeleteAccountClicked} />
5764
</TabContent>
5865
</Col>
5966
</Row>
@@ -64,5 +71,6 @@ const Settings = (props) => {
6471
Settings.propTypes = propTypes;
6572
export default connect(mapStateToProps, {
6673
submitUserChangePassword: actions.submitUserChangePassword,
67-
submitUserAccountInfo: actions.submitUserAccountInfo
74+
submitUserAccountInfo: actions.submitUserAccountInfo,
75+
openDeleteAccountConfirmationModal: actions.openDeleteAccountConfirmationModal
6876
})(Settings);

src/display/views/settings/__tests__/__snapshots__/Settings.spec.js.snap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ exports[`rendering snapshots should render valid snapshot 1`] = `
9999
}
100100
}
101101
/>
102+
<DeleteAccountPane
103+
onDeleteAccountClicked={[Function]}
104+
/>
102105
</Styled(TabContent)>
103106
</Col>
104107
</Row>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { TabPane, Button, CardHeader, CardBody } from 'reactstrap';
4+
import Card from '../../../shared/styled/Card';
5+
6+
const propTypes = {
7+
onDeleteAccountClicked: PropTypes.func.isRequired
8+
};
9+
const DeleteAccountPane = ({ onDeleteAccountClicked }) => {
10+
return (
11+
<TabPane tabId="delete-account">
12+
<Card>
13+
<CardHeader>
14+
<i className="fas fa-trash-alt" /> Delete Account
15+
</CardHeader>
16+
<CardBody className="card-body text-center">
17+
<Button type="submit" color="danger" onClick={onDeleteAccountClicked}>
18+
Delete Account
19+
</Button>
20+
</CardBody>
21+
</Card>
22+
</TabPane>
23+
);
24+
};
25+
DeleteAccountPane.propTypes = propTypes;
26+
export default DeleteAccountPane;

src/infrastructure/actions/index.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ export {
1111
OPEN_DELETE_PUBLIC_VIEW_MODAL,
1212
openDeletePublicViewModal
1313
} from './ui/deletePublicViewModal';
14+
export {
15+
CLOSE_DELETE_ACCOUNT_CONFIRMATION_MODAL,
16+
closeDeleteAccountConfirmationModal,
17+
OPEN_DELETE_ACCOUNT_CONFIRMATION_MODAL,
18+
openDeleteAccountConfirmationModal
19+
} from './ui/deleteAccountConfirmationModal';
1420
export {
1521
CLOSE_UNTRACK_CHARACTER_MODAL,
1622
closeUntrackCharacterModal,
@@ -197,6 +203,14 @@ export {
197203
submitUserChangePasswordFailure,
198204
submitUserChangePasswordSuccess
199205
} from './user/submitUserChangePassword';
206+
export {
207+
SUBMIT_USER_ACCOUNT_DELETION,
208+
SUBMIT_USER_ACCOUNT_DELETION_FAILURE,
209+
SUBMIT_USER_ACCOUNT_DELETION_SUCCESS,
210+
submitUserAccountDeletion,
211+
submitUserAccountDeletionFailure,
212+
submitUserAccountDeletionSuccess
213+
} from './user/submitUserAccountDeletion';
200214
export {
201215
SUBMIT_USER_FORGOT_PASSWORD_FAILURE,
202216
SUBMIT_USER_FORGOT_PASSWORD_SUCCESS,
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export const CLOSE_DELETE_ACCOUNT_CONFIRMATION_MODAL = 'CLOSE_DELETE_ACCOUNT_CONFIRMATION_MODAL';
2+
export function closeDeleteAccountConfirmationModal() {
3+
return {
4+
type: CLOSE_DELETE_ACCOUNT_CONFIRMATION_MODAL
5+
};
6+
}
7+
export const OPEN_DELETE_ACCOUNT_CONFIRMATION_MODAL = 'OPEN_DELETE_ACCOUNT_CONFIRMATION_MODAL';
8+
export function openDeleteAccountConfirmationModal() {
9+
return {
10+
type: OPEN_DELETE_ACCOUNT_CONFIRMATION_MODAL
11+
};
12+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import analytics from '../../constants/analytics';
2+
3+
export const SUBMIT_USER_ACCOUNT_DELETION = 'SUBMIT_USER_ACCOUNT_DELETION';
4+
export function submitUserAccountDeletion() {
5+
return {
6+
type: SUBMIT_USER_ACCOUNT_DELETION,
7+
analytics: {
8+
func: analytics.funcs.EVENT,
9+
event: {
10+
category: analytics.categories.ACCOUNT,
11+
action: 'Deleted account'
12+
}
13+
}
14+
};
15+
}
16+
export const SUBMIT_USER_ACCOUNT_DELETION_FAILURE = 'SUBMIT_USER_ACCOUNT_DELETION_FAILURE';
17+
export function submitUserAccountDeletionFailure(data) {
18+
return {
19+
type: SUBMIT_USER_ACCOUNT_DELETION_FAILURE,
20+
data
21+
};
22+
}
23+
export const SUBMIT_USER_ACCOUNT_DELETION_SUCCESS = 'SUBMIT_USER_ACCOUNT_DELETION_SUCCESS';
24+
export function submitUserAccountDeletionSuccess() {
25+
return {
26+
type: SUBMIT_USER_ACCOUNT_DELETION_SUCCESS
27+
};
28+
}

0 commit comments

Comments
 (0)