import { useDevToolbar } from 'dev-tools' import { FlaskConical, Loader2, ScrollText, User2 } from 'lucide-react' import { useTheme } from 'next-themes' import Link from 'next/link' import { useRouter } from 'next/router' import { useState } from 'react' import { cn, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger, singleThemes, } from 'ui' import { ButtonTooltip } from '../ui/ButtonTooltip' import { useFeaturePreviewModal } from './App/FeaturePreview/FeaturePreviewContext' import { DevToolbarMenuGroup } from './DevToolbarMenuGroup' import { TimezoneDropdown } from './UserDropdown/TimezoneDropdown' import { ProfileImage } from '@/components/ui/ProfileImage' import { UpgradePlanButton } from '@/components/ui/UpgradePlanButton' import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' import { useShowUpgradeCta } from '@/hooks/misc/useShowUpgradeCta' import { IS_PLATFORM } from '@/lib/constants' import { useProfileNameAndPicture } from '@/lib/profile' import { useTrack } from '@/lib/telemetry/track' import { useAppStateSnapshot } from '@/state/app-state' export function UserDropdown({ triggerClassName, contentClassName, }: { triggerClassName?: string contentClassName?: string }) { const router = useRouter() const { theme, setTheme } = useTheme() const appStateSnapshot = useAppStateSnapshot() const profileShowEmailEnabled = useIsFeatureEnabled('profile:show_email') const { username, avatarUrl, primaryEmail, isLoading } = useProfileNameAndPicture() const { toggleFeaturePreviewModal } = useFeaturePreviewModal() const track = useTrack() const { isAvailable: isDevToolbarAvailable } = useDevToolbar() const shouldShowSectionSeparator = IS_PLATFORM || isDevToolbarAvailable // The upgrade CTA is org-scoped, so only enable it on routes where an org is in scope. // Excludes /account/*, /organizations, /new, marketing routes, etc. Gating the hook here // also skips fetching organization data on routes where the CTA can't render. const isOrgScopedRoute = router.pathname.startsWith('/project/') || router.pathname.startsWith('/org/') const { showUpgradeCta } = useShowUpgradeCta({ enabled: isOrgScopedRoute }) const [isOpen, setIsOpen] = useState(false) return ( { setIsOpen(open) if (open) track('header_user_dropdown_opened') }} > {isLoading ? (
) : ( )}
{IS_PLATFORM && ( <>
{!!username ? ( <> {username} {primaryEmail !== username && profileShowEmailEnabled && ( {primaryEmail} )} ) : ( {primaryEmail} )}
{ if (router.pathname !== '/account/me') { appStateSnapshot.setLastRouteBeforeVisitingAccountPage(router.asPath) } }} > Account toggleFeaturePreviewModal(true)} > Feature previews Changelog )} {shouldShowSectionSeparator && } Theme { setTheme(value) }} > {singleThemes.map((theme) => ( {theme.name} ))} {showUpgradeCta && ( <>
{ track('upgrade_cta_clicked', { placement: 'user_dropdown' }) setIsOpen(false) }} />
)} {IS_PLATFORM && ( <> { router.push('/logout') }} > Log out )}
) }