Skip to content

Commit ed8c3c3

Browse files
committed
Reintroduce the "delete account" action
This re-introduces the "Delete Account/Organization" action within the account / organization admin.
1 parent c1f92fd commit ed8c3c3

File tree

3 files changed

+149
-20
lines changed

3 files changed

+149
-20
lines changed

src/pages/AccountSettings/tabs/DeletionCard/DeletionCard.test.tsx

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
12
import { render, screen } from '@testing-library/react'
23
import { MemoryRouter, Route } from 'react-router-dom'
34

45
import DeletionCard from './DeletionCard'
56

7+
const queryClient = new QueryClient({
8+
defaultOptions: { queries: { retry: false } },
9+
})
10+
611
const wrapper: React.FC<React.PropsWithChildren> = ({ children }) => (
7-
<MemoryRouter initialEntries={['/account/gh/test-user']}>
8-
<Route path="/account/:provider/:owner">{children}</Route>
9-
</MemoryRouter>
12+
<QueryClientProvider client={queryClient}>
13+
<MemoryRouter initialEntries={['/account/gh/test-user']}>
14+
<Route path="/account/:provider/:owner">{children}</Route>
15+
</MemoryRouter>
16+
</QueryClientProvider>
1017
)
1118

1219
describe('DeletionCard', () => {

src/pages/AccountSettings/tabs/DeletionCard/DeletionCard.tsx

+74-17
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,86 @@
1+
import { useState } from 'react'
2+
import { useParams } from 'react-router-dom'
3+
14
import Card from 'old_ui/Card'
2-
import A from 'ui/A'
5+
import { useEraseAccount } from 'services/account'
6+
import Button from 'ui/Button'
7+
8+
import EraseOwnerModal from './EraseOwnerModal'
39

410
interface DeletionCardProps {
511
isPersonalSettings: boolean
612
}
713

14+
interface EraseOwnerButtonProps {
15+
isPersonalSettings: boolean
16+
isLoading: boolean
17+
setShowModal: (_: boolean) => void
18+
}
19+
20+
function EraseOwnerButton({
21+
isPersonalSettings,
22+
isLoading,
23+
setShowModal,
24+
}: EraseOwnerButtonProps) {
25+
const button = isPersonalSettings
26+
? 'Erase Personal Account'
27+
: 'Erase Organization'
28+
29+
if (isLoading) {
30+
return (
31+
<div className="font-light italic">
32+
processing erase, this may take a while
33+
</div>
34+
)
35+
}
36+
37+
return (
38+
<Button
39+
variant="danger"
40+
hook="show-modal"
41+
onClick={() => setShowModal(true)}
42+
>
43+
{button}
44+
</Button>
45+
)
46+
}
47+
48+
interface URLParams {
49+
provider?: string
50+
owner?: string
51+
}
52+
853
function DeletionCard({ isPersonalSettings }: DeletionCardProps) {
54+
const { provider, owner } = useParams<URLParams>()
55+
const [showModal, setShowModal] = useState(false)
56+
const { mutate: eraseOwner, isLoading } = useEraseAccount({ provider, owner })
57+
58+
const title = isPersonalSettings ? 'Delete account' : 'Delete organization'
59+
const text = isPersonalSettings
60+
? 'Erase my personal account and all my repositories.'
61+
: 'Erase organization and all its repositories.'
62+
963
return (
1064
<div className="flex flex-col gap-4">
11-
<h2 className="text-lg font-semibold">
12-
{isPersonalSettings ? 'Delete account' : 'Delete organization'}
13-
</h2>
14-
<Card>
15-
<p>
16-
{isPersonalSettings
17-
? 'Erase my personal account and all my repositories. '
18-
: 'Erase organization and all its repositories. '}
19-
<A
20-
to={{ pageName: 'support' }}
21-
hook="contact-support-link"
22-
isExternal
23-
>
24-
Contact support
25-
</A>
26-
</p>
65+
<h2 className="text-lg font-semibold">{title}</h2>
66+
<Card className="flex flex-col sm:flex-row">
67+
<div className="flex flex-1 flex-col gap-1">
68+
<p> {text} </p>
69+
</div>
70+
<div>
71+
<EraseOwnerButton
72+
isPersonalSettings={isPersonalSettings}
73+
isLoading={isLoading}
74+
setShowModal={setShowModal}
75+
/>
76+
<EraseOwnerModal
77+
isPersonalSettings={isPersonalSettings}
78+
isLoading={isLoading}
79+
showModal={showModal}
80+
closeModal={() => setShowModal(false)}
81+
eraseOwner={eraseOwner}
82+
/>
83+
</div>
2784
</Card>
2885
</div>
2986
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import Button from 'ui/Button'
2+
import Modal from 'ui/Modal'
3+
4+
interface EraseOwnerModelProps {
5+
isPersonalSettings: boolean
6+
isLoading: boolean
7+
showModal: boolean
8+
closeModal: () => void
9+
eraseOwner: () => void
10+
}
11+
12+
function EraseOwnerModal({
13+
isPersonalSettings,
14+
closeModal,
15+
eraseOwner,
16+
isLoading,
17+
showModal,
18+
}: EraseOwnerModelProps) {
19+
const title = isPersonalSettings
20+
? 'Are you sure you want to delete your personal account?'
21+
: 'Are you sure you want to erase this organization?'
22+
let text = isPersonalSettings
23+
? 'This action will delete all personal data, including login information and personal tokens.'
24+
: 'This action will delete all organization content and associated tokens.'
25+
text +=
26+
' It will also erase all of the repositories, including all of their contents.'
27+
text +=
28+
' This action is irreversible and if you proceed, you will permanently erase all of the associated content.'
29+
const button = isPersonalSettings
30+
? 'Erase Personal Account'
31+
: 'Erase Organization'
32+
33+
return (
34+
<Modal
35+
isOpen={showModal}
36+
onClose={closeModal}
37+
title={title}
38+
body={<p>{text}</p>}
39+
footer={
40+
<div className="flex gap-2">
41+
<div>
42+
<Button hook="close-modal" onClick={closeModal}>
43+
Cancel
44+
</Button>
45+
</div>
46+
<div>
47+
<Button
48+
isLoading={isLoading}
49+
hook="erase-owner-content"
50+
variant="danger"
51+
onClick={async () => {
52+
await eraseOwner()
53+
closeModal()
54+
}}
55+
>
56+
{button}
57+
</Button>
58+
</div>
59+
</div>
60+
}
61+
/>
62+
)
63+
}
64+
65+
export default EraseOwnerModal

0 commit comments

Comments
 (0)