"use client" import { Logo } from "@ui/assets/Logo" import { useAuth } from "@lib/auth-context" import NovaOrb from "@/components/nova/nova-orb" import { useRef, useState } from "react" import { cn } from "@lib/utils" import { dmSansClassName, dmSans125ClassName } from "@/lib/fonts" import Account from "@/components/settings/account" import Billing from "@/components/settings/billing" import Integrations from "@/components/settings/integrations" import ConnectionsMCP from "@/components/settings/connections-mcp" import CompanyBrainConnections from "@/components/settings/company-brain-connections" import Support from "@/components/settings/support" import { ErrorBoundary } from "@/components/error-boundary" import { useRouter } from "next/navigation" import { useQuery } from "@tanstack/react-query" import { useIsMobile } from "@hooks/use-mobile" import { useLocalStorageUsername } from "@hooks/use-local-storage-username" import { LogOut, RotateCcw, Trash2, Sun, LoaderIcon, User as UserIcon, Zap, HelpCircle, CreditCard, ShieldAlert, ChevronRight, ArrowUpRight, Building2, } from "lucide-react" import { authClient } from "@lib/auth" import { Dialog, DialogContent, DialogClose } from "@ui/components/dialog" import { Popover, PopoverContent, PopoverTrigger } from "@ui/components/popover" import { useResetOrganization } from "@/hooks/use-reset-organization" import { useDeleteUserAccount } from "@/hooks/use-account-settings" import { useDeleteOrganization } from "@/hooks/use-delete-organization" import { SettingsOrgSwitcher } from "@/components/settings/settings-org-switcher" export const TABS = [ "account", "billing", "integrations", "connections", "company-brain", "support", ] as const export type SettingsTab = (typeof TABS)[number] type NavItem = { id: SettingsTab label: string description: string icon: React.ReactNode } const NAV_ITEMS: NavItem[] = [ { id: "account", label: "Account", description: "Your profile and organization", icon: , }, { id: "billing", label: "Billing", description: "Plan, usage and payments", icon: , }, { id: "integrations", label: "Integrations", description: "Save, sync and search across tools", icon: , }, { id: "connections", label: "Connections & MCP", description: "Drive, Notion, OneDrive, MCP", icon: , }, { id: "company-brain", label: "Company Brain", description: "GitHub & Linear — org and personal", icon: , }, { id: "support", label: "Support & Help", description: "Get help or share feedback", icon: , }, ] export function parseHashToTab(hash: string): SettingsTab { const cleaned = hash.replace("#", "").toLowerCase() return TABS.includes(cleaned as SettingsTab) ? (cleaned as SettingsTab) : "account" } function IdentityCard({ displayName }: { displayName: string }) { const firstName = displayName?.split(" ")[0] || "" return (

{firstName ? `${firstName}'s` : "Your"}

supermemory

) } export function SettingsContent({ activeTab, onTabChange, className, showIdentity = true, }: { activeTab: SettingsTab onTabChange: (tab: SettingsTab) => void className?: string showIdentity?: boolean }) { const { user, org, organizations, setActiveOrg, clearActiveOrg } = useAuth() const router = useRouter() const isMobile = useIsMobile() const localStorageUsername = useLocalStorageUsername() const [isResetDialogOpen, setIsResetDialogOpen] = useState(false) const [resetConfirmation, setResetConfirmation] = useState("") const resetOrganization = useResetOrganization() const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false) const [deleteEmailConfirm, setDeleteEmailConfirm] = useState("") const deleteUserAccount = useDeleteUserAccount() const [isDeleteOrgDialogOpen, setIsDeleteOrgDialogOpen] = useState(false) const [deleteOrgConfirm, setDeleteOrgConfirm] = useState("") const deleteOrgInputRef = useRef(null) const deleteOrganization = useDeleteOrganization() // Only owners can delete the organization. const activeMemberRoleQuery = useQuery({ queryKey: ["organization", org?.id, "active-member-role"], queryFn: async () => { const result = await authClient.organization.getActiveMember() if (result.error) { throw new Error(result.error.message ?? "Failed to load team role") } return result.data?.role ?? null }, enabled: !!org?.id, staleTime: 60_000, }) const isOwner = (activeMemberRoleQuery.data ?? "").toLowerCase() === "owner" const [dangerMenuOpen, setDangerMenuOpen] = useState(false) const openDeleteOrganizationDialog = () => { setDangerMenuOpen(false) window.requestAnimationFrame(() => { setIsDeleteOrgDialogOpen(true) }) } const displayName = user?.displayUsername || localStorageUsername || user?.name || user?.email?.split("@")[0] || "" const handleLogout = async () => { await authClient.signOut() router.push("/login") } const handleIntegrations = () => { void router.push("/integrations") } const handleDeleteAccount = async () => { if (deleteEmailConfirm !== user?.email) return deleteUserAccount.mutate( { confirmation: deleteEmailConfirm }, { onSuccess: () => { setIsDeleteDialogOpen(false) setDeleteEmailConfirm("") router.push("/login") }, }, ) } const handleDeleteOrganization = async () => { if (!org || deleteOrgConfirm !== org.name) return deleteOrganization.mutate(org.id, { onSuccess: async () => { setIsDeleteOrgDialogOpen(false) setDeleteOrgConfirm("") const remaining = (organizations ?? []).filter((o) => o.id !== org.id) if (remaining[0]) { await setActiveOrg(remaining[0].slug) window.location.href = "/" } else { await clearActiveOrg() window.location.href = "/onboarding" } }, }) } return ( <>
{/* Left rail */} {/* Content */}
Something went wrong loading this section.{" "}

} > {activeTab === "account" && } {activeTab === "billing" && } {activeTab === "integrations" && } {activeTab === "connections" && } {activeTab === "company-brain" && } {activeTab === "support" && }
{/* Reset data dialog */} {(() => { const confirmText = org?.name || user?.name || "" return ( { setIsResetDialogOpen(open) if (!open) setResetConfirmation("") }} >

Reset all data?

This permanently removes:

  • All documents and memories
  • All connections (Google Drive, Notion, etc.)
  • All custom spaces (default space stays)
  • Organization settings and filters

Your account and billing plan stay intact.{" "} This cannot be undone.

Type{" "} {confirmText || "your name"} {" "} to confirm:

setResetConfirmation(e.target.value)} placeholder={confirmText || "Your name"} autoComplete="off" className="w-full rounded-xl border border-[#2A2D35] bg-[#0D0F14] px-4 py-2.5 text-sm text-white placeholder:text-[#525D6E] focus:outline-none focus:border-[#C7991B]/50 transition-colors" />
) })()} {/* Delete account dialog */} { setIsDeleteDialogOpen(open) if (!open) setDeleteEmailConfirm("") }} >

Delete your account?

Permanently deletes all your data and cancels any active subscriptions.{" "} This cannot be undone.

Type your email{" "} {user?.email} to confirm:

setDeleteEmailConfirm(e.target.value)} placeholder={user?.email ?? "your@email.com"} className="w-full rounded-xl border border-[#2A2D35] bg-[#0D0F14] px-4 py-2.5 text-sm text-white placeholder:text-[#525D6E] focus:outline-none focus:border-[#C73B1B]/50 transition-colors" />
{/* Delete organization dialog */} { setIsDeleteOrgDialogOpen(open) if (!open) setDeleteOrgConfirm("") }} > { event.preventDefault() deleteOrgInputRef.current?.focus() }} >

Delete this organization?

Permanently deletes{" "} {org?.name || "this organization"} {" "} — its documents, spaces, connections, and members.{" "} This cannot be undone.

Type {org?.name} to confirm:

setDeleteOrgConfirm(e.target.value)} placeholder={org?.name ?? "Organization name"} autoComplete="off" className="w-full rounded-xl border border-[#2A2D35] bg-[#0D0F14] px-4 py-2.5 text-sm text-white placeholder:text-[#525D6E] focus:outline-none focus:border-[#C73B1B]/50 transition-colors" />
) }