AllenYuan

Untitled

Jun 13th, 2020
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.74 KB | None | 0 0
  1. import {
  2. IconButton,
  3. List,
  4. ListItem,
  5. ListItemText,
  6. Menu,
  7. MenuItem,
  8. SwipeableDrawer,
  9. } from '@material-ui/core';
  10. import {BugReport, Menu as MenuIcon, Settings} from '@material-ui/icons';
  11. import LogOutButton from 'material-ui/svg-icons/action/power-settings-new';
  12. import {Toolbar, ToolbarGroup} from 'material-ui/Toolbar';
  13. import PropTypes from 'prop-types';
  14. import React, {useCallback, useState, useRef} from 'react';
  15. import {useSelector} from 'react-redux';
  16. import {Link} from 'react-router-dom';
  17. import styled from 'styled-components';
  18.  
  19. import {GITHUB_REPO} from '../../config';
  20. import AccountWidget from '../AccountWidget';
  21. import AppLogo from '../App/AppLogo';
  22. import constants from '../constants';
  23. import LocalizationMenu from '../Localization';
  24.  
  25.  
  26. const REPORT_BUG_PATH = `//github.com/${GITHUB_REPO}/issues`;
  27.  
  28. // create styling for each major subcomponent of Header
  29. const VerticalAlignToolbar = styled(ToolbarGroup)`
  30. display: flex;
  31. align-items: center;
  32. justify-content: center;
  33. `;
  34.  
  35. const VerticalAlignDiv = styled.div`
  36. display: flex;
  37. align-items: center;
  38. justify-content: center;
  39. `;
  40.  
  41. const TabContainer = styled.div`
  42. display: flex;
  43. flex-direction: column;
  44. font-weight: ${constants.fontWeightNormal};
  45. height: 100%;
  46. justify-content: center;
  47. margin: 0 12px;
  48. text-align: center;
  49. position: relative;
  50. `;
  51.  
  52. const AppLogoWrapper = styled.div`
  53. // for small screens, remove the applogo from the navigation
  54. @media screen and (max-width: 800px) {
  55. display: none;
  56. }
  57. `;
  58.  
  59. const DropdownMenu = styled(Menu)`
  60. & .MuiMenu-paper {
  61. background: ${constants.primarySurfaceColor};
  62. }
  63. `;
  64.  
  65. const DropdownMenuItem = styled(MenuItem)`
  66. color: ${constants.primaryTextColor} !important;
  67. padding-bottom: 12px !important;
  68. padding-top: 12px !important;
  69. `;
  70.  
  71. const ToolbarHeader = styled(Toolbar)`
  72. backdrop-filter: blur(16px);
  73. background-color: ${constants.defaultPrimaryColorSolid} !important;
  74. height: 56px;
  75. left: 0;
  76. padding: 8px 16px !important;
  77. position: fixed;
  78. top: 0;
  79. width: 100%;
  80. z-index: 100%;
  81.  
  82. & a {
  83. color: ${constants.primaryTextColor};
  84.  
  85. &:hover {
  86. color: ${constants.primaryTextColor};
  87. opacity: 0.6;
  88. }
  89. }
  90. `;
  91.  
  92. const MenuContent = styled.div`
  93. background: ${constants.primarySurfaceColor};
  94. max-width: 300px;
  95. height: 100%;
  96. overflow: auto;
  97. min-width: 220px;
  98. `;
  99.  
  100. const MenuLogoWrapper = styled.div`
  101. align-items: center;
  102. display: flex;
  103. justify-content: center;
  104. padding: 24px 0;
  105. `;
  106.  
  107. const DrawerLink = styled(Link)`
  108. color: ${constants.textColorPrimary};
  109. `;
  110.  
  111. const LinkGroup = ({navbarPages}) => (
  112. <VerticalAlignToolbar>
  113. {navbarPages.map((page) => (
  114. <TabContainer key={page.key}>
  115. <Link to={page.to}>{page.label}</Link>
  116. {Boolean(page.feature) && (
  117. <div
  118. style={{
  119. position: 'absolute',
  120. textTransform: 'uppercase',
  121. fontSize: '10px',
  122. top: '-10px',
  123. right: '0',
  124. color: 'lightblue',
  125. }}
  126. >
  127. {page.feature}
  128. </div>
  129. )}
  130. </TabContainer>
  131. ))}
  132. </VerticalAlignToolbar>
  133. );
  134.  
  135. LinkGroup.propTypes = {
  136. navbarPages: PropTypes.shape([{}]),
  137. };
  138.  
  139. const SettingsGroup = ({ children }) => {
  140. const [anchorEl, setAnchorEl] = useState(null); // setanchorel hook
  141. const buttonRef = useRef(); // ref for anchorEl
  142.  
  143. // init the handleclose callback: clear setanchorel
  144. const handleClose = useCallback(() => {
  145. setAnchorEl(undefined);
  146. }, [setAnchorEl]);
  147.  
  148. return (
  149. <>
  150. <IconButton
  151. ref={buttonRef}
  152. color="inherit"
  153. onClick={(e) => setAnchorEl(e.currentTarget)}
  154. >
  155. <Settings />
  156. </IconButton>
  157. {buttonRef.current && (
  158. <DropdownMenu
  159. anchorEl={buttonRef.current}
  160. open={Boolean(anchorEl)}
  161. onClose={handleClose}
  162. PaperProps={{ style: { maxHeight: 600 }}}
  163. >
  164. {children}
  165. </DropdownMenu>
  166. )}
  167. </>
  168. );
  169. };
  170.  
  171. const MenuButtonWrapper = styled.div`
  172. margin-right: 12px;
  173. `;
  174.  
  175. const LogoGroup = ({ onMenuClick }) => (
  176. <div style={{ marginRight: 16 }}>
  177. <VerticalAlignToolbar>
  178. <MenuButtonWrapper>
  179. <IconButton edge="start" color="inherit" onClick={onMenuClick}>
  180. <MenuIcon />
  181. </IconButton>
  182. </MenuButtonWrapper>
  183. <AppLogoWrapper>
  184. <AppLogo />
  185. </AppLogoWrapper>
  186. </VerticalAlignToolbar>
  187. </div>
  188. );
  189.  
  190. LogoGroup.propTypes = {
  191. onMenuClick: PropTypes.func,
  192. };
  193.  
  194. const AccountGroup = () => (
  195. <VerticalAlignToolbar>
  196. <AccountWidget />
  197. </VerticalAlignToolbar>
  198. );
  199.  
  200. const ReportBug = ({ strings }) => (
  201. <DropdownMenuItem
  202. component="a"
  203. href={REPORT_BUG_PATH}
  204. target="_blank" // open in new tab
  205. rel="noopener noreferrer" // security for opening in new tab
  206. >
  207. <BugReport style={{ marginRight: 32, width: 24, height: 24 }} />
  208. {strings.app_report_bug}
  209. </DropdownMenuItem>
  210. );
  211.  
  212. ReportBug.propTypes = {
  213. strings: PropTypes.shape({}),
  214. };
  215.  
  216. const LogOut = ({ strings }) => (
  217. <DropdownMenuItem
  218. component="a"
  219. href={`${process.env.REACT_APP_API_HOST}/logout`}
  220. rel="noopener noreferrer"
  221. >
  222. <LogOutButton style={{ marginRight: 32, width: 24, height: 24 }} />
  223. {strings.app_logout}
  224. </DropdownMenuItem>
  225. );
  226.  
  227. LogOut.propTypes = {
  228. strings: PropTypes.shape({}),
  229. };
  230.  
  231. const Header = ({ location, disableSearch }) => {
  232. // set hooks
  233. const [menuIsOpen, setMenuState] = useState(false);
  234.  
  235. // state selectors
  236. const small = useSelector((state) => state.browser.greaterThan.small);
  237. const user = useSelector((state) => {
  238. console.log('header state', state);
  239. return state.app.metadata.data.user;
  240. });
  241. const strings = useSelector((state) => state.app.strings);
  242.  
  243. // data encoding navbar
  244. const navbarPages = [
  245. {
  246. key: 'header_matches',
  247. to: '/matches',
  248. label: strings.header_matches,
  249. },
  250. {
  251. key: 'header_heroes',
  252. to: '/heroes',
  253. label: strings.header_heroes,
  254. },
  255. {
  256. key: 'header_explorer',
  257. to: '/explorer',
  258. label: strings.header_explorer,
  259. },
  260. {
  261. key: 'header_combos',
  262. to: '/combos',
  263. label: strings.combos,
  264. feature: '2020 BP',
  265. },
  266. {
  267. key: 'header_api',
  268. to: '/api-keys',
  269. label: strings.header_api,
  270. },
  271. ];
  272.  
  273. // add some pages revealed by drawer
  274. const drawerPages = [
  275. ...navbarPages,
  276. {
  277. key: 'header_distributions',
  278. to: '/distributions',
  279. label: strings.header_distributions,
  280. },
  281. {
  282. key: 'header_records',
  283. to: '/records',
  284. label: strings.header_records,
  285. },
  286. {
  287. key: 'header_meta',
  288. to: '/meta',
  289. label: strings.header_meta,
  290. },
  291. {
  292. key: 'header_scenarios',
  293. to: '/scenarios',
  294. label: strings.header_scenarios,
  295. },
  296. ];
  297.  
  298. return (
  299. <>
  300. <ToolbarHeader>
  301. {/* logo/settings groups */}
  302. <VerticalAlignDiv>
  303. <LogoGroup onMenuClick={() => setMenuState(true)} />
  304. {small && <LinkGroup navbarPages={navbarPages} />}
  305. </VerticalAlignDiv>
  306. <VerticalAlignDiv style={{ marginLeft: '16px' }}>
  307. {small && <AccountGroup />}
  308. <SettingsGroup>
  309. <LocalizationMenu />
  310. <ReportBug strings={strings} />
  311. {user ? <LogOut strings={strings} /> : null}
  312. </SettingsGroup>
  313. </VerticalAlignDiv>
  314. {/* drawer */}
  315. <SwipeableDrawer
  316. onOpen={() => setMenuState(true)}
  317. onClose = {() => setMenuState(false)}
  318. open = {menuIsOpen}
  319. >
  320. <MenuContent>
  321. <MenuLogoWrapper>
  322. <div>
  323. <AppLogo onClick={() => setMenuState(false)} />
  324. </div>
  325. </MenuLogoWrapper>
  326. {/* render the drawer links */}
  327. <List>
  328. {drawerPages.map((page) => (
  329. <DrawerLink key={`drawer__${page.to}`} to={page.to}>
  330. <ListItem
  331. button
  332. key={`drawer__${page.to}`}
  333. onClick={() => setMenuState(false)}
  334. >
  335. <ListItemText primary={page.label} />
  336. </ListItem>
  337. </DrawerLink>
  338. ))}
  339. </List>
  340. {/* render user links/login links */}
  341. <List>
  342. {user ? (
  343. <>
  344. <DrawerLink to={`/players/${user.account_id}`}>
  345. <ListItem button onClick={() => setMenuState(false)}>
  346. <ListItemText primary={strings.app_my_profile} />
  347. </ListItem>
  348. </DrawerLink>
  349. <DrawerLink
  350. as="a"
  351. href={`${process.env.REACT_APP_API_HOST}/logout`}
  352. >
  353. <ListItem button onClick={() => setMenuState(false)}>
  354. <ListItemText primary={strings.app_logout} />
  355. </ListItem>
  356. </DrawerLink>
  357. </>
  358. ) : (
  359. <>
  360. <DrawerLink
  361. as="a"
  362. href={`${process.env.REACT_APP_API_HOST}/login`}
  363. >
  364. <ListItem button onClick={() => setMenuState(false)}>
  365. <ListItemText primary={strings.app_login} />
  366. </ListItem>
  367. </DrawerLink>
  368. </>
  369. )}
  370. </List>
  371. </MenuContent>
  372. </SwipeableDrawer>
  373. </ToolbarHeader>
  374. </>
  375. );
  376. };
  377.  
  378. export default Header;
Add Comment
Please, Sign In to add comment