"use client"
import { dmSans125ClassName } from "@/lib/fonts"
import { cn } from "@lib/utils"
import { useAuth } from "@lib/auth-context"
import { useOrgSummaries } from "@/hooks/use-org-summaries"
import { Avatar, AvatarFallback, AvatarImage } from "@ui/components/avatar"
import {
PLAN_DISPLAY_NAMES,
PLAN_RANK,
useTokenUsage,
type PlanType,
} from "@/hooks/use-token-usage"
import { Popover, PopoverContent, PopoverTrigger } from "@ui/components/popover"
import { useCustomer } from "autumn-js/react"
import { Check, LoaderIcon, ChevronDown, Building2, Users } from "lucide-react"
import { useMemo, useState } from "react"
function SectionTitle({ children }: { children: React.ReactNode }) {
return (
{children}
)
}
function SettingsCard({ children }: { children: React.ReactNode }) {
return (
{children}
)
}
/** Matches ACTIVE / RECOMMENDED pills in billing settings. */
const orgPlanBadgeBase = cn(
dmSans125ClassName(),
"inline-flex h-[18px] min-w-[42px] shrink-0 items-center justify-center rounded-[3px] px-1.5 text-[10px] uppercase",
)
const ORG_PLAN_BADGE_STYLES: Record = {
free: "bg-[#2E353D] font-mono font-medium tracking-[0.12em] text-[#A3A3A3]",
pro: "bg-[#4BA0FA] font-bold tracking-[0.36px] text-[#00171A]",
scale: "bg-[#0054AD] font-bold tracking-[0.36px] text-[#FAFAFA]",
enterprise: "bg-[#FAFAFA] font-bold tracking-[0.36px] text-[#0D121A]",
}
function OrgPlanBadge({ plan }: { plan: PlanType }) {
return (
{PLAN_DISPLAY_NAMES[plan]}
)
}
const ROLE_LABELS: Record = {
owner: "Owner",
admin: "Admin",
member: "Member",
}
function formatRole(role: string): string {
const r = role?.toLowerCase() ?? ""
if (ROLE_LABELS[r]) return ROLE_LABELS[r]
return r ? r.charAt(0).toUpperCase() + r.slice(1) : "Member"
}
function RolePill({ role }: { role: string }) {
const r = role?.toLowerCase() ?? ""
const isOwner = r === "owner"
return (
{formatRole(role)}
)
}
function resolveOrgPlan(
orgId: string,
isCurrent: boolean,
currentPlan: PlanType,
planByOrgId: Map,
): PlanType {
const fromSummary = planByOrgId.get(orgId)
if (fromSummary) return fromSummary
if (isCurrent) return currentPlan
return "free"
}
export default function Account() {
const { user, org, organizations: allOrgs, setActiveOrg } = useAuth()
const autumn = useCustomer()
const [switchingOrgId, setSwitchingOrgId] = useState(null)
const [orgMenuOpen, setOrgMenuOpen] = useState(false)
const canSwitchOrg = (allOrgs?.length ?? 0) > 1
const { data: orgSummaries } = useOrgSummaries()
const handleOrgSwitch = async (orgSlug: string, orgId: string) => {
if (orgId === org?.id) return
setSwitchingOrgId(orgId)
try {
await setActiveOrg(orgSlug)
window.location.reload()
} catch (error) {
console.error("Failed to switch organization:", error)
setSwitchingOrgId(null)
}
}
const { currentPlan } = useTokenUsage(autumn)
const planByOrgId = useMemo(() => {
const map = new Map()
for (const summary of orgSummaries ?? []) {
map.set(summary.orgId, summary.plan)
}
return map
}, [orgSummaries])
const sortedOrgsForMenu = useMemo(() => {
if (!allOrgs?.length) return []
return [...allOrgs].sort((a, b) => {
const planA = resolveOrgPlan(
a.id,
a.id === org?.id,
currentPlan,
planByOrgId,
)
const planB = resolveOrgPlan(
b.id,
b.id === org?.id,
currentPlan,
planByOrgId,
)
const rankDiff = PLAN_RANK[planB] - PLAN_RANK[planA]
if (rankDiff !== 0) return rankDiff
return a.name.localeCompare(b.name)
})
}, [allOrgs, org?.id, currentPlan, planByOrgId])
const memberSince = user?.createdAt
? new Date(user.createdAt).toLocaleDateString("en-US", {
month: "short",
year: "numeric",
})
: "—"
return (
Profile Details
{/* Avatar + Name/Email */}
{user?.name?.charAt(0) ?? "U"}
{user?.name ?? "—"}
{user?.email ?? "—"}
Organization
{
if (canSwitchOrg) setOrgMenuOpen(open)
}}
>
{org?.name ?? "Personal"}
{canSwitchOrg && (
)}
{canSwitchOrg && (
{sortedOrgsForMenu.map((organization) => {
const isCurrent = organization.id === org?.id
const isSwitching = switchingOrgId === organization.id
const plan = resolveOrgPlan(
organization.id,
isCurrent,
currentPlan,
planByOrgId,
)
return (
)
})}
)}
Member since
{memberSince}
Team members
{(org?.members?.length ?? 0) > 0 && (
{org?.members?.length}{" "}
{org?.members?.length === 1 ? "member" : "members"}
)}
{org?.members && org.members.length > 0 ? (
{[...org.members]
.sort((a, b) => {
const rolePriority = (r: string) =>
r === "owner" ? 0 : r === "admin" ? 1 : 2
const diff =
rolePriority(a.role.toLowerCase()) -
rolePriority(b.role.toLowerCase())
if (diff !== 0) return diff
return (a.user?.name ?? "").localeCompare(b.user?.name ?? "")
})
.map((m, idx) => {
const isYou = m.userId === user?.id
const name = m.user?.name ?? m.user?.email ?? "Unknown"
return (
- 0 && "border-t border-white/[0.04]",
)}
>
{(name.charAt(0) || "U").toUpperCase()}
{name}
{isYou && (
You
)}
{m.user?.email && (
{m.user.email}
)}
)
})}
) : (
Just you for now
Invite teammates from your organization settings.
)}
)
}