Header.jsx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  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 {backURL} from "../actions/PathDB";
  14. import userDefault from "../img/header/userDefault.png"
  15. const pages = ['catalog', 'about us', 'our team', 'faq', 'contact']
  16. const settingsDefaultUserAuth = ['Profile', 'Dashboard', 'Logout']
  17. const Header = ({user={}}) => {
  18. const [anchorElNav, setAnchorElNav] = useState(null);
  19. const [anchorElUser, setAnchorElUser] = useState(null);
  20. const handleOpenNavMenu = (event) => {
  21. setAnchorElNav(event.currentTarget);
  22. };
  23. const handleOpenUserMenu = (event) => {
  24. setAnchorElUser(event.currentTarget);
  25. };
  26. const handleCloseNavMenu = () => {
  27. setAnchorElNav(null);
  28. };
  29. const handleCloseUserMenu = () => {
  30. setAnchorElUser(null);
  31. };
  32. const LogoItem = () => {
  33. return (
  34. <Link
  35. to='/'
  36. className="Header__Logo"
  37. >
  38. ABRAXAS
  39. </Link>
  40. )
  41. }
  42. const LinkItem = ({page, color='white'}) => {
  43. return (
  44. <Button
  45. key={page.toString()}
  46. onClick={handleCloseNavMenu}
  47. sx={{
  48. my: 2,
  49. color: color,
  50. display: 'block'
  51. }}
  52. >
  53. <Link
  54. to={`/${Array.from(page.toLowerCase()).map(i => i === ' ' ? '-' : i).join('')}`}
  55. className="Header__Link"> {page}
  56. </Link>
  57. </Button>
  58. )
  59. }
  60. const IconItems = ({cart={}, wishlist={}, size="large", color='default'}) => {
  61. return (
  62. <>
  63. <Link to='/search'>
  64. <IconButton
  65. key={'search'}
  66. size={size}
  67. aria-label="search"
  68. color={color}
  69. >
  70. <SearchIcon />
  71. </IconButton>
  72. </Link>
  73. <Link to='/my-orders'>
  74. <IconButton
  75. key={'my-orders'}
  76. size={size}
  77. aria-label="my-orders"
  78. color={color}
  79. >
  80. <ManageSearchIcon />
  81. </IconButton>
  82. </Link>
  83. <Link to='/wish-list'>
  84. <IconButton
  85. key={'wish-list'}
  86. size={size}
  87. aria-label="wish-list"
  88. color={color}
  89. >
  90. <Badge
  91. color="success"
  92. badgeContent={+Object.entries(wishlist).length}
  93. anchorOrigin={{
  94. vertical: 'bottom',
  95. horizontal: 'right',
  96. }}
  97. >
  98. <FavoriteBorderIcon />
  99. </Badge>
  100. </IconButton>
  101. </Link>
  102. <Link to='/basket'>
  103. <IconButton
  104. key={'basket'}
  105. size={size}
  106. aria-label="basket"
  107. color={color}
  108. >
  109. <Badge
  110. color="success"
  111. badgeContent={+Object.entries(cart).reduce((a, b) => {
  112. return a + b[1].count
  113. }, 0)}
  114. anchorOrigin={{
  115. vertical: 'bottom',
  116. horizontal: 'right',
  117. }}
  118. >
  119. <ShoppingCartIcon/>
  120. </Badge>
  121. </IconButton>
  122. </Link>
  123. </>
  124. )
  125. }
  126. const CIconItems = connect(state => ({cart: state.cart, wishlist: state.wishlist}))(IconItems)
  127. const ItemAuth = ({link, text}) => {
  128. return (
  129. <Link
  130. style={{
  131. textDecoration: 'none',
  132. color: '#000'
  133. }}
  134. to={`/${link}`}
  135. >
  136. <MenuItem
  137. key={text}
  138. onClick={handleCloseNavMenu}
  139. >
  140. <Typography
  141. textAlign="center"
  142. color='#fff'
  143. >
  144. {text}
  145. </Typography>
  146. </MenuItem>
  147. </Link>
  148. )
  149. }
  150. const UserIcon = ({auth}) => {
  151. return (
  152. Object.entries(auth).length === 0 ?
  153. <Link
  154. style={{textDecoration: 'none'}}
  155. to={'/my-account'}
  156. >
  157. <IconButton sx={{ p: 0 }}>
  158. <Avatar
  159. alt="User default"
  160. src={userDefault}
  161. />
  162. </IconButton>
  163. </Link> :
  164. <>
  165. <Tooltip title="Open settings">
  166. <IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
  167. {!auth.avatar && auth.avatar === null ?
  168. <Avatar
  169. alt="User"
  170. src={userDefault}/>
  171. :
  172. <Avatar
  173. alt="User"
  174. src={user?.avatar?.url && backURL + '/' + user?.avatar?.url}
  175. />
  176. }
  177. </IconButton>
  178. </Tooltip>
  179. <Menu
  180. sx={{ mt: '55px', ml: '90%'}}
  181. id="menu-appbar"
  182. anchorEl={anchorElUser}
  183. anchorOrigin={{
  184. vertical: 'top',
  185. horizontal: 'right',
  186. }}
  187. keepMounted
  188. transformOrigin={{
  189. vertical: 'top',
  190. horizontal: 'right',
  191. }}
  192. open={Boolean(anchorElUser)}
  193. onClose={handleCloseUserMenu}
  194. >
  195. {settingsDefaultUserAuth.map(item => {
  196. if (item === 'Logout') {
  197. return <CButtonLogOut key={'Logout'}/>
  198. }
  199. else if(item === 'Dashboard'){
  200. if (auth.payload?.sub?.acl[2]){
  201. return (
  202. <ItemAuth
  203. link={'admin'}
  204. text={'Dashboard'}
  205. key={'admin'}
  206. />
  207. )
  208. }
  209. }
  210. else if(item !== 'Dashboard') {
  211. return (
  212. <ItemAuth
  213. key={item.toString()}
  214. text={item}
  215. link={Array.from(item.toLowerCase()).map(i => i === ' ' ? '-' : i).join('')}
  216. />
  217. )
  218. }
  219. })}
  220. </Menu>
  221. </>
  222. )
  223. }
  224. const CUserIcon = connect(state => ({auth: state.auth}))(UserIcon)
  225. const ButtonLogOut = ({actionLogOut, actionUserRemove}) => {
  226. return (
  227. <Button
  228. onClick={() => {
  229. actionLogOut();
  230. actionUserRemove();
  231. handleCloseNavMenu();
  232. }}
  233. style={{
  234. textDecoration: 'none',
  235. textTransform: 'capitalize',
  236. fontWeight: '400',
  237. color: '#fff',
  238. textAlign: "center",
  239. width: '100%'
  240. }}
  241. >
  242. Log out
  243. </Button>
  244. )
  245. }
  246. const CButtonLogOut = connect(null, {actionLogOut: actionAuthLogout,
  247. actionUserRemove: actionUserRemove})(ButtonLogOut)
  248. return (
  249. <AppBar
  250. sx={{
  251. padding: '10px 0',
  252. backgroundColor: 'rgb(131,179,175)'
  253. }}
  254. className='Header'
  255. position="fixed"
  256. enableColorOnDark={true}
  257. >
  258. <Container maxWidth="xl">
  259. <Toolbar disableGutters>
  260. <Typography
  261. variant="h6"
  262. noWrap
  263. component="div"
  264. sx={{ mr: 2,
  265. display: {
  266. xs: 'none',
  267. md: 'flex'
  268. }
  269. }}
  270. >
  271. <LogoItem/>
  272. </Typography>
  273. <Box
  274. sx={{
  275. flexGrow: 1,
  276. display: { xs: 'flex', md: 'none' }
  277. }}
  278. >
  279. <IconButton
  280. size="large"
  281. aria-label="account of current user"
  282. aria-controls="menu-appbar"
  283. aria-haspopup="true"
  284. onClick={handleOpenNavMenu}
  285. color="inherit"
  286. >
  287. <MenuIcon />
  288. </IconButton>
  289. <Menu className='Header__Burger'
  290. id="menu-appbar"
  291. anchorEl={anchorElNav}
  292. anchorOrigin={{
  293. vertical: 'bottom',
  294. horizontal: 'left',
  295. }}
  296. keepMounted
  297. transformOrigin={{
  298. vertical: 'top',
  299. horizontal: 'left',
  300. }}
  301. open={Boolean(anchorElNav)}
  302. onClose={handleCloseNavMenu}
  303. sx={{
  304. display: { xs: 'block', md: 'none' },
  305. }}
  306. >
  307. {pages.map((page) => (
  308. <MenuItem
  309. key={page.toString()}
  310. onClick={handleCloseNavMenu}
  311. >
  312. <LinkItem
  313. key={page.toString()}
  314. page={page}
  315. color={'#fff'}
  316. />
  317. </MenuItem>
  318. ))}
  319. <MenuItem onClick={handleCloseNavMenu}>
  320. <CIconItems
  321. size={'large'}
  322. color={'inherit'}
  323. />
  324. </MenuItem>
  325. </Menu>
  326. </Box>
  327. <Typography
  328. variant="h6"
  329. noWrap
  330. component="div"
  331. sx={{
  332. flexGrow: 1,
  333. display: { xs: 'flex', md: 'none' }
  334. }}
  335. >
  336. <LogoItem />
  337. </Typography>
  338. <Box
  339. className='Header__Links'
  340. sx={{
  341. flexGrow: 1,
  342. display: { xs: 'none', md: 'flex' }
  343. }}
  344. >
  345. {pages.map((page) => (
  346. <LinkItem
  347. key={page.toString()}
  348. page={page}
  349. color={'#fff'}
  350. />
  351. ))}
  352. </Box>
  353. <Box
  354. className='Header__Icons'
  355. sx={{
  356. flexGrow: 0,
  357. display: { xs: 'none', md: 'flex' }
  358. }}
  359. >
  360. <CIconItems size={'large'} />
  361. </Box>
  362. <Box sx={{ flexGrow: 0 }}>
  363. <CUserIcon/>
  364. </Box>
  365. </Toolbar>
  366. </Container>
  367. </AppBar>
  368. );
  369. };
  370. const CHeader = connect(state => ({user: state.user}))(Header)
  371. export default CHeader;