feat: delete account (#1653)
* feat: delete account * fix: copy adjustments Co-authored-by: Mo
This commit is contained in:
@@ -25,6 +25,7 @@ import { PanelResizedData } from '@/Types/PanelResizedData'
|
|||||||
import TagContextMenuWrapper from '@/Components/Tags/TagContextMenuWrapper'
|
import TagContextMenuWrapper from '@/Components/Tags/TagContextMenuWrapper'
|
||||||
import FileDragNDropProvider from '../FileDragNDropProvider/FileDragNDropProvider'
|
import FileDragNDropProvider from '../FileDragNDropProvider/FileDragNDropProvider'
|
||||||
import ResponsivePaneProvider from '../ResponsivePane/ResponsivePaneProvider'
|
import ResponsivePaneProvider from '../ResponsivePane/ResponsivePaneProvider'
|
||||||
|
import ConfirmDeleteAccountContainer from '@/Components/ConfirmDeleteAccountModal/ConfirmDeleteAccountModal'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
application: WebApplication
|
application: WebApplication
|
||||||
@@ -240,6 +241,7 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
|
|||||||
<ToastContainer />
|
<ToastContainer />
|
||||||
<FilePreviewModalWrapper application={application} viewControllerManager={viewControllerManager} />
|
<FilePreviewModalWrapper application={application} viewControllerManager={viewControllerManager} />
|
||||||
<PermissionsModalWrapper application={application} />
|
<PermissionsModalWrapper application={application} />
|
||||||
|
<ConfirmDeleteAccountContainer application={application} viewControllerManager={viewControllerManager} />
|
||||||
</>
|
</>
|
||||||
</div>
|
</div>
|
||||||
</ResponsivePaneProvider>
|
</ResponsivePaneProvider>
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
import { observer } from 'mobx-react-lite'
|
||||||
|
import { ViewControllerManager } from '@Controllers/ViewControllerManager'
|
||||||
|
import { AlertDialog, AlertDialogDescription, AlertDialogLabel } from '@reach/alert-dialog'
|
||||||
|
import { useRef } from 'react'
|
||||||
|
import { STRING_DELETE_ACCOUNT_CONFIRMATION } from '@/Constants/Strings'
|
||||||
|
import Button from '@/Components/Button/Button'
|
||||||
|
import { WebApplication } from '@/Application/Application'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
viewControllerManager: ViewControllerManager
|
||||||
|
application: WebApplication
|
||||||
|
}
|
||||||
|
|
||||||
|
const ConfirmDeleteAccountModal = ({ application, viewControllerManager }: Props) => {
|
||||||
|
function closeDialog() {
|
||||||
|
viewControllerManager.accountMenuController.setDeletingAccount(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const cancelRef = useRef<HTMLButtonElement>(null)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AlertDialog onDismiss={closeDialog} leastDestructiveRef={cancelRef} className="max-w-[600px] p-0">
|
||||||
|
<div className="sk-modal-content">
|
||||||
|
<div className="sn-component">
|
||||||
|
<div className="sk-panel">
|
||||||
|
<div className="sk-panel-content">
|
||||||
|
<div className="sk-panel-section">
|
||||||
|
<AlertDialogLabel className="sk-h3 sk-panel-section-title">Delete account?</AlertDialogLabel>
|
||||||
|
<AlertDialogDescription className="sk-panel-row">
|
||||||
|
<div>
|
||||||
|
<p className="text-foreground">{STRING_DELETE_ACCOUNT_CONFIRMATION}</p>
|
||||||
|
</div>
|
||||||
|
</AlertDialogDescription>
|
||||||
|
|
||||||
|
<div className="my-1 mt-4 flex gap-2">
|
||||||
|
<Button primary small colorStyle="neutral" rounded={false} ref={cancelRef} onClick={closeDialog}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
primary
|
||||||
|
small
|
||||||
|
colorStyle="danger"
|
||||||
|
rounded={false}
|
||||||
|
onClick={() => {
|
||||||
|
application.user.deleteAccount().catch(console.error)
|
||||||
|
closeDialog()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Delete my account for good
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</AlertDialog>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfirmDeleteAccountModal.displayName = 'ConfirmDeleteAccountModal'
|
||||||
|
|
||||||
|
const ConfirmDeleteAccountContainer = (props: Props) => {
|
||||||
|
if (!props.viewControllerManager.accountMenuController.deletingAccount) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return <ConfirmDeleteAccountModal {...props} />
|
||||||
|
}
|
||||||
|
|
||||||
|
export default observer(ConfirmDeleteAccountContainer)
|
||||||
@@ -10,6 +10,7 @@ import FilesSection from './Files'
|
|||||||
import PreferencesPane from '../../PreferencesComponents/PreferencesPane'
|
import PreferencesPane from '../../PreferencesComponents/PreferencesPane'
|
||||||
import SubscriptionSharing from './SubscriptionSharing/SubscriptionSharing'
|
import SubscriptionSharing from './SubscriptionSharing/SubscriptionSharing'
|
||||||
import Email from './Email'
|
import Email from './Email'
|
||||||
|
import DeleteAccount from '@/Components/Preferences/Panes/Account/DeleteAccount'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
application: WebApplication
|
application: WebApplication
|
||||||
@@ -33,6 +34,7 @@ const AccountPreferences = ({ application, viewControllerManager }: Props) => (
|
|||||||
)}
|
)}
|
||||||
<Email application={application} />
|
<Email application={application} />
|
||||||
<SignOutWrapper application={application} viewControllerManager={viewControllerManager} />
|
<SignOutWrapper application={application} viewControllerManager={viewControllerManager} />
|
||||||
|
<DeleteAccount application={application} viewControllerManager={viewControllerManager} />
|
||||||
</PreferencesPane>
|
</PreferencesPane>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { observer } from 'mobx-react-lite'
|
||||||
|
import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment'
|
||||||
|
import { Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||||
|
import Button from '@/Components/Button/Button'
|
||||||
|
import PreferencesGroup from '@/Components/Preferences/PreferencesComponents/PreferencesGroup'
|
||||||
|
import { ViewControllerManager } from '@Controllers/ViewControllerManager'
|
||||||
|
import { WebApplication } from '@/Application/Application'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
application: WebApplication
|
||||||
|
viewControllerManager: ViewControllerManager
|
||||||
|
}
|
||||||
|
|
||||||
|
const DeleteAccount = ({ application, viewControllerManager }: Props) => {
|
||||||
|
if (!application.hasAccount()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<PreferencesGroup>
|
||||||
|
<PreferencesSegment>
|
||||||
|
<Title>Delete account</Title>
|
||||||
|
<Text>
|
||||||
|
This action is irreversible. After deletion completes, you will be signed out on all devices. If you have an
|
||||||
|
active paid subscription, cancel the subscription first. Otherwise, if you'd like to keep the subscription,
|
||||||
|
you can re-register with the same email after deletion, and your subscription will be linked back up with your
|
||||||
|
account.
|
||||||
|
</Text>
|
||||||
|
<div className="mt-3 flex flex-row flex-wrap gap-3">
|
||||||
|
<Button
|
||||||
|
colorStyle="danger"
|
||||||
|
label="Delete my account"
|
||||||
|
onClick={() => {
|
||||||
|
viewControllerManager.accountMenuController.setDeletingAccount(true)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</PreferencesSegment>
|
||||||
|
</PreferencesGroup>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default observer(DeleteAccount)
|
||||||
@@ -99,6 +99,8 @@ export const STRING_UPGRADE_ACCOUNT_CONFIRM_BUTTON = 'Upgrade'
|
|||||||
|
|
||||||
export const STRING_REMOVE_OFFLINE_KEY_CONFIRMATION = 'This will delete the previously saved offline key.'
|
export const STRING_REMOVE_OFFLINE_KEY_CONFIRMATION = 'This will delete the previously saved offline key.'
|
||||||
|
|
||||||
|
export const STRING_DELETE_ACCOUNT_CONFIRMATION = 'Are you sure you want to permanently delete your account?'
|
||||||
|
|
||||||
export const STRING_FAILED_TO_UPDATE_USER_SETTING =
|
export const STRING_FAILED_TO_UPDATE_USER_SETTING =
|
||||||
'There was an error while trying to update your settings. Please try again.'
|
'There was an error while trying to update your settings. Please try again.'
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export class AccountMenuController extends AbstractViewController {
|
|||||||
encryptionStatusString = ''
|
encryptionStatusString = ''
|
||||||
isBackupEncrypted = false
|
isBackupEncrypted = false
|
||||||
showSignIn = false
|
showSignIn = false
|
||||||
|
deletingAccount = false
|
||||||
showRegister = false
|
showRegister = false
|
||||||
shouldAnimateCloseMenu = false
|
shouldAnimateCloseMenu = false
|
||||||
currentPane = AccountMenuPane.GeneralMenu
|
currentPane = AccountMenuPane.GeneralMenu
|
||||||
@@ -49,6 +50,7 @@ export class AccountMenuController extends AbstractViewController {
|
|||||||
encryptionStatusString: observable,
|
encryptionStatusString: observable,
|
||||||
isBackupEncrypted: observable,
|
isBackupEncrypted: observable,
|
||||||
showSignIn: observable,
|
showSignIn: observable,
|
||||||
|
deletingAccount: observable,
|
||||||
showRegister: observable,
|
showRegister: observable,
|
||||||
currentPane: observable,
|
currentPane: observable,
|
||||||
shouldAnimateCloseMenu: observable,
|
shouldAnimateCloseMenu: observable,
|
||||||
@@ -64,6 +66,7 @@ export class AccountMenuController extends AbstractViewController {
|
|||||||
setCurrentPane: action,
|
setCurrentPane: action,
|
||||||
setEnableServerOption: action,
|
setEnableServerOption: action,
|
||||||
setServer: action,
|
setServer: action,
|
||||||
|
setDeletingAccount: action,
|
||||||
|
|
||||||
notesAndTagsCount: computed,
|
notesAndTagsCount: computed,
|
||||||
})
|
})
|
||||||
@@ -155,6 +158,10 @@ export class AccountMenuController extends AbstractViewController {
|
|||||||
this.currentPane = pane
|
this.currentPane = pane
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setDeletingAccount = (deletingAccount: boolean): void => {
|
||||||
|
this.deletingAccount = deletingAccount
|
||||||
|
}
|
||||||
|
|
||||||
get notesAndTagsCount(): number {
|
get notesAndTagsCount(): number {
|
||||||
return this.notesAndTags.length
|
return this.notesAndTags.length
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user