Header.jsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. import {AppBar, Box, Toolbar, IconButton, Typography, Menu, Container, Avatar, Button, Tooltip, MenuItem, Badge} from '@mui/material';
  2. import MenuIcon from '@mui/icons-material/Menu';
  3. import SearchIcon from '@mui/icons-material/Search';
  4. import FavoriteBorderIcon from '@mui/icons-material/FavoriteBorder';
  5. import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
  6. import ManageSearchIcon from '@mui/icons-material/ManageSearch';
  7. import Link from "react-router-dom/es/Link";
  8. import {useState} from "react";
  9. import '../scss/Header.scss';
  10. import {actionAuthLogout} from "../reducers/AuthReducer";
  11. import {connect} from "react-redux";
  12. import {actionUserRemove} from "../reducers/UserReducer";
  13. import {actionFullUserFindOne} from "../actions/ActionUserFind";
  14. import {backURL} from "../actions/PathDB";
  15. import userDefault from "../img/header/userDefault.png"
  16. const pages = ['catalog', 'about us', 'our team', 'faq', 'contact']
  17. const settingsDefaultUserAuth = ['Profile', 'Logout']
  18. const Header = ({user={}, createUser}) => {
  19. if (localStorage.authToken && localStorage.userId && Object.keys(user).length === 0){
  20. createUser(localStorage.userId)
  21. }
  22. const [anchorElNav, setAnchorElNav] = useState(null);
  23. const [anchorElUser, setAnchorElUser] = useState(null);
  24. const handleOpenNavMenu = (event) => {
  25. setAnchorElNav(event.currentTarget);
  26. };
  27. const handleOpenUserMenu = (event) => {
  28. setAnchorElUser(event.currentTarget);
  29. };
  30. const handleCloseNavMenu = () => {
  31. setAnchorElNav(null);
  32. };
  33. const handleCloseUserMenu = () => {
  34. setAnchorElUser(null);
  35. };
  36. const LogoItem = () => {
  37. return (
  38. <Link to='/' className="Header__Logo"> ABRAXAS </Link>
  39. )
  40. }
  41. const LinkItem = ({page, color='white'}) => {
  42. return (
  43. <Button
  44. key={page}
  45. onClick={handleCloseNavMenu}
  46. sx={{ my: 2, color: color, display: 'block'}}
  47. >
  48. <Link
  49. to={`/${Array.from(page.toLowerCase()).map(i => i === ' ' ? '-' : i).join('')}`}
  50. className="Header__Link"> {page}
  51. </Link>
  52. </Button>
  53. )
  54. }
  55. const IconItems = ({cart={}, size="large", color='default', valueWishList=0}) => {
  56. return (
  57. <>
  58. <Link to='/search'>
  59. <IconButton size={size} aria-label="search" color={color}>
  60. <SearchIcon />
  61. </IconButton>
  62. </Link>
  63. <Link to='/my-orders'>
  64. <IconButton size={size} aria-label="my-orders" color={color}>
  65. <ManageSearchIcon />
  66. </IconButton>
  67. </Link>
  68. <Link to='/wish-list'>
  69. <IconButton size={size} aria-label="wish-list" color={color}>
  70. <Badge
  71. color="success"
  72. badgeContent={valueWishList}
  73. anchorOrigin={{
  74. vertical: 'bottom',
  75. horizontal: 'right',
  76. }}
  77. >
  78. <FavoriteBorderIcon />
  79. </Badge>
  80. </IconButton>
  81. </Link>
  82. <Link to='/basket'>
  83. <IconButton size={size} aria-label="basket" color={color}>
  84. <Badge
  85. color="success"
  86. badgeContent={+Object.entries(cart).reduce((a, b) => {
  87. return a + b[1].count
  88. }, 0)}
  89. anchorOrigin={{
  90. vertical: 'bottom',
  91. horizontal: 'right',
  92. }}
  93. >
  94. <ShoppingCartIcon/>
  95. </Badge>
  96. </IconButton>
  97. </Link>
  98. </>
  99. )
  100. }
  101. const CIconItems = connect(state => ({cart: state.cart}))(IconItems)
  102. const ItemAuth = ({link, text}) => {
  103. return (
  104. <Link style={{textDecoration: 'none', color: '#000'}} to={`/${link}`}>
  105. <MenuItem key={text} onClick={handleCloseNavMenu}>
  106. <Typography textAlign="center" color='#fff'>{text}</Typography>
  107. </MenuItem>
  108. </Link>
  109. )
  110. }
  111. const UserIcon = ({auth}) => {
  112. return (
  113. !localStorage.authToken ?
  114. <Link style={{textDecoration: 'none'}} to={'/my-account'}>
  115. <IconButton sx={{ p: 0 }}>
  116. <Avatar alt="User" src={userDefault} />
  117. </IconButton>
  118. </Link> :
  119. <>
  120. <Tooltip title="Open settings">
  121. <IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
  122. {auth.avatar === null ?
  123. <Avatar alt="User" src={userDefault}/> :
  124. <Avatar alt="User" src={user?.avatar?.url && backURL + '/' + user?.avatar?.url}/>
  125. }
  126. </IconButton>
  127. </Tooltip>
  128. <Menu
  129. sx={{ mt: '55px', ml: '90%'}}
  130. id="menu-appbar"
  131. anchorEl={anchorElUser}
  132. anchorOrigin={{
  133. vertical: 'top',
  134. horizontal: 'right',
  135. }}
  136. keepMounted
  137. transformOrigin={{
  138. vertical: 'top',
  139. horizontal: 'right',
  140. }}
  141. open={Boolean(anchorElUser)}
  142. onClose={handleCloseUserMenu}
  143. >
  144. {settingsDefaultUserAuth.map(item => {
  145. if (item === 'Logout') {
  146. return <CButtonLogOut/>
  147. }
  148. return <ItemAuth text={item}
  149. link={Array.from(item.toLowerCase()).map(i => i === ' ' ? '-' : i).join('')}/>
  150. })}
  151. </Menu>
  152. </>
  153. )
  154. }
  155. const CUserIcon = connect(state => ({auth: state.auth}))(UserIcon)
  156. const ButtonLogOut = ({actionLogOut, actionUserRemove}) => {
  157. return (
  158. <Button
  159. onClick={() => {actionLogOut(); actionUserRemove(); handleCloseNavMenu()}}
  160. style={{textDecoration: 'none', color: '#fff', textAlign: "center", width: '100%'}}
  161. >
  162. Log out
  163. </Button>
  164. )
  165. }
  166. const CButtonLogOut = connect(null, {actionLogOut: actionAuthLogout, actionUserRemove: actionUserRemove})(ButtonLogOut)
  167. return (
  168. <AppBar sx={{padding: '10px 0', backgroundColor: 'rgb(131,179,175)'}} className='Header' position="fixed" enableColorOnDark={true}>
  169. <Container maxWidth="xl">
  170. <Toolbar disableGutters>
  171. <Typography
  172. variant="h6"
  173. noWrap
  174. component="div"
  175. sx={{ mr: 2, display: { xs: 'none', md: 'flex' } }}
  176. >
  177. <LogoItem/>
  178. </Typography>
  179. <Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}>
  180. <IconButton
  181. size="large"
  182. aria-label="account of current user"
  183. aria-controls="menu-appbar"
  184. aria-haspopup="true"
  185. onClick={handleOpenNavMenu}
  186. color="inherit"
  187. >
  188. <MenuIcon />
  189. </IconButton>
  190. <Menu className='Header__Burger'
  191. id="menu-appbar"
  192. anchorEl={anchorElNav}
  193. anchorOrigin={{
  194. vertical: 'bottom',
  195. horizontal: 'left',
  196. }}
  197. keepMounted
  198. transformOrigin={{
  199. vertical: 'top',
  200. horizontal: 'left',
  201. }}
  202. open={Boolean(anchorElNav)}
  203. onClose={handleCloseNavMenu}
  204. sx={{
  205. display: { xs: 'block', md: 'none' },
  206. }}
  207. >
  208. {pages.map((page) => (
  209. <MenuItem key={page} onClick={handleCloseNavMenu}>
  210. <LinkItem page={page} color={'#fff'}/>
  211. </MenuItem>
  212. ))}
  213. <MenuItem onClick={handleCloseNavMenu}>
  214. <CIconItems size={'large'} color={'inherit'} />
  215. </MenuItem>
  216. </Menu>
  217. </Box>
  218. <Typography
  219. variant="h6"
  220. noWrap
  221. component="div"
  222. sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}
  223. >
  224. <LogoItem />
  225. </Typography>
  226. <Box className='Header__Links' sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}>
  227. {pages.map((page) => (
  228. <LinkItem page={page} color={'#fff'}/>
  229. ))}
  230. </Box>
  231. <Box className='Header__Icons' sx={{ flexGrow: 0, display: { xs: 'none', md: 'flex' } }}>
  232. <CIconItems size={'large'} />
  233. </Box>
  234. <Box sx={{ flexGrow: 0 }}>
  235. <CUserIcon/>
  236. </Box>
  237. </Toolbar>
  238. </Container>
  239. </AppBar>
  240. );
  241. };
  242. const CHeader = connect(state => ({user: state.user}), {createUser: actionFullUserFindOne})(Header)
  243. export default CHeader;