From 77950e48c76f4a3b29d01831d43039caba29888a Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期二, 18 十一月 2025 14:12:42 +0800
Subject: [PATCH] 修改
---
app/components/header/account-dropdown/index.tsx | 274 +++++++++++++++++++++++++++---------------------------
1 files changed, 136 insertions(+), 138 deletions(-)
diff --git a/app/components/header/account-dropdown/index.tsx b/app/components/header/account-dropdown/index.tsx
index 4a08a4c..d9065f3 100644
--- a/app/components/header/account-dropdown/index.tsx
+++ b/app/components/header/account-dropdown/index.tsx
@@ -2,53 +2,43 @@
import { useTranslation } from 'react-i18next'
import { Fragment, useState } from 'react'
import { useRouter } from 'next/navigation'
-import { useContextSelector } from 'use-context-selector'
-import {
- RiAccountCircleLine,
- RiArrowRightUpLine,
- RiBookOpenLine,
- RiGithubLine,
- RiGraduationCapFill,
- RiInformation2Line,
- RiLogoutBoxRLine,
- RiMap2Line,
- RiSettings3Line,
- RiStarLine,
- RiTShirt2Line,
-} from '@remixicon/react'
+import { useContext } from 'use-context-selector'
+import { RiArrowDownSLine, RiLogoutBoxRLine } from '@remixicon/react'
import Link from 'next/link'
-import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
+import { Menu, Transition } from '@headlessui/react'
import Indicator from '../indicator'
import AccountAbout from '../account-about'
-import GithubStar from '../github-star'
-import Support from './support'
-import Compliance from './compliance'
-import PremiumBadge from '@/app/components/base/premium-badge'
-import { useGetDocLanguage } from '@/context/i18n'
+import { mailToSupport } from '../utils/util'
+import WorkplaceSelector from './workplace-selector'
+import classNames from '@/utils/classnames'
+import I18n from '@/context/i18n'
import Avatar from '@/app/components/base/avatar'
-import ThemeSwitcher from '@/app/components/base/theme-switcher'
import { logout } from '@/service/common'
-import AppContext, { useAppContext } from '@/context/app-context'
-import { useProviderContext } from '@/context/provider-context'
+import { useAppContext } from '@/context/app-context'
+import { ArrowUpRight } from '@/app/components/base/icons/src/vender/line/arrows'
import { useModalContext } from '@/context/modal-context'
-import { LicenseStatus } from '@/types/feature'
-import { IS_CLOUD_EDITION } from '@/config'
-import cn from '@/utils/classnames'
+import { LanguagesSupported } from '@/i18n/language'
+import { useProviderContext } from '@/context/provider-context'
+import { Plan } from '@/app/components/billing/type'
-export default function AppSelector() {
+export type IAppSelector = {
+ isMobile: boolean
+}
+
+export default function AppSelector({ isMobile }: IAppSelector) {
const itemClassName = `
- flex items-center w-full h-9 pl-3 pr-2 text-text-secondary system-md-regular
- rounded-lg hover:bg-state-base-hover cursor-pointer gap-1
+ flex items-center w-full h-9 px-3 text-text-secondary system-md-regular
+ rounded-lg hover:bg-state-base-hover cursor-pointer
`
const router = useRouter()
const [aboutVisible, setAboutVisible] = useState(false)
- const systemFeatures = useContextSelector(AppContext, v => v.systemFeatures)
+ const { locale } = useContext(I18n)
const { t } = useTranslation()
- const { userProfile, langeniusVersionInfo, isCurrentWorkspaceOwner } = useAppContext()
- const { isEducationAccount } = useProviderContext()
+ const { userProfile, langeniusVersionInfo } = useAppContext()
const { setShowAccountSettingModal } = useModalContext()
- const docLanguage = useGetDocLanguage()
+ const { plan } = useProviderContext()
+ const canEmailSupport = plan.type === Plan.professional || plan.type === Plan.team || plan.type === Plan.enterprise
const handleLogout = async () => {
await logout({
@@ -69,9 +59,21 @@
{
({ open }) => (
<>
- <MenuButton className={cn('inline-flex items-center rounded-[20px] p-0.5 hover:bg-background-default-dodge', open && 'bg-background-default-dodge')}>
- <Avatar avatar={userProfile.avatar_url} name={userProfile.name} size={36} />
- </MenuButton>
+ <Menu.Button
+ className={`
+ inline-flex items-center
+ rounded-[20px] py-1 pr-2.5 pl-1 text-sm
+ text-gray-700 hover:bg-gray-200
+ mobile:px-1
+ ${open && 'bg-gray-200'}
+ `}
+ >
+ <Avatar avatar={userProfile.avatar_url} name={userProfile.name} className='sm:mr-2 mr-0' size={32} />
+ {!isMobile && <>
+ {userProfile.name}
+ <RiArrowDownSLine className="w-3 h-3 ml-1 text-gray-700" />
+ </>}
+ </Menu.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
@@ -81,135 +83,131 @@
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
- <MenuItems
+ <Menu.Items
className="
absolute right-0 mt-1.5 w-60 max-w-80
- origin-top-right divide-y divide-divider-subtle rounded-xl bg-components-panel-bg-blur shadow-lg
- backdrop-blur-sm focus:outline-none
+ divide-y divide-divider-subtle origin-top-right rounded-lg bg-components-panel-bg-blur
+ shadow-lg focus:outline-none
"
>
- <MenuItem disabled>
- <div className='flex flex-nowrap items-center py-[13px] pl-3 pr-2'>
- <div className='grow'>
- <div className='system-md-medium break-all text-text-primary'>
- {userProfile.name}
- {isEducationAccount && (
- <PremiumBadge size='s' color='blue' className='ml-1 !px-2'>
- <RiGraduationCapFill className='mr-1 h-3 w-3' />
- <span className='system-2xs-medium'>EDU</span>
- </PremiumBadge>
- )}
- </div>
- <div className='system-xs-regular break-all text-text-tertiary'>{userProfile.email}</div>
- </div>
+ <Menu.Item disabled>
+ <div className='flex flex-nowrap items-center px-4 py-[13px]'>
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} size={36} className='mr-3' />
+ <div className='grow'>
+ <div className='system-md-medium text-text-primary break-all'>{userProfile.name}</div>
+ <div className='system-xs-regular text-text-tertiary break-all'>{userProfile.email}</div>
+ </div>
</div>
- </MenuItem>
+ </Menu.Item>
+ <div className='px-1 py-1'>
+ <div className='mt-2 px-3 text-xs font-medium text-text-tertiary'>{t('common.userProfile.workspace')}</div>
+ <WorkplaceSelector />
+ </div>
<div className="px-1 py-1">
- <MenuItem>
- <Link
- className={cn(itemClassName, 'group',
- 'data-[active]:bg-state-base-hover',
+ <Menu.Item>
+ {({ active }) => <Link
+ className={classNames(itemClassName, 'group justify-between',
+ active && 'bg-state-base-hover',
)}
href='/account'
target='_self' rel='noopener noreferrer'>
- <RiAccountCircleLine className='size-4 shrink-0 text-text-tertiary' />
- <div className='system-md-regular grow px-1 text-text-secondary'>{t('common.account.account')}</div>
- <RiArrowRightUpLine className='size-[14px] shrink-0 text-text-tertiary' />
- </Link>
- </MenuItem>
- <MenuItem>
- <div className={cn(itemClassName,
- 'data-[active]:bg-state-base-hover',
+ <div>{t('common.account.account')}</div>
+ <ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' />
+ </Link>}
+ </Menu.Item>
+ <Menu.Item>
+ {({ active }) => <div className={classNames(itemClassName,
+ active && 'bg-state-base-hover',
)} onClick={() => setShowAccountSettingModal({ payload: 'members' })}>
- <RiSettings3Line className='size-4 shrink-0 text-text-tertiary' />
- <div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.settings')}</div>
- </div>
- </MenuItem>
- </div>
- <div className='p-1'>
- <MenuItem>
- <Link
- className={cn(itemClassName, 'group justify-between',
- 'data-[active]:bg-state-base-hover',
+ <div>{t('common.userProfile.settings')}</div>
+ </div>}
+ </Menu.Item>
+ {canEmailSupport && <Menu.Item>
+ {({ active }) => <a
+ className={classNames(itemClassName, 'group justify-between',
+ active && 'bg-state-base-hover',
)}
- href={`https://docs.dify.ai/${docLanguage}/introduction`}
+ href={mailToSupport(userProfile.email, plan.type, langeniusVersionInfo.current_version)}
target='_blank' rel='noopener noreferrer'>
- <RiBookOpenLine className='size-4 shrink-0 text-text-tertiary' />
- <div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.helpCenter')}</div>
- <RiArrowRightUpLine className='size-[14px] shrink-0 text-text-tertiary' />
- </Link>
- </MenuItem>
- <Support />
- {IS_CLOUD_EDITION && isCurrentWorkspaceOwner && <Compliance />}
- </div>
- <div className='p-1'>
- <MenuItem>
- <Link
- className={cn(itemClassName, 'group justify-between',
- 'data-[active]:bg-state-base-hover',
+ <div>{t('common.userProfile.emailSupport')}</div>
+ <ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' />
+ </a>}
+ </Menu.Item>}
+ <Menu.Item>
+ {({ active }) => <Link
+ className={classNames(itemClassName, 'group justify-between',
+ active && 'bg-state-base-hover',
+ )}
+ href='https://github.com/langgenius/dify/discussions/categories/feedbacks'
+ target='_blank' rel='noopener noreferrer'>
+ <div>{t('common.userProfile.communityFeedback')}</div>
+ <ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' />
+ </Link>}
+ </Menu.Item>
+ <Menu.Item>
+ {({ active }) => <Link
+ className={classNames(itemClassName, 'group justify-between',
+ active && 'bg-state-base-hover',
+ )}
+ href='https://discord.gg/5AEfbxcd9k'
+ target='_blank' rel='noopener noreferrer'>
+ <div>{t('common.userProfile.community')}</div>
+ <ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' />
+ </Link>}
+ </Menu.Item>
+ <Menu.Item>
+ {({ active }) => <Link
+ className={classNames(itemClassName, 'group justify-between',
+ active && 'bg-state-base-hover',
+ )}
+ href={
+ locale !== LanguagesSupported[1] ? 'https://docs.dify.ai/' : `https://docs.dify.ai/v/${locale.toLowerCase()}/`
+ }
+ target='_blank' rel='noopener noreferrer'>
+ <div>{t('common.userProfile.helpCenter')}</div>
+ <ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' />
+ </Link>}
+ </Menu.Item>
+ <Menu.Item>
+ {({ active }) => <Link
+ className={classNames(itemClassName, 'group justify-between',
+ active && 'bg-state-base-hover',
)}
href='https://roadmap.dify.ai'
target='_blank' rel='noopener noreferrer'>
- <RiMap2Line className='size-4 shrink-0 text-text-tertiary' />
- <div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.roadmap')}</div>
- <RiArrowRightUpLine className='size-[14px] shrink-0 text-text-tertiary' />
- </Link>
- </MenuItem>
- {systemFeatures.license.status === LicenseStatus.NONE && <MenuItem>
- <Link
- className={cn(itemClassName, 'group justify-between',
- 'data-[active]:bg-state-base-hover',
- )}
- href='https://github.com/langgenius/dify'
- target='_blank' rel='noopener noreferrer'>
- <RiGithubLine className='size-4 shrink-0 text-text-tertiary' />
- <div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.github')}</div>
- <div className='flex items-center gap-0.5 rounded-[5px] border border-divider-deep bg-components-badge-bg-dimm px-[5px] py-[3px]'>
- <RiStarLine className='size-3 shrink-0 text-text-tertiary' />
- <GithubStar className='system-2xs-medium-uppercase text-text-tertiary' />
- </div>
- </Link>
- </MenuItem>}
+ <div>{t('common.userProfile.roadmap')}</div>
+ <ArrowUpRight className='hidden w-[14px] h-[14px] text-text-tertiary group-hover:flex' />
+ </Link>}
+ </Menu.Item>
{
document?.body?.getAttribute('data-public-site-about') !== 'hide' && (
- <MenuItem>
- <div className={cn(itemClassName, 'justify-between',
- 'data-[active]:bg-state-base-hover',
+ <Menu.Item>
+ {({ active }) => <div className={classNames(itemClassName, 'justify-between',
+ active && 'bg-state-base-hover',
)} onClick={() => setAboutVisible(true)}>
- <RiInformation2Line className='size-4 shrink-0 text-text-tertiary' />
- <div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.about')}</div>
- <div className='flex shrink-0 items-center'>
- <div className='system-xs-regular mr-2 text-text-tertiary'>{langeniusVersionInfo.current_version}</div>
+ <div>{t('common.userProfile.about')}</div>
+ <div className='flex items-center'>
+ <div className='mr-2 system-xs-regular text-text-tertiary'>{langeniusVersionInfo.current_version}</div>
<Indicator color={langeniusVersionInfo.current_version === langeniusVersionInfo.latest_version ? 'green' : 'orange'} />
</div>
- </div>
- </MenuItem>
+ </div>}
+ </Menu.Item>
)
}
</div>
- <MenuItem disabled>
- <div className='p-1'>
- <div className={cn(itemClassName, 'hover:bg-transparent')}>
- <RiTShirt2Line className='size-4 shrink-0 text-text-tertiary' />
- <div className='system-md-regular grow px-1 text-text-secondary'>{t('common.theme.theme')}</div>
- <ThemeSwitcher/>
- </div>
- </div>
- </MenuItem>
- <MenuItem>
- <div className='p-1' onClick={() => handleLogout()}>
+ <Menu.Item>
+ {({ active }) => <div className='p-1' onClick={() => handleLogout()}>
<div
- className={cn(itemClassName, 'group justify-between',
- 'data-[active]:bg-state-base-hover',
- )}
+ className={
+ classNames('flex items-center justify-between h-9 px-3 rounded-lg cursor-pointer group hover:bg-state-base-hover',
+ active && 'bg-state-base-hover')}
>
- <RiLogoutBoxRLine className='size-4 shrink-0 text-text-tertiary' />
- <div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.logout')}</div>
+ <div className='system-md-regular text-text-secondary'>{t('common.userProfile.logout')}</div>
+ <RiLogoutBoxRLine className='hidden w-4 h-4 text-text-tertiary group-hover:flex' />
</div>
- </div>
- </MenuItem>
- </MenuItems>
+ </div>}
+ </Menu.Item>
+ </Menu.Items>
</Transition>
</>
)
--
Gitblit v1.8.0