import styled from '@emotion/styled';
import {addErrorMessage, addLoadingMessage} from 'sentry/actionCreators/indicator';
import {ModalRenderProps, openModal} from 'sentry/actionCreators/modal';
import {Alert} from 'sentry/components/alert';
import {Button} from 'sentry/components/button';
import HookOrDefault from 'sentry/components/hookOrDefault';
import Panel from 'sentry/components/panels/panel';
import PanelAlert from 'sentry/components/panels/panelAlert';
import PanelBody from 'sentry/components/panels/panelBody';
import PanelHeader from 'sentry/components/panels/panelHeader';
import PanelItem from 'sentry/components/panels/panelItem';
import {t, tct} from 'sentry/locale';
import {Organization} from 'sentry/types';
import DeprecatedAsyncView from 'sentry/views/deprecatedAsyncView';
import {ConfirmAccountClose} from 'sentry/views/settings/account/confirmAccountClose';
import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
import TextBlock from 'sentry/views/settings/components/text/textBlock';
const BYE_URL = '/';
const leaveRedirect = () => (window.location.href = BYE_URL);
const Important = styled('div')`
font-weight: bold;
font-size: 1.2em;
`;
function GoodbyeModalContent({Header, Body, Footer}: ModalRenderProps) {
return (
{t('Your account has been deactivated and scheduled for removal.')}
{t('Thanks for using Sentry! We hope to see you again soon!')}
);
}
type OwnedOrg = {
organization: Organization;
singleOwner: boolean;
};
type Props = DeprecatedAsyncView['props'];
type State = DeprecatedAsyncView['state'] & {
organizations: OwnedOrg[] | null;
/**
* Org slugs that will be removed
*/
orgsToRemove: Set | null;
};
class AccountClose extends DeprecatedAsyncView {
leaveRedirectTimeout: number | undefined = undefined;
componentWillUnmount() {
window.clearTimeout(this.leaveRedirectTimeout);
}
getEndpoints(): ReturnType {
return [['organizations', '/organizations/?owner=1']];
}
getDefaultState() {
return {
...super.getDefaultState(),
orgsToRemove: null,
};
}
get singleOwnerOrgs() {
return this.state.organizations
?.filter(({singleOwner}) => singleOwner)
?.map(({organization}) => organization.slug);
}
getTitle() {
return t('Close Account');
}
handleChange = (
{slug}: Organization,
isSingle: boolean,
event: React.ChangeEvent
) => {
const checked = event.target.checked;
// Can't unselect an org where you are the single owner
if (isSingle) {
return;
}
this.setState(state => {
const set = state.orgsToRemove || new Set(this.singleOwnerOrgs);
if (checked) {
set.add(slug);
} else {
set.delete(slug);
}
return {orgsToRemove: set};
});
};
get orgSlugsToRemove() {
const {orgsToRemove} = this.state;
return (
(orgsToRemove === null ? this.singleOwnerOrgs : Array.from(orgsToRemove)) || []
);
}
handleRemoveAccount = async () => {
const orgs = this.orgSlugsToRemove;
addLoadingMessage('Closing account\u2026');
try {
await this.api.requestPromise('/users/me/', {
method: 'DELETE',
data: {organizations: orgs},
});
openModal(GoodbyeModalContent, {
onClose: leaveRedirect,
});
// Redirect after 10 seconds
window.clearTimeout(this.leaveRedirectTimeout);
this.leaveRedirectTimeout = window.setTimeout(leaveRedirect, 10000);
} catch {
addErrorMessage('Error closing account');
}
};
renderBody() {
const {organizations, orgsToRemove} = this.state;
const HookedCustomConfirmAccountClose = HookOrDefault({
hookName: 'component:confirm-account-close',
defaultComponent: props => ,
});
return (
);
}
}
export default AccountClose;