mirror of
https://github.com/wassname/talk.git
synced 2026-08-11 11:27:10 +08:00
Moving gdpr to talk-plugin-profile-data
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
.container {
|
||||
border: 1px solid #f26563;
|
||||
border-radius: 2px;
|
||||
color: #3b4a53;
|
||||
padding: 20px 10px;
|
||||
background-color: rgba(242, 101, 99, 0.1);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.button {
|
||||
color: #787D80;
|
||||
border-radius: 2px;
|
||||
background-color: transparent;
|
||||
height: 30px;
|
||||
font-size: 0.9em;
|
||||
line-height: normal;
|
||||
|
||||
&:hover {
|
||||
background-color: #eaeaea;
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
background-color: #787D80;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
i.icon {
|
||||
font-size: 1em;
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
margin: 0;
|
||||
padding-left: 22px;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
text-align: center;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import { Button, Icon } from 'plugin-api/beta/client/components/ui';
|
||||
import styles from './AccountDeletionRequestedSign.css';
|
||||
import { getErrorMessages } from 'coral-framework/utils';
|
||||
|
||||
class AccountDeletionRequestedSign extends React.Component {
|
||||
cancelAccountDeletion = async () => {
|
||||
const { cancelAccountDeletion, notify } = this.props;
|
||||
try {
|
||||
await cancelAccountDeletion();
|
||||
notify(
|
||||
'success',
|
||||
'Account Deletion Request Cancelled - Your request to delete your account has been cancelled. You may now write comments, reply to comments, and select reactions.'
|
||||
);
|
||||
} catch (err) {
|
||||
notify('error', getErrorMessages(err));
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<h4 className={styles.title}>
|
||||
<Icon name="warning" className={styles.icon} />Account Deletion
|
||||
Requested
|
||||
</h4>
|
||||
<p className={styles.description}>
|
||||
A request to delete your account was received on.
|
||||
</p>
|
||||
<p className={styles.description}>
|
||||
If you would like to continue leaving comments, replies or reactions,
|
||||
you may cancel your request to delete your account below before
|
||||
</p>
|
||||
<div className={styles.actions}>
|
||||
<Button
|
||||
className={cn(styles.button, styles.secondary)}
|
||||
onClick={this.cancelAccountDeletion}
|
||||
>
|
||||
Cancel Account Deletion Request
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AccountDeletionRequestedSign.propTypes = {
|
||||
cancelAccountDeletion: PropTypes.func.isRequired,
|
||||
notify: PropTypes.func.isRequired,
|
||||
root: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default AccountDeletionRequestedSign;
|
||||
@@ -0,0 +1,23 @@
|
||||
.button {
|
||||
color: #787D80;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #787d80;
|
||||
background-color: transparent;
|
||||
height: 30px;
|
||||
font-size: 0.9em;
|
||||
line-height: normal;
|
||||
|
||||
&:hover {
|
||||
background-color: #eaeaea;
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
background-color: #787D80;
|
||||
color: white;
|
||||
}
|
||||
|
||||
> i {
|
||||
font-size: 1.2em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import moment from 'moment';
|
||||
import styles from './DeleteMyAccount.css';
|
||||
import { Button } from 'plugin-api/beta/client/components/ui';
|
||||
import DeleteMyAccountDialog from './DeleteMyAccountDialog';
|
||||
import { getErrorMessages } from 'coral-framework/utils';
|
||||
|
||||
const initialState = { showDialog: false };
|
||||
|
||||
class DeleteMyAccount extends React.Component {
|
||||
state = initialState;
|
||||
|
||||
showDialog = () => {
|
||||
this.setState({
|
||||
showDialog: true,
|
||||
});
|
||||
};
|
||||
|
||||
closeDialog = () => {
|
||||
this.setState({
|
||||
showDialog: false,
|
||||
});
|
||||
};
|
||||
|
||||
cancelAccountDeletion = async () => {
|
||||
const { cancelAccountDeletion, notify } = this.props;
|
||||
try {
|
||||
await cancelAccountDeletion();
|
||||
notify(
|
||||
'success',
|
||||
'Account Deletion Request Cancelled - Your request to delete your account has been cancelled. You may now write comments, reply to comments, and select reactions.'
|
||||
);
|
||||
} catch (err) {
|
||||
notify('error', getErrorMessages(err));
|
||||
}
|
||||
};
|
||||
|
||||
requestAccountDeletion = async () => {
|
||||
const { requestAccountDeletion, notify } = this.props;
|
||||
try {
|
||||
await requestAccountDeletion();
|
||||
notify('success', 'Account Deletion Requested');
|
||||
} catch (err) {
|
||||
notify('error', getErrorMessages(err));
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { me: { scheduledDeletionDate } } = this.props.root;
|
||||
return (
|
||||
<div className="talk-plugin-auth--delete-my-account">
|
||||
<DeleteMyAccountDialog
|
||||
requestAccountDeletion={this.requestAccountDeletion}
|
||||
showDialog={this.state.showDialog}
|
||||
closeDialog={this.closeDialog}
|
||||
/>
|
||||
<h3
|
||||
className={cn(
|
||||
styles.title,
|
||||
'talk-plugin-auth--delete-my-account-description'
|
||||
)}
|
||||
>
|
||||
Delete My Account
|
||||
</h3>
|
||||
<p
|
||||
className={cn(
|
||||
styles.description,
|
||||
'talk-plugin-auth--delete-my-account-description'
|
||||
)}
|
||||
>
|
||||
Deleting your account will permanently erase your profile and remove
|
||||
all your comments from this site.
|
||||
</p>
|
||||
<p
|
||||
className={cn(
|
||||
styles.description,
|
||||
'talk-plugin-auth--delete-my-account-description'
|
||||
)}
|
||||
>
|
||||
{scheduledDeletionDate &&
|
||||
`You have already submitted a request to delete your account.
|
||||
Your account will be deleted on ${moment(
|
||||
scheduledDeletionDate
|
||||
).format('MMM Do YYYY, h:mm:ss a')}. You may
|
||||
cancel the request until that time`}
|
||||
</p>
|
||||
{scheduledDeletionDate ? (
|
||||
<Button
|
||||
className={cn(styles.button, styles.secondary)}
|
||||
onClick={this.cancelAccountDeletion}
|
||||
>
|
||||
Cancel Account Deletion Request
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
className={cn(styles.button)}
|
||||
icon="delete"
|
||||
onClick={this.showDialog}
|
||||
>
|
||||
Delete My Account
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
DeleteMyAccount.propTypes = {
|
||||
requestAccountDeletion: PropTypes.func.isRequired,
|
||||
cancelAccountDeletion: PropTypes.func.isRequired,
|
||||
notify: PropTypes.func.isRequired,
|
||||
root: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default DeleteMyAccount;
|
||||
@@ -0,0 +1,37 @@
|
||||
.dialog {
|
||||
border: none;
|
||||
box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2);
|
||||
width: 380px;
|
||||
top: 10px;
|
||||
font-family: Helvetica, 'Helvetica Neue', Verdana, sans-serif;
|
||||
font-size: 14px;
|
||||
border-radius: 4px;
|
||||
padding: 12px 20px;
|
||||
}
|
||||
|
||||
.close {
|
||||
font-size: 20px;
|
||||
line-height: 14px;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
position: absolute;
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
color: #363636;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #6b6b6b;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.2em;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1em;
|
||||
line-height: 20px;
|
||||
margin: 0;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './DeleteMyAccountDialog.css';
|
||||
import { Dialog } from 'plugin-api/beta/client/components/ui';
|
||||
import StepProgress from './StepProgress';
|
||||
import DeleteMyAccountStep0 from './DeleteMyAccountStep0';
|
||||
import DeleteMyAccountStep1 from './DeleteMyAccountStep1';
|
||||
import DeleteMyAccountStep2 from './DeleteMyAccountStep2';
|
||||
import DeleteMyAccountStep3 from './DeleteMyAccountStep3';
|
||||
import DeleteMyAccountFinalStep from './DeleteMyAccountFinalStep';
|
||||
|
||||
const initialState = { step: 0, formData: {} };
|
||||
|
||||
class DeleteMyAccountDialog extends React.Component {
|
||||
state = initialState;
|
||||
|
||||
goToNextStep = () => {
|
||||
this.setState(state => ({
|
||||
step: state.step + 1,
|
||||
}));
|
||||
};
|
||||
|
||||
clear = () => {
|
||||
this.setState(initialState);
|
||||
};
|
||||
|
||||
cancel = () => {
|
||||
this.clear();
|
||||
this.props.closeDialog();
|
||||
};
|
||||
|
||||
onChange = e => {
|
||||
const { name, value } = e.target;
|
||||
|
||||
this.setState(state => ({
|
||||
formData: {
|
||||
...state.formData,
|
||||
[name]: value,
|
||||
},
|
||||
}));
|
||||
};
|
||||
|
||||
render() {
|
||||
const { step } = this.state;
|
||||
return (
|
||||
<Dialog open={this.props.showDialog} className={styles.dialog}>
|
||||
<span className={styles.close} onClick={this.cancel}>
|
||||
×
|
||||
</span>
|
||||
<h3 className={styles.title}>Delete My Account</h3>
|
||||
<StepProgress currentStep={this.state.step} totalSteps={4} />
|
||||
{step === 0 && (
|
||||
<DeleteMyAccountStep0
|
||||
goToNextStep={this.goToNextStep}
|
||||
cancel={this.cancel}
|
||||
/>
|
||||
)}
|
||||
{step === 1 && (
|
||||
<DeleteMyAccountStep1
|
||||
goToNextStep={this.goToNextStep}
|
||||
cancel={this.cancel}
|
||||
/>
|
||||
)}
|
||||
{step === 2 && (
|
||||
<DeleteMyAccountStep2
|
||||
goToNextStep={this.goToNextStep}
|
||||
cancel={this.cancel}
|
||||
/>
|
||||
)}
|
||||
{step === 3 && (
|
||||
<DeleteMyAccountStep3
|
||||
formData={this.state.formData}
|
||||
goToNextStep={this.goToNextStep}
|
||||
cancel={this.cancel}
|
||||
requestAccountDeletion={this.props.requestAccountDeletion}
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
)}
|
||||
{step === 4 && <DeleteMyAccountFinalStep finish={this.cancel} />}
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
DeleteMyAccountDialog.propTypes = {
|
||||
showDialog: PropTypes.bool.isRequired,
|
||||
closeDialog: PropTypes.func.isRequired,
|
||||
requestAccountDeletion: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default DeleteMyAccountDialog;
|
||||
@@ -0,0 +1,55 @@
|
||||
import React from 'react';
|
||||
import cn from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Button, Icon } from 'plugin-api/beta/client/components/ui';
|
||||
import styles from './DeleteMyAccountStep.css';
|
||||
|
||||
const DeleteMyAccountFinalStep = props => (
|
||||
<div className={styles.step}>
|
||||
<p className={styles.description}>
|
||||
Your request has been submitted and confirmation has been sent to the
|
||||
email address associated with your account.
|
||||
</p>
|
||||
|
||||
<div className={cn(styles.box, styles.scheduledDeletion)}>
|
||||
<strong className={styles.block}>
|
||||
Your account is scheduled to be deleted at:
|
||||
</strong>
|
||||
<strong className={styles.block}>
|
||||
<Icon name="access_time" className={styles.timeIcon} />
|
||||
<span>Account Deletion Date and Time</span>
|
||||
</strong>
|
||||
</div>
|
||||
|
||||
<p className={styles.description}>
|
||||
<strong>Changed your mind?</strong> Simply sign in to your account again
|
||||
before this time and click “<strong>
|
||||
Cancel Account Deletion Request.
|
||||
</strong>”
|
||||
</p>
|
||||
|
||||
<p className={styles.description}>
|
||||
<strong>Tell us why.</strong> Wed like to know why you chose to delete
|
||||
your account. Send us feedback on our comment system by emailing.
|
||||
</p>
|
||||
|
||||
<div className={cn(styles.actions, styles.columnView)}>
|
||||
<Button
|
||||
className={cn(styles.button, styles.proceed)}
|
||||
onClick={props.finish}
|
||||
full
|
||||
>
|
||||
Done
|
||||
</Button>
|
||||
<span className={styles.note}>
|
||||
Note: You will be immediately signed out of your account.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
DeleteMyAccountFinalStep.propTypes = {
|
||||
finish: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default DeleteMyAccountFinalStep;
|
||||
@@ -0,0 +1,116 @@
|
||||
.list {
|
||||
padding: 0;
|
||||
margin: 20px 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.itemIcon {
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
.text {
|
||||
flex-grow: 1;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
> i.itemIcon {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
color: #787D80;
|
||||
border-radius: 2px;
|
||||
background-color: transparent;
|
||||
height: 30px;
|
||||
font-size: 0.9em;
|
||||
line-height: normal;
|
||||
|
||||
&:hover {
|
||||
background-color: #eaeaea;
|
||||
}
|
||||
|
||||
&.cancel {
|
||||
background-color: transparent;
|
||||
color: #787D80;
|
||||
}
|
||||
|
||||
&.proceed {
|
||||
background-color: #3498DB;
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.danger {
|
||||
background-color: #FA4643;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
text-align: right;
|
||||
padding-top: 20px;
|
||||
|
||||
&.columnView {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.2em;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1em;
|
||||
line-height: 20px;
|
||||
margin: 0;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.note {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.subTitle {
|
||||
font-size: 1em;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.textBox {
|
||||
background-color: #F1F2F2;
|
||||
border: none;
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
box-sizing: border-box;
|
||||
color: #3B4A53;
|
||||
font-size: 1em;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.block {
|
||||
display: block;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.step {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.scheduledDeletion {
|
||||
i.timeIcon {
|
||||
font-size: 1.2em;
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import { Button, Icon } from 'plugin-api/beta/client/components/ui';
|
||||
import styles from './DeleteMyAccountStep.css';
|
||||
|
||||
const DeleteMyAccountStep0 = props => (
|
||||
<div className={styles.step}>
|
||||
<p className={styles.description}>
|
||||
You are attempting to delete your account. This means:
|
||||
</p>
|
||||
<ul className={styles.list}>
|
||||
<li className={styles.item}>
|
||||
<Icon name="done" className={styles.itemIcon} />
|
||||
<span className={styles.text}>
|
||||
All of your comments are removed from this site
|
||||
</span>
|
||||
</li>
|
||||
<li className={styles.item}>
|
||||
<Icon name="done" className={styles.itemIcon} />
|
||||
<span className={styles.text}>
|
||||
All of your comments are deleted from our database
|
||||
</span>
|
||||
</li>
|
||||
<li className={styles.item}>
|
||||
<Icon name="done" className={styles.itemIcon} />
|
||||
<span className={styles.text}>
|
||||
Your username and email address are removed from our system
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div className={cn(styles.actions)}>
|
||||
<Button
|
||||
className={cn(styles.button, styles.cancel)}
|
||||
onClick={props.cancel}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
className={cn(styles.button, styles.proceed)}
|
||||
onClick={props.goToNextStep}
|
||||
>
|
||||
Proceed
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
DeleteMyAccountStep0.propTypes = {
|
||||
goToNextStep: PropTypes.func.isRequired,
|
||||
cancel: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default DeleteMyAccountStep0;
|
||||
@@ -0,0 +1,43 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import { Button } from 'plugin-api/beta/client/components/ui';
|
||||
import styles from './DeleteMyAccountStep.css';
|
||||
|
||||
const DeleteMyAccountStep1 = props => (
|
||||
<div className={styles.step}>
|
||||
<h4 className={styles.subTitle}>When will my account be deleted?</h4>
|
||||
<p className={styles.description}>
|
||||
Your account will be deleted 24 hours after your request has been
|
||||
submitted.
|
||||
</p>
|
||||
<h4 className={styles.subTitle}>
|
||||
Can I still write comments until my account is deleted?{' '}
|
||||
</h4>
|
||||
<p className={styles.description}>
|
||||
No. Once youve requested account deletion, you can no longer write
|
||||
comments, reply to comments, or select reactions.
|
||||
</p>
|
||||
<div className={cn(styles.actions)}>
|
||||
<Button
|
||||
className={cn(styles.button, styles.cancel)}
|
||||
onClick={props.cancel}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
className={cn(styles.button, styles.proceed)}
|
||||
onClick={props.goToNextStep}
|
||||
>
|
||||
Proceed
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
DeleteMyAccountStep1.propTypes = {
|
||||
goToNextStep: PropTypes.func.isRequired,
|
||||
cancel: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default DeleteMyAccountStep1;
|
||||
@@ -0,0 +1,42 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import { Button } from 'plugin-api/beta/client/components/ui';
|
||||
import styles from './DeleteMyAccountStep.css';
|
||||
|
||||
const DeleteMyAccountStep2 = props => (
|
||||
<div className={styles.step}>
|
||||
<p className={styles.description}>
|
||||
Before your account is deleted, we recommend you download your comment
|
||||
history for your records. After your account is deleted, you will be
|
||||
unable to request your comment history.
|
||||
</p>
|
||||
<p className={styles.description}>
|
||||
To download your comment history go to:
|
||||
<strong className={styles.block}>
|
||||
My Profile {`>`} Download My Comment History
|
||||
</strong>
|
||||
</p>
|
||||
<div className={cn(styles.actions)}>
|
||||
<Button
|
||||
className={cn(styles.button, styles.cancel)}
|
||||
onClick={props.cancel}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
className={cn(styles.button, styles.proceed)}
|
||||
onClick={props.goToNextStep}
|
||||
>
|
||||
Proceed
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
DeleteMyAccountStep2.propTypes = {
|
||||
goToNextStep: PropTypes.func.isRequired,
|
||||
cancel: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default DeleteMyAccountStep2;
|
||||
@@ -0,0 +1,96 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import { Button } from 'plugin-api/beta/client/components/ui';
|
||||
import styles from './DeleteMyAccountStep.css';
|
||||
import InputField from '../../components/InputField';
|
||||
|
||||
const initialState = {
|
||||
showError: false,
|
||||
};
|
||||
|
||||
class DeleteMyAccountStep3 extends React.Component {
|
||||
state = initialState;
|
||||
phrase = 'delete';
|
||||
|
||||
showError = () => {
|
||||
this.setState({
|
||||
showError: true,
|
||||
});
|
||||
};
|
||||
|
||||
clear = () => {
|
||||
this.setState(initialState);
|
||||
};
|
||||
|
||||
deleteAndContinue = async () => {
|
||||
if (this.formHasError()) {
|
||||
this.showError();
|
||||
return;
|
||||
}
|
||||
|
||||
await this.props.requestAccountDeletion();
|
||||
this.clear();
|
||||
this.props.goToNextStep();
|
||||
};
|
||||
|
||||
formHasError = () =>
|
||||
!this.props.formData.confirmPhrase ||
|
||||
this.props.formData.confirmPhrase !== this.phrase;
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={styles.step}>
|
||||
<h4 className={styles.subTitle}>
|
||||
Are you sure you want to delete your account?
|
||||
</h4>
|
||||
<p className={styles.description}>
|
||||
To confirm you would like to delete your account please type in the
|
||||
following phrase into the text box below:
|
||||
</p>
|
||||
<input
|
||||
className={styles.textBox}
|
||||
disabled={true}
|
||||
readOnly={true}
|
||||
value={this.phrase}
|
||||
/>
|
||||
<InputField
|
||||
id="confirmPhrase"
|
||||
label={'Type phrase bellow to confirm'}
|
||||
name="confirmPhrase"
|
||||
type="text"
|
||||
onChange={this.props.onChange}
|
||||
defaultValue=""
|
||||
hasError={this.formHasError()}
|
||||
errorMsg={'The input is not correct'}
|
||||
showError={this.state.showError}
|
||||
columnDisplay
|
||||
/>
|
||||
<div className={cn(styles.actions)}>
|
||||
<Button
|
||||
className={cn(styles.button, styles.cancel)}
|
||||
onClick={this.props.cancel}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
className={cn(styles.button, styles.danger)}
|
||||
onClick={this.deleteAndContinue}
|
||||
>
|
||||
Delete My Account
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
DeleteMyAccountStep3.propTypes = {
|
||||
goToNextStep: PropTypes.func.isRequired,
|
||||
requestAccountDeletion: PropTypes.func.isRequired,
|
||||
cancel: PropTypes.func.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
formData: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default DeleteMyAccountStep3;
|
||||
@@ -0,0 +1,12 @@
|
||||
.errorMsg {
|
||||
color: #FA4643;
|
||||
font-size: 0.9em;
|
||||
|
||||
i.warningIcon {
|
||||
font-size: 17px;
|
||||
}
|
||||
}
|
||||
|
||||
.warningIcon {
|
||||
color: #FA4643;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './ErrorMessage.css';
|
||||
import { Icon } from 'plugin-api/beta/client/components/ui';
|
||||
|
||||
const ErrorMessage = ({ children }) => (
|
||||
<div className={styles.errorMsg}>
|
||||
<Icon className={styles.warningIcon} name="warning" />
|
||||
<span>{children}</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
ErrorMessage.propTypes = {
|
||||
children: PropTypes.node,
|
||||
};
|
||||
|
||||
export default ErrorMessage;
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
.detailItem {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.detailItemContainer {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.columnDisplay {
|
||||
flex-direction: column;
|
||||
|
||||
.detailItemMessage {
|
||||
padding: 4px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.detailItemContent {
|
||||
border: solid 1px #787D80;
|
||||
border-radius: 2px;
|
||||
background-color: white;
|
||||
height: 30px;
|
||||
display: inline-block;
|
||||
width: 230px;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
|
||||
> .detailIcon {
|
||||
font-size: 1.2em;
|
||||
padding: 0 5px;
|
||||
color: #787D80;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
&.error {
|
||||
border: solid 2px #FA4643;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
background-color: #E0E0E0;
|
||||
}
|
||||
}
|
||||
|
||||
.detailLabel {
|
||||
color: #4C4C4D;
|
||||
font-size: 1em;
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.detailValue {
|
||||
background: transparent;
|
||||
border: none;
|
||||
font-size: 1em;
|
||||
color: #000;
|
||||
outline: none;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.detailItemMessage {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 6px;
|
||||
padding-top: 16px;
|
||||
|
||||
.warningIcon, .checkIcon {
|
||||
font-size: 17px;
|
||||
}
|
||||
}
|
||||
|
||||
.checkIcon {
|
||||
color: #00CD73;
|
||||
}
|
||||
|
||||
.warningIcon {
|
||||
color: #FA4643;
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import styles from './InputField.css';
|
||||
import ErrorMessage from './ErrorMessage';
|
||||
import { Icon } from 'plugin-api/beta/client/components/ui';
|
||||
|
||||
const InputField = ({
|
||||
id = '',
|
||||
label = '',
|
||||
type = 'text',
|
||||
name = '',
|
||||
onChange = () => {},
|
||||
showError = true,
|
||||
hasError = false,
|
||||
errorMsg = '',
|
||||
children,
|
||||
columnDisplay = false,
|
||||
showSuccess = false,
|
||||
validationType = '',
|
||||
icon = '',
|
||||
value = '',
|
||||
defaultValue = '',
|
||||
disabled = false,
|
||||
}) => {
|
||||
const inputValue = {
|
||||
...(value ? { value } : {}),
|
||||
...(defaultValue ? { defaultValue } : {}),
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.detailItem}>
|
||||
<div
|
||||
className={cn(styles.detailItemContainer, {
|
||||
[styles.columnDisplay]: columnDisplay,
|
||||
})}
|
||||
>
|
||||
{label && (
|
||||
<label className={styles.detailLabel} id={id}>
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
<div
|
||||
className={cn(
|
||||
styles.detailItemContent,
|
||||
{ [styles.error]: hasError && showError },
|
||||
{ [styles.disabled]: disabled }
|
||||
)}
|
||||
>
|
||||
{icon && <Icon name={icon} className={styles.detailIcon} />}
|
||||
<input
|
||||
id={id}
|
||||
type={type}
|
||||
name={name}
|
||||
className={styles.detailValue}
|
||||
onChange={onChange}
|
||||
autoComplete="off"
|
||||
data-validation-type={validationType}
|
||||
disabled={disabled}
|
||||
{...inputValue}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.detailItemMessage}>
|
||||
{!hasError &&
|
||||
showSuccess &&
|
||||
value && <Icon className={styles.checkIcon} name="check_circle" />}
|
||||
{hasError && showError && <ErrorMessage>{errorMsg}</ErrorMessage>}
|
||||
</div>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
InputField.propTypes = {
|
||||
id: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
label: PropTypes.string,
|
||||
type: PropTypes.string,
|
||||
name: PropTypes.string.isRequired,
|
||||
onChange: PropTypes.func,
|
||||
value: PropTypes.string,
|
||||
defaultValue: PropTypes.string,
|
||||
icon: PropTypes.string,
|
||||
showError: PropTypes.bool,
|
||||
hasError: PropTypes.bool,
|
||||
errorMsg: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
columnDisplay: PropTypes.bool,
|
||||
showSuccess: PropTypes.bool,
|
||||
validationType: PropTypes.string,
|
||||
};
|
||||
|
||||
export default InputField;
|
||||
@@ -0,0 +1,32 @@
|
||||
.step {
|
||||
color: #BBBEBF;
|
||||
background-color: white;
|
||||
padding: 6px;
|
||||
z-index: 10;
|
||||
|
||||
&.current {
|
||||
color: rgba(0, 205, 115, 0.3);
|
||||
}
|
||||
|
||||
&.completed {
|
||||
color: #00CD73;
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
position: absolute;
|
||||
border: solid 2px #BBBEBF;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
margin: 0 20px;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import React from 'react';
|
||||
import cn from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './StepProgress.css';
|
||||
import { Icon } from 'plugin-api/beta/client/components/ui';
|
||||
|
||||
const CheckItem = ({ current = false, completed = false }) => (
|
||||
<span
|
||||
className={cn(styles.step, {
|
||||
[styles.current]: current,
|
||||
[styles.completed]: completed,
|
||||
})}
|
||||
>
|
||||
<Icon name="check_circle" />
|
||||
</span>
|
||||
);
|
||||
|
||||
CheckItem.propTypes = {
|
||||
current: PropTypes.bool.isRequired,
|
||||
completed: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const Line = () => <hr className={styles.line} />;
|
||||
|
||||
class StepProgress extends React.Component {
|
||||
render() {
|
||||
const { currentStep, totalSteps } = this.props;
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
{Array.from({ length: totalSteps }).map((_, i) => (
|
||||
<CheckItem
|
||||
key={`step_${i}`}
|
||||
completed={i < currentStep}
|
||||
current={currentStep === i}
|
||||
/>
|
||||
))}
|
||||
<Line />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
StepProgress.propTypes = {
|
||||
currentStep: PropTypes.number.isRequired,
|
||||
totalSteps: PropTypes.number.isRequired,
|
||||
};
|
||||
|
||||
export default StepProgress;
|
||||
Reference in New Issue
Block a user