diff --git a/packages/shared/src/components/profile/AccountDangerZone.tsx b/packages/shared/src/components/profile/AccountDangerZone.tsx index c94b47566e8..16fd4105a0f 100644 --- a/packages/shared/src/components/profile/AccountDangerZone.tsx +++ b/packages/shared/src/components/profile/AccountDangerZone.tsx @@ -9,6 +9,8 @@ interface AccountDangerZoneProps { onDelete: () => void; className?: string; children?: ReactNode; + buttonDisabled?: boolean; + buttonLoading?: boolean; } const Important = () => ( @@ -48,6 +50,8 @@ const ImportantActiveAppleSubscription = () => { function AccountDangerZone({ onDelete, className, + buttonDisabled = false, + buttonLoading = false, }: AccountDangerZoneProps): ReactElement { const { isPlus, status, plusProvider } = usePlusSubscription(); @@ -70,7 +74,8 @@ function AccountDangerZone({ important={ disableDeletion ? : } - buttonDisabled={disableDeletion} + buttonDisabled={disableDeletion || buttonDisabled} + buttonLoading={buttonLoading} /> ); } diff --git a/packages/shared/src/components/widgets/DangerZone.tsx b/packages/shared/src/components/widgets/DangerZone.tsx index c71974c8c5e..ddd77d52b96 100644 --- a/packages/shared/src/components/widgets/DangerZone.tsx +++ b/packages/shared/src/components/widgets/DangerZone.tsx @@ -18,6 +18,7 @@ interface DangerZoneProps { onClick: () => void; className?: string; buttonDisabled?: boolean; + buttonLoading?: boolean; } export function DangerZone({ @@ -29,6 +30,7 @@ export function DangerZone({ onClick, children, buttonDisabled = false, + buttonLoading = false, }: DangerZoneProps): ReactElement { return (
{cta} diff --git a/packages/webapp/components/layouts/SettingsLayout/Security/index.tsx b/packages/webapp/components/layouts/SettingsLayout/Security/index.tsx index 2057ea55729..827fdb07c16 100644 --- a/packages/webapp/components/layouts/SettingsLayout/Security/index.tsx +++ b/packages/webapp/components/layouts/SettingsLayout/Security/index.tsx @@ -1,3 +1,5 @@ +import React, { useState } from 'react'; +import type { FormEvent, MutableRefObject, ReactElement } from 'react'; import { providerMap } from '@dailydotdev/shared/src/components/auth/common'; import { Button, @@ -7,9 +9,7 @@ import { } from '@dailydotdev/shared/src/components/buttons/Button'; import { LockIcon, MailIcon } from '@dailydotdev/shared/src/components/icons'; import AccountDangerZone from '@dailydotdev/shared/src/components/profile/AccountDangerZone'; -import AuthContext from '@dailydotdev/shared/src/contexts/AuthContext'; -import type { FormEvent, MutableRefObject, ReactElement } from 'react'; -import React, { useContext, useState } from 'react'; +import { useAuthContext } from '@dailydotdev/shared/src/contexts/AuthContext'; import type { AuthSession, KratosProviderData, @@ -33,6 +33,7 @@ import { capitalize } from '@dailydotdev/shared/src/lib/strings'; import { BOOT_LOCAL_KEY } from '@dailydotdev/shared/src/contexts/common'; import { DEFAULT_ERROR } from '@dailydotdev/shared/src/graphql/common'; import { Tooltip } from '@dailydotdev/shared/src/components/tooltip/Tooltip'; +import { useMutation } from '@tanstack/react-query'; import AccountContentSection from '../AccountContentSection'; import { AccountPageContainer } from '../AccountPageContainer'; import type { ManageSocialProvidersProps } from '../common'; @@ -118,7 +119,7 @@ function AccountSecurityDefault({ onUpdatePassword, onUpdateProviders, }: AccountSecurityDefaultProps): ReactElement { - const { deleteAccount } = useContext(AuthContext); + const { deleteAccount } = useAuthContext(); const { displayToast } = useToastNotification(); const { onUpdateSignBack } = useSignBack(); const [linkProvider, setLinkProvider] = useState(null); @@ -152,19 +153,22 @@ function AccountSecurityDefault({ manageSocialProviders({ type: 'unlink', provider }); } }; - const deleteAccountPrompt = async () => { - if (await showPrompt(deleteAccountPromptOptions)) { - try { + const { mutate: deleteAccountPrompt, isPending: isDeleting } = useMutation({ + mutationKey: ['deleteAccount'], + mutationFn: async () => { + if (await showPrompt(deleteAccountPromptOptions)) { await deleteAccount(); - } catch (error) { - displayToast(DEFAULT_ERROR); - return; } + }, + onError: () => { + displayToast(DEFAULT_ERROR); + }, + onSuccess: async () => { await onUpdateSignBack(null, null); globalThis?.localStorage.removeItem(BOOT_LOCAL_KEY); window.location.replace('/'); - } - }; + }, + }); useEventListener(globalThis, 'message', async (e) => { if (e.data?.eventKey !== AuthEvent.SocialRegistration) { @@ -287,6 +291,7 @@ function AccountSecurityDefault({ deleteAccountPrompt()} className="mt-6" + buttonLoading={isDeleting} />