mirror of
https://github.com/langgenius/dify.git
synced 2026-08-28 18:24:32 +08:00
104 lines
3.9 KiB
TypeScript
104 lines
3.9 KiB
TypeScript
'use client'
|
|
|
|
import type { ReactElement } from 'react'
|
|
import { Avatar } from '@langgenius/dify-ui/avatar'
|
|
import { cn } from '@langgenius/dify-ui/cn'
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuTrigger,
|
|
} from '@langgenius/dify-ui/dropdown-menu'
|
|
import { useAtomValue } from 'jotai'
|
|
import { useState } from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import { resetUser } from '@/app/components/base/amplitude/utils'
|
|
import { useSetEducationExpiredHasNoticed, useSetEducationReverifyHasNoticed, useSetEducationReverifyPrevExpireAt } from '@/app/education-apply/storage'
|
|
import { userProfileAtom } from '@/context/account-state'
|
|
import { langGeniusVersionInfoAtom } from '@/context/version-state'
|
|
import { useRouter } from '@/next/navigation'
|
|
import { useLogout } from '@/service/use-common'
|
|
import AccountAbout from '../account-about'
|
|
import { DefaultMenuContent } from './default-menu-content'
|
|
import { MainNavMenuContent } from './main-nav-menu-content'
|
|
|
|
type AccountDropdownProps = {
|
|
trigger?: (props: {
|
|
isOpen: boolean
|
|
ariaLabel: string
|
|
}) => ReactElement
|
|
variant?: 'default' | 'mainNav'
|
|
}
|
|
|
|
const mainNavMenuPopupClassName = 'w-60 max-w-80 overflow-hidden bg-components-panel-bg-blur! p-0! backdrop-blur-[5px]'
|
|
|
|
export default function AppSelector({
|
|
trigger,
|
|
variant = 'default',
|
|
}: AccountDropdownProps = {}) {
|
|
const router = useRouter()
|
|
const [aboutVisible, setAboutVisible] = useState(false)
|
|
const [isAccountMenuOpen, setIsAccountMenuOpen] = useState(false)
|
|
const { t } = useTranslation()
|
|
const userProfile = useAtomValue(userProfileAtom)
|
|
const langGeniusVersionInfo = useAtomValue(langGeniusVersionInfoAtom)
|
|
const clearEducationReverifyPrevExpireAt = useSetEducationReverifyPrevExpireAt()
|
|
const clearEducationReverifyHasNoticed = useSetEducationReverifyHasNoticed()
|
|
const clearEducationExpiredHasNoticed = useSetEducationExpiredHasNoticed()
|
|
|
|
const { mutateAsync: logout } = useLogout()
|
|
|
|
const handleLogout = async () => {
|
|
await logout()
|
|
resetUser()
|
|
// Tokens are now stored in cookies and cleared by backend
|
|
|
|
// To avoid use other account's education notice info
|
|
clearEducationReverifyPrevExpireAt(null)
|
|
clearEducationReverifyHasNoticed(null)
|
|
clearEducationExpiredHasNoticed(null)
|
|
|
|
router.push('/signin')
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<DropdownMenu open={isAccountMenuOpen} onOpenChange={setIsAccountMenuOpen}>
|
|
{trigger
|
|
? (
|
|
<DropdownMenuTrigger
|
|
render={trigger({
|
|
isOpen: isAccountMenuOpen,
|
|
ariaLabel: t('account.account', { ns: 'common' }),
|
|
})}
|
|
/>
|
|
)
|
|
: (
|
|
<DropdownMenuTrigger
|
|
aria-label={t('account.account', { ns: 'common' })}
|
|
className={cn('inline-flex items-center rounded-[20px] p-0.5 hover:bg-background-default-dodge', isAccountMenuOpen && 'bg-background-default-dodge')}
|
|
>
|
|
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} size="lg" />
|
|
</DropdownMenuTrigger>
|
|
)}
|
|
<DropdownMenuContent
|
|
placement={variant === 'mainNav' ? 'top-start' : 'bottom-end'}
|
|
sideOffset={6}
|
|
alignOffset={variant === 'mainNav' ? 4 : 0}
|
|
popupClassName={variant === 'mainNav' ? mainNavMenuPopupClassName : 'w-60 max-w-80 bg-components-panel-bg-blur! py-0! backdrop-blur-xs'}
|
|
>
|
|
{variant === 'mainNav'
|
|
? <MainNavMenuContent onLogout={handleLogout} />
|
|
: (
|
|
<DefaultMenuContent
|
|
closeAccountDropdown={() => setIsAccountMenuOpen(false)}
|
|
onShowAbout={() => setAboutVisible(true)}
|
|
onLogout={handleLogout}
|
|
/>
|
|
)}
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
{aboutVisible && <AccountAbout onCancel={() => setAboutVisible(false)} langGeniusVersionInfo={langGeniusVersionInfo} />}
|
|
</div>
|
|
)
|
|
}
|