From a430284aa21e3ae1f0d5654e55b2ad2852519cc2 Mon Sep 17 00:00:00 2001
From: wwf <yearningwang@iqtogether.com>
Date: 星期三, 04 六月 2025 15:17:49 +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