mirror of
https://github.com/supabase/supabase.git
synced 2026-10-13 05:09:12 +03:00
When user logs out from the user dropdown, they're redirected to the sign-in page via the withAuth redirect, which means that the returnTo param is used -- but if the user _intentionally_ logged out, this might not be the right behavior, i.e., if they want to log in to another account. Instead, if they chose to log out, we shouldn't use the returnTo param. Since the /logout page already implements this behavior, I changed "Log out" button to just route to the /logout page.
145 lines
5.0 KiB
TypeScript
145 lines
5.0 KiB
TypeScript
import { Command, FlaskConical, Loader2, Settings } from 'lucide-react'
|
|
import { useTheme } from 'next-themes'
|
|
import Link from 'next/link'
|
|
import { useRouter } from 'next/router'
|
|
|
|
import { ProfileImage } from 'components/ui/ProfileImage'
|
|
import { IS_PLATFORM } from 'lib/constants'
|
|
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
|
|
import { useProfileNameAndPicture } from 'lib/profile'
|
|
import { useAppStateSnapshot } from 'state/app-state'
|
|
import {
|
|
Button,
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuGroup,
|
|
DropdownMenuItem,
|
|
DropdownMenuLabel,
|
|
DropdownMenuRadioGroup,
|
|
DropdownMenuRadioItem,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuTrigger,
|
|
Theme,
|
|
singleThemes,
|
|
} from 'ui'
|
|
import { useCommandMenuOpenedTelemetry, useSetCommandMenuOpen } from 'ui-patterns/CommandMenu'
|
|
import { useFeaturePreviewModal } from './App/FeaturePreview/FeaturePreviewContext'
|
|
|
|
export function UserDropdown() {
|
|
const router = useRouter()
|
|
const { theme, setTheme } = useTheme()
|
|
const appStateSnapshot = useAppStateSnapshot()
|
|
const profileShowEmailEnabled = useIsFeatureEnabled('profile:show_email')
|
|
const { username, avatarUrl, primaryEmail, isLoading } = useProfileNameAndPicture()
|
|
|
|
const setCommandMenuOpen = useSetCommandMenuOpen()
|
|
const sendTelemetry = useCommandMenuOpenedTelemetry()
|
|
const { openFeaturePreviewModal } = useFeaturePreviewModal()
|
|
|
|
const handleCommandMenuOpen = () => {
|
|
setCommandMenuOpen(true)
|
|
sendTelemetry()
|
|
}
|
|
|
|
return (
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild className="border flex-shrink-0 px-3">
|
|
<Button
|
|
type="default"
|
|
className="[&>span]:flex px-0 py-0 rounded-full overflow-hidden h-8 w-8"
|
|
>
|
|
{isLoading ? (
|
|
<div className="w-full h-full flex items-center justify-center">
|
|
<Loader2 className="animate-spin text-foreground-lighter" size={16} />
|
|
</div>
|
|
) : (
|
|
<ProfileImage alt={username} src={avatarUrl} className="w-8 h-8 rounded-md" />
|
|
)}
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
|
|
<DropdownMenuContent side="bottom" align="end">
|
|
{IS_PLATFORM && (
|
|
<>
|
|
<div className="px-2 py-1 flex flex-col gap-0 text-sm">
|
|
{!!username && (
|
|
<>
|
|
<span title={username} className="w-full text-left text-foreground truncate">
|
|
{username}
|
|
</span>
|
|
{primaryEmail !== username && profileShowEmailEnabled && (
|
|
<span
|
|
title={primaryEmail}
|
|
className="w-full text-left text-foreground-light text-xs truncate"
|
|
>
|
|
{primaryEmail}
|
|
</span>
|
|
)}
|
|
</>
|
|
)}
|
|
</div>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuGroup>
|
|
<DropdownMenuItem className="flex gap-2" asChild>
|
|
<Link
|
|
href="/account/me"
|
|
onClick={() => {
|
|
if (router.pathname !== '/account/me') {
|
|
appStateSnapshot.setLastRouteBeforeVisitingAccountPage(router.asPath)
|
|
}
|
|
}}
|
|
>
|
|
<Settings size={14} strokeWidth={1.5} className="text-foreground-lighter" />
|
|
Account preferences
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem
|
|
className="flex gap-2"
|
|
onClick={openFeaturePreviewModal}
|
|
onSelect={openFeaturePreviewModal}
|
|
>
|
|
<FlaskConical size={14} strokeWidth={1.5} className="text-foreground-lighter" />
|
|
Feature previews
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem className="flex gap-2" onClick={handleCommandMenuOpen}>
|
|
<Command size={14} strokeWidth={1.5} className="text-foreground-lighter" />
|
|
Command menu
|
|
</DropdownMenuItem>
|
|
<DropdownMenuSeparator />
|
|
</DropdownMenuGroup>
|
|
</>
|
|
)}
|
|
<DropdownMenuGroup>
|
|
<DropdownMenuLabel>Theme</DropdownMenuLabel>
|
|
<DropdownMenuRadioGroup
|
|
value={theme}
|
|
onValueChange={(value) => {
|
|
setTheme(value)
|
|
}}
|
|
>
|
|
{singleThemes.map((theme: Theme) => (
|
|
<DropdownMenuRadioItem key={theme.value} value={theme.value}>
|
|
{theme.name}
|
|
</DropdownMenuRadioItem>
|
|
))}
|
|
</DropdownMenuRadioGroup>
|
|
</DropdownMenuGroup>
|
|
{IS_PLATFORM && (
|
|
<>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuGroup>
|
|
<DropdownMenuItem
|
|
onSelect={() => {
|
|
router.push('/logout')
|
|
}}
|
|
>
|
|
Log out
|
|
</DropdownMenuItem>
|
|
</DropdownMenuGroup>
|
|
</>
|
|
)}
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
)
|
|
}
|