aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaheshtheDev <[email protected]>2026-01-06 18:39:04 +0000
committerMaheshtheDev <[email protected]>2026-01-06 18:39:04 +0000
commit6a8c8a5091adef9a0d747a2e7878f4d4c844b4dd (patch)
tree18d83cb925ee71b8ed9fa79f91ba595465f2091b
parentchore: chatid for posthog (#650) (diff)
downloadsupermemory-6a8c8a5091adef9a0d747a2e7878f4d4c844b4dd.tar.xz
supermemory-6a8c8a5091adef9a0d747a2e7878f4d4c844b4dd.zip
feat: delete org consumer (#654)01-05-feat_delete_org_consumer
-rw-r--r--apps/web/components/views/profile.tsx117
1 files changed, 117 insertions, 0 deletions
diff --git a/apps/web/components/views/profile.tsx b/apps/web/components/views/profile.tsx
index c60f4310..62297358 100644
--- a/apps/web/components/views/profile.tsx
+++ b/apps/web/components/views/profile.tsx
@@ -1,12 +1,24 @@
"use client"
import { useAuth } from "@lib/auth-context"
+import { authClient } from "@lib/auth"
import {
fetchConnectionsFeature,
fetchMemoriesFeature,
fetchSubscriptionStatus,
} from "@lib/queries"
+import {
+ AlertDialog,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+ AlertDialogTrigger,
+} from "@repo/ui/components/alert-dialog"
import { Button } from "@repo/ui/components/button"
+import { Input } from "@repo/ui/components/input"
import { Skeleton } from "@repo/ui/components/skeleton"
import { HeadingH3Bold } from "@repo/ui/text/heading/heading-h3-bold"
import { useCustomer } from "autumn-js/react"
@@ -20,13 +32,19 @@ import {
} from "lucide-react"
import { motion } from "motion/react"
import Link from "next/link"
+import { useRouter } from "next/navigation"
import { useState } from "react"
export function ProfileView() {
const { user: session, org } = useAuth()
const organizations = org
const autumn = useCustomer()
+ const router = useRouter()
const [isLoading, setIsLoading] = useState(false)
+ const [isDeleting, setIsDeleting] = useState(false)
+ const [deleteConfirmation, setDeleteConfirmation] = useState("")
+ const [deleteDialogOpen, setDeleteDialogOpen] = useState(false)
+ const [deleteError, setDeleteError] = useState<string | null>(null)
const {
data: status = {
@@ -74,6 +92,31 @@ export function ProfileView() {
})
}
+ const handleDeleteAccount = async () => {
+ if (deleteConfirmation !== "DELETE" || !org?.id) return
+
+ setIsDeleting(true)
+ setDeleteError(null)
+
+ try {
+ await authClient.organization.delete({
+ organizationId: org.id,
+ })
+
+ await authClient.signOut()
+
+ router.push("/login")
+ } catch (error) {
+ console.error("Failed to delete account:", error)
+ setDeleteError(
+ error instanceof Error
+ ? error.message
+ : "Failed to delete account. Please try again or contact support.",
+ )
+ setIsDeleting(false)
+ }
+ }
+
if (session?.isAnonymous) {
return (
<div className="space-y-4">
@@ -364,6 +407,80 @@ export function ProfileView() {
)}
</div>
)}
+
+ {/* Delete Account */}
+ {!session?.isAnonymous && org && (
+ <div className="pt-4 mt-2">
+ <div className="flex items-center justify-between">
+ <div>
+ <p className="text-sm text-foreground">Delete account</p>
+ <p className="text-xs text-muted-foreground">
+ Permanently delete your data and cancel subscription
+ </p>
+ </div>
+ <AlertDialog
+ open={deleteDialogOpen}
+ onOpenChange={setDeleteDialogOpen}
+ >
+ <AlertDialogTrigger asChild>
+ <Button
+ variant="ghost"
+ size="sm"
+ className="text-red-500 hover:text-red-600 hover:bg-red-500/10"
+ >
+ Delete
+ </Button>
+ </AlertDialogTrigger>
+ <AlertDialogContent>
+ <AlertDialogHeader>
+ <AlertDialogTitle>Delete account?</AlertDialogTitle>
+ <AlertDialogDescription asChild>
+ <div className="space-y-3">
+ <p>
+ This will permanently delete your memories, connections,
+ settings, and cancel any subscriptions.
+ </p>
+ <p className="text-foreground">
+ Type{" "}
+ <code className="bg-muted px-1.5 py-0.5 rounded text-red-500">
+ DELETE
+ </code>{" "}
+ to confirm:
+ </p>
+ </div>
+ </AlertDialogDescription>
+ </AlertDialogHeader>
+ <Input
+ value={deleteConfirmation}
+ onChange={(e) => setDeleteConfirmation(e.target.value)}
+ placeholder="DELETE"
+ autoComplete="off"
+ />
+ {deleteError && (
+ <p className="text-sm text-red-500">{deleteError}</p>
+ )}
+ <AlertDialogFooter>
+ <AlertDialogCancel
+ onClick={() => {
+ setDeleteConfirmation("")
+ setDeleteError(null)
+ }}
+ >
+ Cancel
+ </AlertDialogCancel>
+ <Button
+ variant="destructive"
+ onClick={handleDeleteAccount}
+ disabled={deleteConfirmation !== "DELETE" || isDeleting}
+ >
+ {isDeleting ? "Deleting..." : "Delete account"}
+ </Button>
+ </AlertDialogFooter>
+ </AlertDialogContent>
+ </AlertDialog>
+ </div>
+ </div>
+ )}
</div>
)
}