import { Button } from "@ui/components/button" import { Logo, LogoFull } from "@ui/assets/Logo" import Link from "next/link" import { MoonIcon, Plus, SunIcon, MonitorIcon, User, CreditCard, Chrome, LogOut, WaypointsIcon, Gauge, HistoryIcon, Trash2, X, Check, } from "lucide-react" import { DropdownMenuContent, DropdownMenuTrigger, DropdownMenuSeparator, DropdownMenuLabel, } from "@ui/components/dropdown-menu" import { DropdownMenuItem } from "@ui/components/dropdown-menu" import { DropdownMenu } from "@ui/components/dropdown-menu" import { Avatar, AvatarFallback, AvatarImage } from "@ui/components/avatar" import { Tooltip, TooltipContent, TooltipTrigger } from "@ui/components/tooltip" import { useAuth } from "@lib/auth-context" import { ConnectAIModal } from "./connect-ai-modal" import { useTheme } from "next-themes" import { usePathname, useRouter, useSearchParams } from "next/navigation" import { MCPIcon } from "./menu" import { authClient } from "@lib/auth" import { analytics } from "@/lib/analytics" import { useGraphModal, usePersistentChat, useProject } from "@/stores" import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, } from "@ui/components/dialog" import { ScrollArea } from "@ui/components/scroll-area" import { formatDistanceToNow } from "date-fns" import { cn } from "@lib/utils" import { useEffect, useMemo, useState } from "react" export function Header({ onAddMemory }: { onAddMemory?: () => void }) { const { user } = useAuth() const searchParams = useSearchParams() const { theme, setTheme } = useTheme() const router = useRouter() const { setIsOpen: setGraphModalOpen } = useGraphModal() const { getCurrentChat, conversations, currentChatId, setCurrentChatId, deleteConversation, } = usePersistentChat() const { selectedProject } = useProject() const pathname = usePathname() const [isDialogOpen, setIsDialogOpen] = useState(false) const [confirmingDeleteId, setConfirmingDeleteId] = useState( null, ) const [mcpModalOpen, setMcpModalOpen] = useState(false) const [mcpInitialClient, setMcpInitialClient] = useState<"mcp-url" | null>( null, ) const [mcpInitialTab, setMcpInitialTab] = useState< "oneClick" | "manual" | null >(null) const sorted = useMemo(() => { return [...conversations].sort((a, b) => a.lastUpdated < b.lastUpdated ? 1 : -1, ) }, [conversations]) useEffect(() => { const mcpParam = searchParams.get("mcp") if (mcpParam === "manual") { setMcpInitialClient("mcp-url") setMcpInitialTab("manual") setMcpModalOpen(true) const newSearchParams = new URLSearchParams(searchParams.toString()) newSearchParams.delete("mcp") const newUrl = `${ window.location.pathname }${newSearchParams.toString() ? `?${newSearchParams.toString()}` : ""}` window.history.replaceState({}, "", newUrl) } }, [searchParams]) function handleNewChat() { analytics.newChatStarted() const newId = crypto.randomUUID() setCurrentChatId(newId) router.push(`/chat/${newId}`) setIsDialogOpen(false) } function formatRelativeTime(isoString: string): string { return formatDistanceToNow(new Date(isoString), { addSuffix: true }) } const handleSignOut = () => { analytics.userSignedOut() authClient.signOut() router.push("/login") } return (
{getCurrentChat()?.title && pathname.includes("/chat") ? (
{getCurrentChat()?.title}
) : ( <> )}
{ setIsDialogOpen(open) if (open) { analytics.chatHistoryViewed() } if (!open) { setConfirmingDeleteId(null) } }} >

Chat History

Conversations Project{" "} {selectedProject}
{sorted.map((c) => { const isActive = c.id === currentChatId return (
) : ( )} ) })} {sorted.length === 0 && (
No conversations yet
)}

Graph View

Connect to AI (MCP)

{user?.name?.charAt(0)}

{user?.name}

{user?.email}

router.push("/settings")}> Profile router.push("/settings/billing")} > Billing router.push("/settings/integrations")} > Integrations { window.open( "https://chromewebstore.google.com/detail/supermemory/afpgkkipfdpeaflnpoaffkcankadgjfc", "_blank", "noopener,noreferrer", ) }} > Chrome Extension e.preventDefault()} > Theme
handleSignOut()}> Logout
) }