Skip to content

Commit

Permalink
[TOOL-3525] Dashboard: Add Delete Account in account settings page
Browse files Browse the repository at this point in the history
  • Loading branch information
MananTank committed Feb 27, 2025
1 parent 39a8afd commit 3dbafe9
Show file tree
Hide file tree
Showing 8 changed files with 257 additions and 49 deletions.
17 changes: 17 additions & 0 deletions apps/dashboard/src/@/api/team.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,23 @@ export async function getTeams() {
return null;
}

export async function getDefaultTeam() {
const token = await getAuthToken();
if (!token) {
return null;
}

const res = await fetch(`${API_SERVER_URL}/v1/teams/~`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (res.ok) {
return (await res.json())?.result as Team;
}
return null;
}

type TeamNebulaWaitList = {
onWaitlist: boolean;
createdAt: null | string;
Expand Down
40 changes: 29 additions & 11 deletions apps/dashboard/src/@/components/blocks/DangerSettingCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { useState } from "react";
import { cn } from "../../lib/utils";
import { DynamicHeight } from "../ui/DynamicHeight";

export function DangerSettingCard(props: {
title: string;
Expand All @@ -24,9 +26,14 @@ export function DangerSettingCard(props: {
confirmationDialog: {
title: string;
description: React.ReactNode;
children?: React.ReactNode;
onClose?: () => void;
};
children?: React.ReactNode;
}) {
const [isConfirmationDialogOpen, setIsConfirmationDialogOpen] =
useState(false);

return (
<div
className={cn(
Expand All @@ -50,7 +57,15 @@ export function DangerSettingCard(props: {
props.footerClassName,
)}
>
<Dialog>
<Dialog
open={isConfirmationDialogOpen}
onOpenChange={(v) => {
setIsConfirmationDialogOpen(v);
if (!v) {
props.confirmationDialog.onClose?.();
}
}}
>
<DialogTrigger asChild>
<Button
variant="destructive"
Expand All @@ -66,17 +81,20 @@ export function DangerSettingCard(props: {
className="z-[10001] overflow-hidden p-0"
dialogOverlayClassName="z-[10000]"
>
<div className="p-6">
<DialogHeader className="pr-10">
<DialogTitle className="leading-snug">
{props.confirmationDialog.title}
</DialogTitle>
<DynamicHeight>
<div className="p-6">
<DialogHeader className="pr-10">
<DialogTitle className="leading-snug">
{props.confirmationDialog.title}
</DialogTitle>

<DialogDescription>
{props.confirmationDialog.description}
</DialogDescription>
</DialogHeader>
</div>
<DialogDescription>
{props.confirmationDialog.description}
</DialogDescription>
</DialogHeader>
{props.confirmationDialog.children}
</div>
</DynamicHeight>

<div className="flex justify-end gap-4 border-t bg-card p-6 lg:gap-2">
<DialogClose asChild>
Expand Down
29 changes: 28 additions & 1 deletion apps/dashboard/src/app/account/settings/AccountSettingsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
"use client";

import { redirectToBillingPortal } from "@/actions/billing";
import { confirmEmailWithOTP } from "@/actions/confirmEmail";
import { apiServerProxy } from "@/actions/proxies";
import { updateAccount } from "@/actions/updateAccount";
import { useDashboardRouter } from "@/lib/DashboardRouter";
import type { Account } from "@3rdweb-sdk/react/hooks/useApi";
import type { ThirdwebClient } from "thirdweb";
import { upload } from "thirdweb/storage";
import { doLogout } from "../../login/auth-actions";
import { AccountSettingsPageUI } from "./AccountSettingsPageUI";

export function AccountSettingsPage(props: {
account: Account;
client: ThirdwebClient;
defaultTeamSlug: string;
defaultTeamName: string;
}) {
const router = useDashboardRouter();
return (
Expand All @@ -25,8 +30,30 @@ export function AccountSettingsPage(props: {

<div className="container max-w-[950px] grow pt-8 pb-20">
<AccountSettingsPageUI
hideDeleteAccount
client={props.client}
defaultTeamSlug={props.defaultTeamSlug}
defaultTeamName={props.defaultTeamName}
onAccountDeleted={async () => {
await doLogout();
router.replace("/login");
}}
deleteAccount={async () => {
// TODO - test this once the API is functional
try {
const res = await apiServerProxy({
method: "DELETE",
pathname: "/v1/account",
});

return {
status: res.status,
};
} catch (error) {
console.error(error);
return { status: 500 };
}
}}
redirectToBillingPortal={redirectToBillingPortal}
updateAccountAvatar={async (file) => {
let uri: string | undefined = undefined;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { Checkbox, CheckboxWithLabel } from "@/components/ui/checkbox";
import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { getThirdwebClient } from "@/constants/thirdweb.server";
import type { Meta, StoryObj } from "@storybook/react";
import { useState } from "react";
Expand Down Expand Up @@ -40,6 +48,13 @@ function Variants() {
const [isVerifiedEmail, setIsVerifiedEmail] = useState(true);
const [sendEmailFails, setSendEmailFails] = useState(false);
const [emailConfirmationFails, setEmailConfirmationFails] = useState(false);
const [deleteAccountStatusResponse, setDeleteAccountStatusResponse] =
useState<400 | 402 | 500 | 200>(200);

const deleteAccountStub = async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return { status: deleteAccountStatusResponse };
};

return (
<div className="container flex max-w-[1132px] flex-col gap-10 py-10">
Expand Down Expand Up @@ -67,9 +82,37 @@ function Variants() {
/>
Email Confirmation Fails
</CheckboxWithLabel>

<div className="mt-3 flex flex-col gap-2">
<Label>Delete Account Response</Label>
<Select
value={String(deleteAccountStatusResponse)}
onValueChange={(value) =>
setDeleteAccountStatusResponse(
Number(value) as 400 | 402 | 500 | 200,
)
}
>
<SelectTrigger className="min-w-[320px]">
<SelectValue placeholder="Select status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="200">200 - Success</SelectItem>
<SelectItem value="400">400 - Active Subscriptions</SelectItem>
<SelectItem value="402">402 - Unpaid Invoices</SelectItem>
<SelectItem value="500">500 - Unknown Error</SelectItem>
</SelectContent>
</Select>
</div>
</div>

<AccountSettingsPageUI
defaultTeamSlug="foo"
defaultTeamName="Foo"
redirectToBillingPortal={async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return { status: 200 };
}}
account={{
name: "John Doe",
email: "[email protected]",
Expand All @@ -96,6 +139,10 @@ function Variants() {
throw new Error("Email already exists");
}
}}
deleteAccount={deleteAccountStub}
onAccountDeleted={() => {
console.log("Account deleted");
}}
/>
<Toaster richColors />
</div>
Expand Down
Loading

0 comments on commit 3dbafe9

Please sign in to comment.