LocalDropdown.tsx100 lines · main
1import { FlaskConical, Settings } from 'lucide-react'
2import { useTheme } from 'next-themes'
3import Link from 'next/link'
4import { useRouter } from 'next/router'
5import {
6 cn,
7 DropdownMenu,
8 DropdownMenuContent,
9 DropdownMenuGroup,
10 DropdownMenuItem,
11 DropdownMenuLabel,
12 DropdownMenuRadioGroup,
13 DropdownMenuRadioItem,
14 DropdownMenuSeparator,
15 DropdownMenuTrigger,
16 singleThemes,
17 Theme,
18} from 'ui'
19
20import { ButtonTooltip } from '../ui/ButtonTooltip'
21import { useFeaturePreviewModal } from './App/FeaturePreview/FeaturePreviewContext'
22import { ProfileImage } from '@/components/ui/ProfileImage'
23import { useTrack } from '@/lib/telemetry/track'
24import { useAppStateSnapshot } from '@/state/app-state'
25
26export const LocalDropdown = ({
27 triggerClassName,
28 contentClassName,
29}: {
30 triggerClassName?: string
31 contentClassName?: string
32}) => {
33 const router = useRouter()
34 const { theme, setTheme } = useTheme()
35 const appStateSnapshot = useAppStateSnapshot()
36 const { toggleFeaturePreviewModal } = useFeaturePreviewModal()
37 const track = useTrack()
38
39 return (
40 <DropdownMenu
41 onOpenChange={(open) => {
42 if (open) track('header_local_dropdown_opened')
43 }}
44 >
45 <DropdownMenuTrigger className={cn('border shrink-0 px-3', triggerClassName)} asChild>
46 <ButtonTooltip
47 type="default"
48 className="[&>span]:flex px-0 py-0 rounded-full overflow-hidden h-8 w-8"
49 tooltip={{ content: { text: 'Settings' } }}
50 >
51 <ProfileImage className="w-8 h-8 rounded-md" />
52 <span className="sr-only">Settings</span>
53 </ButtonTooltip>
54 </DropdownMenuTrigger>
55 <DropdownMenuContent side="bottom" align="end" className={cn('w-44', contentClassName)}>
56 <DropdownMenuItem className="flex gap-2 cursor-pointer" asChild>
57 <Link
58 href="/account/me"
59 onClick={() => {
60 if (router.pathname !== '/account/me') {
61 appStateSnapshot.setLastRouteBeforeVisitingAccountPage(router.asPath)
62 }
63 }}
64 >
65 <Settings size={14} strokeWidth={1.5} className="text-foreground-lighter" />
66 Preferences
67 </Link>
68 </DropdownMenuItem>
69 <DropdownMenuItem
70 className="flex gap-2 cursor-pointer"
71 onClick={() => toggleFeaturePreviewModal(true)}
72 onSelect={() => toggleFeaturePreviewModal(true)}
73 >
74 <FlaskConical size={14} strokeWidth={1.5} className="text-foreground-lighter" />
75 Feature previews
76 </DropdownMenuItem>
77 <DropdownMenuSeparator />
78 <DropdownMenuGroup>
79 <DropdownMenuLabel>Theme</DropdownMenuLabel>
80 <DropdownMenuRadioGroup
81 value={theme}
82 onValueChange={(value) => {
83 setTheme(value)
84 }}
85 >
86 {singleThemes.map((theme: Theme) => (
87 <DropdownMenuRadioItem
88 key={theme.value}
89 value={theme.value}
90 className="cursor-pointer"
91 >
92 {theme.name}
93 </DropdownMenuRadioItem>
94 ))}
95 </DropdownMenuRadioGroup>
96 </DropdownMenuGroup>
97 </DropdownMenuContent>
98 </DropdownMenu>
99 )
100}