HeaderBar.js 6.8 KB

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