HeaderBar.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. import React, {useContext, useState} from 'react';
  2. import {Link, useNavigate} from 'react-router-dom';
  3. import {UserContext} from '../context/User';
  4. import {Button, Container, Icon, Menu, Segment} from 'semantic-ui-react';
  5. import {API, getLogo, getSystemName, isAdmin, isMobile, showSuccess} from '../helpers';
  6. import '../index.css';
  7. import {
  8. IconAt,
  9. IconHistogram,
  10. IconGift,
  11. IconKey,
  12. IconUser,
  13. IconLayers,
  14. IconHelpCircle,
  15. IconCreditCard,
  16. IconSemiLogo,
  17. IconHome,
  18. IconImage
  19. } from '@douyinfe/semi-icons';
  20. import {Nav, Avatar, Dropdown, Layout, Switch} from '@douyinfe/semi-ui';
  21. import {stringToColor} from "../helpers/render";
  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. let navigate = useNavigate();
  41. const [showSidebar, setShowSidebar] = useState(false);
  42. const systemName = getSystemName();
  43. const logo = getLogo();
  44. async function logout() {
  45. setShowSidebar(false);
  46. await API.get('/api/user/logout');
  47. showSuccess('注销成功!');
  48. userDispatch({type: 'logout'});
  49. localStorage.removeItem('user');
  50. navigate('/login');
  51. }
  52. const toggleSidebar = () => {
  53. setShowSidebar(!showSidebar);
  54. };
  55. const renderButtons = (isMobile) => {
  56. return headerButtons.map((button) => {
  57. if (button.admin && !isAdmin()) return <></>;
  58. if (isMobile) {
  59. return (
  60. <Menu.Item
  61. onClick={() => {
  62. navigate(button.to);
  63. setShowSidebar(false);
  64. }}
  65. >
  66. {button.name}
  67. </Menu.Item>
  68. );
  69. }
  70. return (
  71. <Menu.Item key={button.name} as={Link} to={button.to}>
  72. <Icon name={button.icon}/>
  73. {button.name}
  74. </Menu.Item>
  75. );
  76. });
  77. };
  78. if (isMobile()) {
  79. return (
  80. <>
  81. <Menu
  82. borderless
  83. size='large'
  84. style={
  85. showSidebar
  86. ? {
  87. borderBottom: 'none',
  88. marginBottom: '0',
  89. borderTop: 'none',
  90. height: '51px'
  91. }
  92. : {borderTop: 'none', height: '52px'}
  93. }
  94. >
  95. <Container>
  96. <Menu.Item as={Link} to='/'>
  97. <img
  98. src={logo}
  99. alt='logo'
  100. style={{marginRight: '0.75em'}}
  101. />
  102. <div style={{fontSize: '20px'}}>
  103. <b>{systemName}</b>
  104. </div>
  105. </Menu.Item>
  106. <Menu.Menu position='right'>
  107. <Menu.Item onClick={toggleSidebar}>
  108. <Icon name={showSidebar ? 'close' : 'sidebar'}/>
  109. </Menu.Item>
  110. </Menu.Menu>
  111. </Container>
  112. </Menu>
  113. {showSidebar ? (
  114. <Segment style={{marginTop: 0, borderTop: '0'}}>
  115. <Menu secondary vertical style={{ width: '100%', margin: 0 }}>
  116. {renderButtons(true)}
  117. <Menu.Item>
  118. {userState.user ? (
  119. <Button onClick={logout}>注销</Button>
  120. ) : (
  121. <>
  122. <Button
  123. onClick={() => {
  124. setShowSidebar(false);
  125. navigate('/login');
  126. }}
  127. >
  128. 登录
  129. </Button>
  130. <Button
  131. onClick={() => {
  132. setShowSidebar(false);
  133. navigate('/register');
  134. }}
  135. >
  136. 注册
  137. </Button>
  138. </>
  139. )}
  140. </Menu.Item>
  141. </Menu>
  142. </Segment>
  143. ) : (
  144. <></>
  145. )}
  146. </>
  147. );
  148. }
  149. const switchMode = (model) => {
  150. const body = document.body;
  151. if (!model) {
  152. body.removeAttribute('theme-mode');
  153. } else {
  154. body.setAttribute('theme-mode', 'dark');
  155. }
  156. };
  157. return (
  158. <>
  159. <Layout>
  160. <div style={{width: '100%'}}>
  161. <Nav
  162. mode={'horizontal'}
  163. // bodyStyle={{ height: 100 }}
  164. renderWrapper={({itemElement, isSubNav, isInSubNav, props}) => {
  165. const routerMap = {
  166. about: "/about",
  167. };
  168. return (
  169. <Link
  170. style={{textDecoration: "none"}}
  171. to={routerMap[props.itemKey]}
  172. >
  173. {itemElement}
  174. </Link>
  175. );
  176. }}
  177. selectedKeys={[]}
  178. // items={headerButtons}
  179. onSelect={key => console.log(key)}
  180. footer={
  181. <>
  182. <Nav.Item itemKey={'about'} icon={<IconHelpCircle />} />
  183. <Switch checkedText="🌞" size={'large'} uncheckedText="🌙" onChange={switchMode} />
  184. {userState.user ?
  185. <>
  186. <Dropdown
  187. position="bottomRight"
  188. render={
  189. <Dropdown.Menu>
  190. <Dropdown.Item onClick={logout}>退出</Dropdown.Item>
  191. </Dropdown.Menu>
  192. }
  193. >
  194. <Avatar size="small" color={stringToColor(userState.user.username)} style={{ margin: 4 }}>
  195. {userState.user.username[0]}
  196. </Avatar>
  197. <span>{userState.user.username}</span>
  198. </Dropdown>
  199. </>
  200. :
  201. <>
  202. <Nav.Item itemKey={'login'} text={'登录'} icon={<IconKey />} />
  203. <Nav.Item itemKey={'register'} text={'注册'} icon={<IconUser />} />
  204. </>
  205. }
  206. </>
  207. }
  208. >
  209. </Nav>
  210. </div>
  211. </Layout>
  212. </>
  213. );
  214. };
  215. export default HeaderBar;