Skip to content

Commit b920288

Browse files
committed
Merge branch 'develop' of https://github.com/outerbase/studio into develop
2 parents adff2e9 + 1f0cdff commit b920288

File tree

3 files changed

+52
-9
lines changed

3 files changed

+52
-9
lines changed

src/app/(outerbase)/account/account-footer.tsx

+37-8
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,21 @@ import {
66
Dialog,
77
DialogContent,
88
DialogDescription,
9+
DialogHeader,
10+
DialogTitle,
911
} from "@/components/ui/dialog";
1012
import { isValidEmail } from "@/lib/validation";
11-
import { DialogTitle } from "@radix-ui/react-dialog";
13+
import { deleteOuterbaseUser } from "@/outerbase-cloud/api-account";
1214
import { Check, Copy } from "lucide-react";
13-
import { useMemo, useState } from "react";
15+
import { useCallback, useMemo, useState } from "react";
16+
import { toast } from "sonner";
1417

1518
export default function AccountFooter() {
16-
const { session } = useSession();
19+
const { session, logout } = useSession();
1720
const [open, setOpen] = useState(false);
1821
const [copied, setCopied] = useState(false);
1922
const [email, setEmail] = useState("");
23+
const [loading, setLoading] = useState(false);
2024

2125
const copyToClipboard = async () => {
2226
if (!session) return;
@@ -27,16 +31,36 @@ export default function AccountFooter() {
2731
console.error("Failed to copy:", error);
2832
}
2933
};
34+
3035
const onClose = () => {
3136
setCopied(false);
3237
setOpen(false);
3338
setEmail("");
39+
setLoading(false);
3440
};
41+
42+
const onDeleteOuerbaseUser = useCallback(() => {
43+
setLoading(true);
44+
deleteOuterbaseUser()
45+
.then(() => {
46+
onClose();
47+
logout();
48+
})
49+
.catch((err) => {
50+
setLoading(false);
51+
toast.error(err.message);
52+
});
53+
}, [logout]);
54+
3555
const fullName = useMemo(() => {
3656
if (!session) return;
3757
return session?.user.first_name + " " + session?.user.last_name;
3858
}, [session]);
3959

60+
const disabled = useMemo(() => {
61+
return !isValidEmail(email) || email !== session?.user.email;
62+
}, [email, session]);
63+
4064
return (
4165
<>
4266
<Dialog
@@ -48,9 +72,12 @@ export default function AccountFooter() {
4872
}}
4973
>
5074
<DialogContent className="justify-items-start">
51-
<DialogTitle>
52-
Confirm deletion of {fullName}&apos; account
53-
</DialogTitle>
75+
<DialogHeader>
76+
<DialogTitle>
77+
Confirm deletion of {fullName}&apos; account
78+
</DialogTitle>
79+
</DialogHeader>
80+
5481
<DialogDescription className="text-base">
5582
Deleting this account will delete all Bases and Workspaces and
5683
revoke all connections made to your databases. All members will lose
@@ -76,9 +103,11 @@ export default function AccountFooter() {
76103
</Label>
77104
<div className="flex flex-row gap-5">
78105
<Button
79-
disabled={!isValidEmail(email)}
80-
onClick={onClose}
106+
loading={loading}
107+
disabled={disabled}
108+
onClick={onDeleteOuerbaseUser}
81109
variant="destructive"
110+
shape="base"
82111
title="I understand, delete my account"
83112
/>
84113
<Button variant="secondary" onClick={onClose} title="Cancel" />

src/app/(outerbase)/session-provider.tsx

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"use client";
2+
import { useRouter } from "next/navigation";
23
import {
34
createContext,
45
PropsWithChildren,
@@ -19,11 +20,13 @@ interface OuterebaseSessionContextProps {
1920
session: OuterbaseAPISession;
2021
user: OuterbaseAPIUser;
2122
};
23+
logout: () => void;
2224
refreshSession: () => Promise<void>;
2325
}
2426

2527
const OuterbaseSessionContext = createContext<OuterebaseSessionContextProps>({
2628
isLoading: true,
29+
logout: () => {},
2730
refreshSession: async () => {},
2831
});
2932

@@ -32,6 +35,7 @@ export function useSession() {
3235
}
3336

3437
export function OuterbaseSessionProvider({ children }: PropsWithChildren) {
38+
const router = useRouter();
3539
const token =
3640
typeof window !== "undefined" ? localStorage.getItem("ob-token") || "" : "";
3741

@@ -52,9 +56,15 @@ export function OuterbaseSessionProvider({ children }: PropsWithChildren) {
5256
await mutate("session-" + token);
5357
}, [token]);
5458

59+
const logout = useCallback(() => {
60+
localStorage.removeItem("session");
61+
localStorage.removeItem("ob-token");
62+
router.push("/signin");
63+
}, [router]);
64+
5565
return (
5666
<OuterbaseSessionContext.Provider
57-
value={{ session: data, isLoading, token, refreshSession }}
67+
value={{ session: data, isLoading, token, logout, refreshSession }}
5868
>
5969
{children}
6070
</OuterbaseSessionContext.Provider>

src/outerbase-cloud/api-account.ts

+4
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,7 @@ export async function verifyOuterbaseOTP(token: string) {
8484
export async function submitVerifyPhone2FA(id: string, data: { code: string }) {
8585
return await requestOuterbase(`/api/v1/me/phone/${id}/submit`, "POST", data);
8686
}
87+
88+
export async function deleteOuterbaseUser() {
89+
return await requestOuterbase("/api/v1/me", "DELETE");
90+
}

0 commit comments

Comments
 (0)