index.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. 'use client'
  2. import { useEffect, useState } from 'react'
  3. import { useTranslation } from 'react-i18next'
  4. import { usePathname, useSelectedLayoutSegment } from 'next/navigation'
  5. import classNames from 'classnames'
  6. import { CommandLineIcon } from '@heroicons/react/24/solid'
  7. import Link from 'next/link'
  8. import AccountDropdown from './account-dropdown'
  9. import AppNav from './app-nav'
  10. import DatasetNav from './dataset-nav'
  11. import s from './index.module.css'
  12. import type { GithubRepo } from '@/models/common'
  13. import { WorkspaceProvider } from '@/context/workspace-context'
  14. import { useAppContext } from '@/context/app-context'
  15. import { Grid01 } from '@/app/components/base/icons/src/vender/line/layout'
  16. import { Grid01 as Grid01Solid } from '@/app/components/base/icons/src/vender/solid/layout'
  17. import { PuzzlePiece01 } from '@/app/components/base/icons/src/vender/line/development'
  18. import { PuzzlePiece01 as PuzzlePiece01Solid } from '@/app/components/base/icons/src/vender/solid/development'
  19. const navClassName = `
  20. flex items-center relative mr-3 px-3 h-8 rounded-xl
  21. font-medium text-sm
  22. cursor-pointer
  23. `
  24. const headerEnvClassName: { [k: string]: string } = {
  25. DEVELOPMENT: 'bg-[#FEC84B] border-[#FDB022] text-[#93370D]',
  26. TESTING: 'bg-[#A5F0FC] border-[#67E3F9] text-[#164C63]',
  27. }
  28. const Header = () => {
  29. const { t } = useTranslation()
  30. const pathname = usePathname()
  31. const { userProfile, langeniusVersionInfo } = useAppContext()
  32. const showEnvTag = langeniusVersionInfo.current_env === 'TESTING' || langeniusVersionInfo.current_env === 'DEVELOPMENT'
  33. const selectedSegment = useSelectedLayoutSegment()
  34. const isPluginsComingSoon = selectedSegment === 'plugins-coming-soon'
  35. const isExplore = selectedSegment === 'explore'
  36. const [starCount, setStarCount] = useState(0)
  37. const isBordered = ['/apps', '/datasets'].includes(pathname)
  38. useEffect(() => {
  39. globalThis.fetch('https://api.github.com/repos/langgenius/dify').then(res => res.json()).then((data: GithubRepo) => {
  40. setStarCount(data.stargazers_count)
  41. })
  42. }, [])
  43. return (
  44. <div className={classNames(
  45. 'sticky top-0 left-0 right-0 z-20 flex bg-gray-100 grow-0 shrink-0 basis-auto h-14',
  46. s.header,
  47. isBordered ? 'border-b border-gray-200' : '',
  48. )}
  49. >
  50. <div className={classNames(
  51. s[`header-${langeniusVersionInfo.current_env}`],
  52. 'flex flex-1 items-center justify-between px-4',
  53. )}>
  54. <div className='flex items-center'>
  55. <Link href="/apps" className='flex items-center mr-4'>
  56. <div className={s.logo} />
  57. </Link>
  58. {
  59. starCount > 0 && (
  60. <Link
  61. href='https://github.com/langgenius/dify'
  62. target='_blank'
  63. className='flex items-center leading-[18px] border border-gray-200 rounded-md text-xs text-gray-700 font-semibold overflow-hidden'>
  64. <div className='flex items-center px-2 py-1 bg-gray-100'>
  65. <div className={`${s['github-icon']} mr-1 rounded-full`} />
  66. Star
  67. </div>
  68. <div className='px-2 py-1 bg-white border-l border-gray-200'>{`${starCount}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}</div>
  69. </Link>
  70. )
  71. }
  72. </div>
  73. <div className='flex items-center'>
  74. <Link href="/explore/apps" className={classNames(
  75. navClassName, 'group',
  76. isExplore && 'bg-white shadow-[0_2px_5px_-1px_rgba(0,0,0,0.05),0_2px_4px_-2px_rgba(0,0,0,0.05)]',
  77. isExplore ? 'text-primary-600' : 'text-gray-500 hover:bg-gray-200',
  78. )}>
  79. {
  80. isExplore
  81. ? <Grid01Solid className='mr-2 w-4 h-4' />
  82. : <Grid01 className='mr-2 w-4 h-4' />
  83. }
  84. {t('common.menus.explore')}
  85. </Link>
  86. <AppNav />
  87. <Link href="/plugins-coming-soon" className={classNames(
  88. navClassName, 'group',
  89. isPluginsComingSoon && 'bg-white shadow-[0_2px_5px_-1px_rgba(0,0,0,0.05),0_2px_4px_-2px_rgba(0,0,0,0.05)]',
  90. isPluginsComingSoon ? 'text-primary-600' : 'text-gray-500 hover:bg-gray-200',
  91. )}>
  92. {
  93. isPluginsComingSoon
  94. ? <PuzzlePiece01Solid className='mr-2 w-4 h-4' />
  95. : <PuzzlePiece01 className='mr-2 w-4 h-4' />
  96. }
  97. {t('common.menus.plugins')}
  98. </Link>
  99. <DatasetNav />
  100. </div>
  101. <div className='flex items-center flex-shrink-0'>
  102. {
  103. showEnvTag && (
  104. <div className={`
  105. flex items-center h-[22px] mr-4 rounded-md px-2 text-xs font-medium border
  106. ${headerEnvClassName[langeniusVersionInfo.current_env]}
  107. `}>
  108. {
  109. langeniusVersionInfo.current_env === 'TESTING' && (
  110. <>
  111. <div className={s['beaker-icon']} />
  112. {t('common.environment.testing')}
  113. </>
  114. )
  115. }
  116. {
  117. langeniusVersionInfo.current_env === 'DEVELOPMENT' && (
  118. <>
  119. <CommandLineIcon className='w-3 h-3 mr-1' />
  120. {t('common.environment.development')}
  121. </>
  122. )
  123. }
  124. </div>
  125. )
  126. }
  127. <WorkspaceProvider>
  128. <AccountDropdown userProfile={userProfile} langeniusVersionInfo={langeniusVersionInfo} />
  129. </WorkspaceProvider>
  130. </div>
  131. </div>
  132. </div>
  133. )
  134. }
  135. export default Header