HeaderBar.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. import React, { useContext, useEffect, useState } from 'react';
  2. import { Link, useNavigate } from 'react-router-dom';
  3. import { UserContext } from '../context/User';
  4. import { useSetTheme, useTheme } from '../context/Theme';
  5. import { API, getLogo, getSystemName, isMobile, showSuccess } from '../helpers';
  6. import '../index.css';
  7. import fireworks from 'react-fireworks';
  8. import {
  9. IconHelpCircle,
  10. IconHome,
  11. IconHomeStroked,
  12. IconKey,
  13. IconNoteMoneyStroked,
  14. IconPriceTag,
  15. IconUser
  16. } from '@douyinfe/semi-icons';
  17. import { Avatar, Dropdown, Layout, Nav, Switch } from '@douyinfe/semi-ui';
  18. import { stringToColor } from '../helpers/render';
  19. import Text from '@douyinfe/semi-ui/lib/es/typography/text';
  20. // HeaderBar Buttons
  21. let headerButtons = [
  22. {
  23. text: '关于',
  24. itemKey: 'about',
  25. to: '/about',
  26. icon: <IconHelpCircle />,
  27. },
  28. ];
  29. let buttons = [
  30. {
  31. text: '首页',
  32. itemKey: 'home',
  33. to: '/',
  34. // icon: <IconHomeStroked />,
  35. },
  36. // {
  37. // text: '模型价格',
  38. // itemKey: 'pricing',
  39. // to: '/pricing',
  40. // icon: <IconNoteMoneyStroked />,
  41. // },
  42. ];
  43. if (localStorage.getItem('chat_link')) {
  44. headerButtons.splice(1, 0, {
  45. name: '聊天',
  46. to: '/chat',
  47. icon: 'comments',
  48. });
  49. }
  50. const HeaderBar = () => {
  51. const [userState, userDispatch] = useContext(UserContext);
  52. let navigate = useNavigate();
  53. const [showSidebar, setShowSidebar] = useState(false);
  54. const systemName = getSystemName();
  55. const logo = getLogo();
  56. const currentDate = new Date();
  57. // enable fireworks on new year(1.1 and 2.9-2.24)
  58. const isNewYear =
  59. (currentDate.getMonth() === 0 && currentDate.getDate() === 1) ||
  60. (currentDate.getMonth() === 1 &&
  61. currentDate.getDate() >= 9 &&
  62. currentDate.getDate() <= 24);
  63. async function logout() {
  64. setShowSidebar(false);
  65. await API.get('/api/user/logout');
  66. showSuccess('注销成功!');
  67. userDispatch({ type: 'logout' });
  68. localStorage.removeItem('user');
  69. navigate('/login');
  70. }
  71. const handleNewYearClick = () => {
  72. fireworks.init('root', {});
  73. fireworks.start();
  74. setTimeout(() => {
  75. fireworks.stop();
  76. setTimeout(() => {
  77. window.location.reload();
  78. }, 10000);
  79. }, 3000);
  80. };
  81. const theme = useTheme();
  82. const setTheme = useSetTheme();
  83. useEffect(() => {
  84. if (theme === 'dark') {
  85. document.body.setAttribute('theme-mode', 'dark');
  86. }
  87. if (isNewYear) {
  88. console.log('Happy New Year!');
  89. }
  90. }, []);
  91. return (
  92. <>
  93. <Layout>
  94. <div style={{ width: '100%' }}>
  95. <Nav
  96. mode={'horizontal'}
  97. // bodyStyle={{ height: 100 }}
  98. renderWrapper={({ itemElement, isSubNav, isInSubNav, props }) => {
  99. const routerMap = {
  100. about: '/about',
  101. login: '/login',
  102. register: '/register',
  103. home: '/',
  104. };
  105. return (
  106. <Link
  107. style={{ textDecoration: 'none' }}
  108. to={routerMap[props.itemKey]}
  109. >
  110. {itemElement}
  111. </Link>
  112. );
  113. }}
  114. selectedKeys={[]}
  115. // items={headerButtons}
  116. onSelect={(key) => {}}
  117. header={isMobile()?{
  118. logo: (
  119. <img src={logo} alt='logo' style={{ marginRight: '0.75em' }} />
  120. ),
  121. }:{
  122. logo: (
  123. <img src={logo} alt='logo' />
  124. ),
  125. text: systemName,
  126. }}
  127. items={buttons}
  128. footer={
  129. <>
  130. {isNewYear && (
  131. // happy new year
  132. <Dropdown
  133. position='bottomRight'
  134. render={
  135. <Dropdown.Menu>
  136. <Dropdown.Item onClick={handleNewYearClick}>
  137. Happy New Year!!!
  138. </Dropdown.Item>
  139. </Dropdown.Menu>
  140. }
  141. >
  142. <Nav.Item itemKey={'new-year'} text={'🏮'} />
  143. </Dropdown>
  144. )}
  145. <Nav.Item itemKey={'about'} icon={<IconHelpCircle />} />
  146. <>
  147. {!isMobile() && (
  148. <Switch
  149. checkedText='🌞'
  150. size={'large'}
  151. checked={theme === 'dark'}
  152. uncheckedText='🌙'
  153. onChange={(checked) => {
  154. setTheme(checked);
  155. }}
  156. />
  157. )}
  158. </>
  159. {userState.user ? (
  160. <>
  161. <Dropdown
  162. position='bottomRight'
  163. render={
  164. <Dropdown.Menu>
  165. <Dropdown.Item onClick={logout}>退出</Dropdown.Item>
  166. </Dropdown.Menu>
  167. }
  168. >
  169. <Avatar
  170. size='small'
  171. color={stringToColor(userState.user.username)}
  172. style={{ margin: 4 }}
  173. >
  174. {userState.user.username[0]}
  175. </Avatar>
  176. <span>{userState.user.username}</span>
  177. </Dropdown>
  178. </>
  179. ) : (
  180. <>
  181. <Nav.Item
  182. itemKey={'login'}
  183. text={'登录'}
  184. // icon={<IconKey />}
  185. />
  186. <Nav.Item
  187. itemKey={'register'}
  188. text={'注册'}
  189. icon={<IconUser />}
  190. />
  191. </>
  192. )}
  193. </>
  194. }
  195. ></Nav>
  196. </div>
  197. </Layout>
  198. </>
  199. );
  200. };
  201. export default HeaderBar;