import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import {
BookOpen,
Flag,
LogOut,
Settings,
type LucideIcon,
UserPlus,
} from "lucide-react";
import { hidesCompanyPage, type DeploymentMode } from "@paperclipai/shared";
import { Link } from "@/lib/router";
import { authApi } from "@/api/auth";
import { queryKeys } from "@/lib/queryKeys";
import { useCloudInstance } from "@/hooks/useCloudInstance";
import { useCloudInviteUrl } from "@/hooks/useCloudInviteUrl";
import { useCanInviteCompanyMembers } from "@/hooks/useCompanyInviteAccess";
import { useHiddenSettings } from "@/hooks/useHiddenSettings";
import { useSignOut } from "@/hooks/useSignOut";
import { useStagingCommit } from "@/hooks/useStagingCommit";
import { userProfilePath } from "@/lib/userProfileLinks";
import { useSidebar } from "../context/SidebarContext";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { cn, SIDEBAR_RAIL_HIDDEN_LABEL } from "../lib/utils";
import { ThemeToggle } from "./ThemeToggle";
import { SidebarServerInfo } from "./SidebarServerInfo";
const INVITES_PATH = "/company/settings/members?tab=invites";
const DOCS_URL = "https://docs.paperclip.ing/";
const FEEDBACK_URL = "https://paperclip.ing/feedback";
interface SidebarAccountMenuProps {
deploymentMode?: DeploymentMode;
open?: boolean;
onOpenChange?: (open: boolean) => void;
/** Contextual navigation occupies a full sidebar even if the saved global nav mode is collapsed. */
forceExpanded?: boolean;
}
interface MenuActionProps {
label: string;
icon: LucideIcon;
onClick?: () => void;
href?: string;
/** Opens `href` in a new tab (docs and other off-product links). */
external?: boolean;
/**
* Leaves the app in the current tab with a full navigation. Cloud links
* must use this: the cloud harness shadows those paths on tenant hosts, so
* the in-app router can never reach them.
*/
topLevel?: boolean;
}
function deriveInitials(name: string) {
const parts = name.trim().split(/\s+/).filter(Boolean);
if (parts.length >= 2) {
return `${parts[0]?.[0] ?? ""}${parts[parts.length - 1]?.[0] ?? ""}`.toUpperCase();
}
return name.slice(0, 2).toUpperCase();
}
function MenuAction({
label,
icon: Icon,
onClick,
href,
external = false,
topLevel = false,
}: MenuActionProps) {
const className =
"flex h-(--profile-popover-row-height) w-full items-center gap-(--profile-popover-row-gap) rounded-lg px-2.5 text-left text-(length:--text-compact) font-medium leading-(--profile-popover-label-line-height) text-foreground transition-colors hover:bg-accent";
const content = (
<>