Skip to content

Commit 61f5c6a

Browse files
committed
refactor(appmenu): move the duplicate logic into hook
1 parent 8c2389b commit 61f5c6a

File tree

5 files changed

+36
-60
lines changed

5 files changed

+36
-60
lines changed

src/components/appMenu/CircularMenu/CircularMenu.tsx

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import { useState, useEffect } from 'react';
21
import getMenuItems from 'src/utils/appsMenu';
32
import styles from './CircularMenu.module.scss';
4-
import { MenuItem } from 'src/types/menu';
5-
import { useLocation } from 'react-router-dom';
63
import _ from 'lodash';
74
import CircularMenuItem from './CircularMenuItem';
5+
import { useActiveMenuItem } from 'src/hooks/useActiveMenuItem';
86

97
declare module 'react' {
108
interface CSSProperties {
@@ -15,43 +13,18 @@ declare module 'react' {
1513
}
1614

1715
function CircularMenu({ circleSize }) {
18-
const [activeItem, setActiveItem] = useState<MenuItem | null>(null);
1916
const chunkSize = 7;
2017
const linkChunks = _.chunk(getMenuItems(), chunkSize);
21-
const location = useLocation();
18+
19+
const { isActiveItem, activeItem } = useActiveMenuItem(getMenuItems());
2220

2321
const calculateDiameter = (index, circleSize) => {
2422
const menuCircleDiameter = circleSize / 2 + 45 * (index + 1) - 10;
2523
const nextLevelMenuAngle = index === 1 ? -28 : 0; // decreases the angle of second menu layer
26-
const menuItemsAngle = index === 1 ? 16 : 23; // angle in wich menu items spreads around brain
24+
const menuItemsAngle = index === 1 ? 16 : 23; // angle in which menu items spread around the brain
2725
return { menuCircleDiameter, nextLevelMenuAngle, menuItemsAngle };
2826
};
2927

30-
const isActiveItem = (item: MenuItem) => {
31-
if (location.pathname === item.to) {
32-
return true;
33-
}
34-
if (
35-
item.to === '/robot' &&
36-
(location.pathname.includes('@') || location.pathname.includes('neuron/'))
37-
) {
38-
return true;
39-
}
40-
if (item.to === '/senate' && location.pathname.startsWith('/senate/')) {
41-
return true;
42-
}
43-
return item.subItems?.some((subItem) => location.pathname === subItem.to);
44-
};
45-
46-
useEffect(() => {
47-
const activeMenuItem = getMenuItems().find((item) => isActiveItem(item));
48-
setActiveItem(activeMenuItem || null);
49-
}, [location]);
50-
51-
const handleItemClick = (item: MenuItem) => {
52-
setActiveItem(item);
53-
};
54-
5528
return (
5629
<div>
5730
{linkChunks.map((chunk, index) => {
@@ -77,7 +50,7 @@ function CircularMenu({ circleSize }) {
7750
<li key={index}>
7851
<CircularMenuItem
7952
item={item}
80-
onClick={() => handleItemClick(item)}
53+
onClick={() => isActiveItem(item)}
8154
selected={isSelected}
8255
/>
8356
</li>

src/components/appMenu/CircularMenu/CircularMenuItem.module.scss

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@import '../../../style/mixins.scss';
22

3-
.menu_item {
3+
.menuItem {
44
box-shadow: 0px 0px 13px #ffffff54;
55
opacity: 1;
66
background-color: #101010;
@@ -13,14 +13,14 @@
1313
pointer-events: auto;
1414
}
1515

16-
.menu_item.active {
16+
.menuItem.active {
1717
border: 1px solid #ffffff6b;
1818
box-shadow: 0px 0px 8px #ffffff98 inset, 0px 0px 13px #ffffff98;
1919
width: 100%;
2020
height: 100%;
2121
}
2222

23-
.menu_item:hover {
23+
.menuItem:hover {
2424
border: 1px solid #4ed6ae;
2525
box-shadow: 0px 0px 8px #4ed6ae inset, 0px 0px 13px #4ed6ae;
2626
}

src/components/appMenu/CircularMenu/CircularMenuItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function CircularMenuItem({ item, onClick, selected }: Props) {
1414
const isExternal = item.to.startsWith('http');
1515

1616
return (
17-
<div className={cx(styles.menu_item, { [styles.active]: selected })}>
17+
<div className={cx(styles.menuItem, { [styles.active]: selected })}>
1818
<AdviserHoverWrapper adviserContent={item.name}>
1919
<NavLink
2020
to={item.to}

src/components/appMenu/MobileMenu/MobileMenu.tsx

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,18 @@
11
import { useState, useRef } from 'react';
2-
import { useLocation, NavLink } from 'react-router-dom';
2+
import { NavLink } from 'react-router-dom';
33
import getMenuItems from 'src/utils/appsMenu';
44
import styles from './MobileMenu.module.scss';
5-
import { MenuItem } from 'src/types/menu';
65
import cx from 'classnames';
76
import useOnClickOutside from 'src/hooks/useOnClickOutside';
7+
import { useActiveMenuItem } from 'src/hooks/useActiveMenuItem';
88

99
const MobileMenu = () => {
1010
const [isOpen, setIsOpen] = useState(false);
11-
const location = useLocation();
1211
const menuRef = useRef<HTMLDivElement>(null);
1312

1413
const toggleMenu = () => setIsOpen(!isOpen);
1514

16-
const isActiveItem = (item: MenuItem) => {
17-
if (location.pathname === item.to) {
18-
return true;
19-
}
20-
if (
21-
item.to === '/robot' &&
22-
(location.pathname.includes('@') || location.pathname.includes('neuron/'))
23-
) {
24-
return true;
25-
}
26-
if (item.to === '/senate' && location.pathname.startsWith('/senate/')) {
27-
return true;
28-
}
29-
return item.subItems?.some((subItem) => location.pathname === subItem.to);
30-
};
31-
32-
const getActiveItem = () => {
33-
return getMenuItems().find((item) => isActiveItem(item)) || null;
34-
};
35-
36-
const activeItem = getActiveItem();
15+
const { isActiveItem, activeItem } = useActiveMenuItem(getMenuItems());
3716

3817
useOnClickOutside(menuRef, () => setIsOpen(false));
3918

src/hooks/useActiveMenuItem.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { MenuItem } from 'src/types/menu';
2+
import { useLocation } from 'react-router-dom';
3+
4+
export const useActiveMenuItem = (menuItems: MenuItem[]) => {
5+
const location = useLocation();
6+
const isActiveItem = (item: MenuItem) => {
7+
if (location.pathname === item.to) {
8+
return true;
9+
}
10+
if (
11+
item.to === '/robot' &&
12+
(location.pathname.includes('@') || location.pathname.includes('neuron/'))
13+
) {
14+
return true;
15+
}
16+
if (item.to === '/senate' && location.pathname.startsWith('/senate/')) {
17+
return true;
18+
}
19+
return item.subItems?.some((subItem) => location.pathname === subItem.to);
20+
};
21+
22+
const activeItem = menuItems.find((item) => isActiveItem(item)) || null;
23+
return { isActiveItem, activeItem };
24+
};

0 commit comments

Comments
 (0)