Header.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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, Dropdown, Icon, Menu, Segment } from 'semantic-ui-react';
  5. import { API, getLogo, getSystemName, isAdmin, isMobile, showSuccess } from '../helpers';
  6. import '../index.css';
  7. // Header Buttons
  8. let headerButtons = [
  9. {
  10. name: '首页',
  11. to: '/',
  12. icon: 'home'
  13. },
  14. {
  15. name: '渠道',
  16. to: '/channel',
  17. icon: 'sitemap',
  18. admin: true
  19. },
  20. {
  21. name: '令牌',
  22. to: '/token',
  23. icon: 'key'
  24. },
  25. {
  26. name: '兑换',
  27. to: '/redemption',
  28. icon: 'dollar sign',
  29. admin: true
  30. },
  31. {
  32. name: '充值',
  33. to: '/topup',
  34. icon: 'cart'
  35. },
  36. {
  37. name: '用户',
  38. to: '/user',
  39. icon: 'user',
  40. admin: true
  41. },
  42. {
  43. name: '日志',
  44. to: '/log',
  45. icon: 'book'
  46. },
  47. {
  48. name: '设置',
  49. to: '/setting',
  50. icon: 'setting'
  51. },
  52. {
  53. name: '关于',
  54. to: '/about',
  55. icon: 'info circle'
  56. }
  57. ];
  58. if (localStorage.getItem('chat_link')) {
  59. headerButtons.splice(1, 0, {
  60. name: '聊天',
  61. to: '/chat',
  62. icon: 'comments'
  63. });
  64. }
  65. const Header = () => {
  66. const [userState, userDispatch] = useContext(UserContext);
  67. let navigate = useNavigate();
  68. const [showSidebar, setShowSidebar] = useState(false);
  69. const systemName = getSystemName();
  70. const logo = getLogo();
  71. async function logout() {
  72. setShowSidebar(false);
  73. await API.get('/api/user/logout');
  74. showSuccess('注销成功!');
  75. userDispatch({ type: 'logout' });
  76. localStorage.removeItem('user');
  77. navigate('/login');
  78. }
  79. const toggleSidebar = () => {
  80. setShowSidebar(!showSidebar);
  81. };
  82. const renderButtons = (isMobile) => {
  83. return headerButtons.map((button) => {
  84. if (button.admin && !isAdmin()) return <></>;
  85. if (isMobile) {
  86. return (
  87. <Menu.Item
  88. onClick={() => {
  89. navigate(button.to);
  90. setShowSidebar(false);
  91. }}
  92. >
  93. {button.name}
  94. </Menu.Item>
  95. );
  96. }
  97. return (
  98. <Menu.Item key={button.name} as={Link} to={button.to}>
  99. <Icon name={button.icon} />
  100. {button.name}
  101. </Menu.Item>
  102. );
  103. });
  104. };
  105. if (isMobile()) {
  106. return (
  107. <>
  108. <Menu
  109. borderless
  110. size='large'
  111. style={
  112. showSidebar
  113. ? {
  114. borderBottom: 'none',
  115. marginBottom: '0',
  116. borderTop: 'none',
  117. height: '51px'
  118. }
  119. : { borderTop: 'none', height: '52px' }
  120. }
  121. >
  122. <Container>
  123. <Menu.Item as={Link} to='/'>
  124. <img
  125. src={logo}
  126. alt='logo'
  127. style={{ marginRight: '0.75em' }}
  128. />
  129. <div style={{ fontSize: '20px' }}>
  130. <b>{systemName}</b>
  131. </div>
  132. </Menu.Item>
  133. <Menu.Menu position='right'>
  134. <Menu.Item onClick={toggleSidebar}>
  135. <Icon name={showSidebar ? 'close' : 'sidebar'} />
  136. </Menu.Item>
  137. </Menu.Menu>
  138. </Container>
  139. </Menu>
  140. {showSidebar ? (
  141. <Segment style={{ marginTop: 0, borderTop: '0' }}>
  142. <Menu secondary vertical style={{ width: '100%', margin: 0 }}>
  143. {renderButtons(true)}
  144. <Menu.Item>
  145. {userState.user ? (
  146. <Button onClick={logout}>注销</Button>
  147. ) : (
  148. <>
  149. <Button
  150. onClick={() => {
  151. setShowSidebar(false);
  152. navigate('/login');
  153. }}
  154. >
  155. 登录
  156. </Button>
  157. <Button
  158. onClick={() => {
  159. setShowSidebar(false);
  160. navigate('/register');
  161. }}
  162. >
  163. 注册
  164. </Button>
  165. </>
  166. )}
  167. </Menu.Item>
  168. </Menu>
  169. </Segment>
  170. ) : (
  171. <></>
  172. )}
  173. </>
  174. );
  175. }
  176. return (
  177. <>
  178. <Menu borderless style={{ borderTop: 'none' }}>
  179. <Container>
  180. <Menu.Item as={Link} to='/' className={'hide-on-mobile'}>
  181. <img src={logo} alt='logo' style={{ marginRight: '0.75em' }} />
  182. <div style={{ fontSize: '20px' }}>
  183. <b>{systemName}</b>
  184. </div>
  185. </Menu.Item>
  186. {renderButtons(false)}
  187. <Menu.Menu position='right'>
  188. {userState.user ? (
  189. <Dropdown
  190. text={userState.user.username}
  191. pointing
  192. className='link item'
  193. >
  194. <Dropdown.Menu>
  195. <Dropdown.Item onClick={logout}>注销</Dropdown.Item>
  196. </Dropdown.Menu>
  197. </Dropdown>
  198. ) : (
  199. <Menu.Item
  200. name='登录'
  201. as={Link}
  202. to='/login'
  203. className='btn btn-link'
  204. />
  205. )}
  206. </Menu.Menu>
  207. </Container>
  208. </Menu>
  209. </>
  210. );
  211. };
  212. export default Header;