Skip to content

Commit 835daca

Browse files
authored
[HUMAN App] refactor: layout components (#3220)
1 parent 4312262 commit 835daca

File tree

20 files changed

+413
-353
lines changed

20 files changed

+413
-353
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { t } from 'i18next';
2-
import type { BottomMenuItem } from '@/shared/components/layout/protected/drawer-navigation';
32
import { HelpIcon, UserOutlinedIcon } from '@/shared/components/ui/icons';
43
import { routerPaths } from '@/router/router-paths';
54
import { DarkModeSwitch } from '@/shared/components/ui/dark-mode-switch';
5+
import { type MenuItem } from '../layout/protected';
66

7-
export const operatorDrawerBottomMenuItems: BottomMenuItem[] = [
7+
export const operatorDrawerBottomMenuItems: MenuItem[] = [
88
{
99
label: t('components.DrawerNavigation.profile'),
1010
link: routerPaths.operator.profile,
Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,26 @@
11
import { t } from 'i18next';
2-
import type {
3-
BottomMenuItem,
4-
TopMenuItem,
5-
} from '@/shared/components/layout/protected/drawer-navigation';
62
import {
73
HelpIcon,
84
UserOutlinedIcon,
95
WorkIcon,
106
} from '@/shared/components/ui/icons';
11-
import { routerPaths } from '@/router/router-paths';
127
import { DarkModeSwitch } from '@/shared/components/ui/dark-mode-switch';
138
import type { UserData } from '@/modules/auth/context/auth-context';
9+
import { routerPaths } from '@/router/router-paths';
10+
import { type MenuItem } from '../layout/protected';
1411

15-
export const workerDrawerTopMenuItems = (
16-
user: UserData | null
17-
): TopMenuItem[] => {
12+
export const workerDrawerTopMenuItems = (user: UserData | null): MenuItem[] => {
1813
return [
19-
...[
20-
{
21-
label: t('components.DrawerNavigation.jobs'),
22-
icon: <WorkIcon />,
23-
link: routerPaths.worker.jobsDiscovery,
24-
disabled: !user?.wallet_address || user.kyc_status !== 'approved',
25-
},
26-
],
14+
{
15+
label: t('components.DrawerNavigation.jobs'),
16+
icon: <WorkIcon />,
17+
link: routerPaths.worker.jobsDiscovery,
18+
disabled: !user?.wallet_address || user.kyc_status !== 'approved',
19+
},
2720
];
2821
};
2922

30-
export const workerDrawerBottomMenuItems: BottomMenuItem[] = [
23+
export const workerDrawerBottomMenuItems: MenuItem[] = [
3124
{
3225
label: t('components.DrawerNavigation.profile'),
3326
link: routerPaths.worker.profile,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './drawer-menu-items-operator';
2+
export * from './drawer-menu-items-worker';

packages/apps/human-app/frontend/src/shared/components/layout/footer.tsx renamed to packages/apps/human-app/frontend/src/router/components/footer.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@ interface FooterProps {
1010
displayChatIcon?: boolean;
1111
isProtected?: boolean;
1212
}
13-
export function Footer({ isProtected, displayChatIcon = true }: FooterProps) {
13+
export function Footer({
14+
isProtected,
15+
displayChatIcon = true,
16+
}: Readonly<FooterProps>) {
1417
const { colorPalette } = useColorMode();
1518
const { t } = useTranslation();
1619
const isMobile = useIsMobile('md');
1720

18-
const parseLeftPadding = () => {
21+
const getLeftPadding = () => {
1922
if (isMobile) {
2023
return '0';
2124
}
@@ -31,7 +34,7 @@ export function Footer({ isProtected, displayChatIcon = true }: FooterProps) {
3134
container
3235
sx={{
3336
pr: 0,
34-
pl: parseLeftPadding(),
37+
pl: getLeftPadding(),
3538
pb: isMobile ? 0 : '32px',
3639
[breakpoints.mobile]: {
3740
pr: 0,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './drawer-menu-items';
2+
export * from './layout/protected';
3+
export * from './layout/unprotected';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './is-drawer-item';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { type MenuItem, type DrawerItem } from '../protected';
2+
3+
export function isDrawerItem(item: MenuItem): item is DrawerItem {
4+
return 'label' in item;
5+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import {
2+
List,
3+
ListItem,
4+
Stack,
5+
ListItemButton,
6+
ListItemText,
7+
Typography,
8+
} from '@mui/material';
9+
import { useLocation } from 'react-router-dom';
10+
import { useColorMode } from '@/shared/contexts/color-mode';
11+
import { useIsMobile } from '@/shared/hooks';
12+
import { colorPalette } from '@/shared/styles/color-palette';
13+
import { onlyDarkModeColor } from '@/shared/styles/dark-color-palette';
14+
import { isDrawerItem } from '../helpers';
15+
import { type MenuItem, type DrawerItem } from './drawer-navigation';
16+
import { NAVBAR_PADDING } from './navbar';
17+
18+
interface MenuItemListProps {
19+
handleItemClick: (item: DrawerItem) => void;
20+
items?: MenuItem[];
21+
}
22+
export function BottomMenuItemsList({
23+
handleItemClick,
24+
items = [],
25+
}: Readonly<MenuItemListProps>) {
26+
const { isDarkMode } = useColorMode();
27+
const isMobile = useIsMobile();
28+
const location = useLocation();
29+
30+
return (
31+
<List>
32+
{items.map((item) => {
33+
if (!isDrawerItem(item)) {
34+
return (
35+
<ListItem key={`list-item-${item.key}`}>
36+
<Stack
37+
direction="row"
38+
sx={{
39+
width: '100%',
40+
mx: isMobile ? '28px' : NAVBAR_PADDING,
41+
}}
42+
>
43+
{item}
44+
</Stack>
45+
</ListItem>
46+
);
47+
}
48+
49+
const { label, link, icon } = item;
50+
const isActive = location.pathname === link;
51+
52+
return (
53+
<ListItem
54+
alignItems="center"
55+
disablePadding
56+
key={label}
57+
sx={{ padding: '0 8px', borderRadius: '4px' }}
58+
>
59+
<ListItemButton
60+
alignItems="center"
61+
onClick={() => {
62+
handleItemClick(item);
63+
}}
64+
selected={isActive}
65+
sx={{
66+
borderRadius: '4px',
67+
p: 0,
68+
'&.Mui-selected': {
69+
backgroundColor: isDarkMode
70+
? onlyDarkModeColor.listItemColor
71+
: colorPalette.primary.shades,
72+
},
73+
}}
74+
>
75+
<Stack
76+
alignItems="center"
77+
direction="row"
78+
gap="32px"
79+
justifyContent="center"
80+
sx={{
81+
padding: '8px 16px',
82+
}}
83+
>
84+
{icon}
85+
<ListItemText
86+
disableTypography
87+
primary={
88+
<Typography
89+
component="span"
90+
variant={isMobile ? 'h5' : 'body1'}
91+
>
92+
{label}
93+
</Typography>
94+
}
95+
sx={{
96+
textAlign: 'center',
97+
marginLeft: '10px',
98+
}}
99+
/>
100+
</Stack>
101+
</ListItemButton>
102+
</ListItem>
103+
);
104+
})}
105+
</List>
106+
);
107+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import Box from '@mui/material/Box';
2+
import Drawer from '@mui/material/Drawer';
3+
import CssBaseline from '@mui/material/CssBaseline';
4+
import { Stack } from '@mui/material';
5+
import { useNavigate } from 'react-router-dom';
6+
import { t } from 'i18next';
7+
import type { Dispatch, SetStateAction } from 'react';
8+
import { HumanLogoNavbarIcon } from '@/shared/components/ui/icons';
9+
import { Button } from '@/shared/components/ui/button';
10+
import { useIsMobile } from '@/shared/hooks/use-is-mobile';
11+
import { useHandleMainNavIconClick } from '@/shared/hooks/use-handle-main-nav-icon-click';
12+
import { TopMenuItemsList } from './top-menu-items-list';
13+
import { BottomMenuItemsList } from './bottom-menu-items-list';
14+
15+
const drawerWidth = 240;
16+
17+
export interface DrawerItem {
18+
label: string;
19+
link?: string;
20+
href?: string;
21+
icon?: JSX.Element;
22+
disabled?: boolean;
23+
onClick?: () => void;
24+
}
25+
26+
export type MenuItem = DrawerItem | JSX.Element;
27+
interface DrawerNavigationProps {
28+
open: boolean;
29+
setDrawerOpen: Dispatch<SetStateAction<boolean>>;
30+
topMenuItems?: MenuItem[];
31+
bottomMenuItems?: MenuItem[];
32+
signOut: () => void;
33+
}
34+
35+
export function DrawerNavigation({
36+
open,
37+
setDrawerOpen,
38+
topMenuItems,
39+
bottomMenuItems,
40+
signOut,
41+
}: Readonly<DrawerNavigationProps>) {
42+
const navigate = useNavigate();
43+
const isMobile = useIsMobile();
44+
const handleMainNavIconClick = useHandleMainNavIconClick();
45+
46+
const handleItemClick = ({ disabled, href, link, onClick }: DrawerItem) => {
47+
if (disabled) return;
48+
49+
if (isMobile) setDrawerOpen(false);
50+
51+
if (onClick) {
52+
onClick();
53+
return;
54+
}
55+
56+
if (href) {
57+
window.open(href, '_blank', 'noreferrer');
58+
return;
59+
}
60+
61+
if (link) {
62+
navigate(link);
63+
}
64+
};
65+
66+
return (
67+
<Box
68+
sx={{
69+
display: 'flex',
70+
}}
71+
>
72+
<CssBaseline />
73+
<Drawer
74+
anchor="left"
75+
open={open}
76+
sx={{
77+
width: drawerWidth,
78+
flexShrink: 0,
79+
'& .MuiDrawer-paper': {
80+
width: isMobile ? '100%' : drawerWidth,
81+
boxSizing: 'border-box',
82+
paddingTop: '44px',
83+
},
84+
}}
85+
variant="persistent"
86+
>
87+
{!isMobile && (
88+
<Stack
89+
alignItems="flex-start"
90+
sx={{ paddingLeft: '26px', cursor: 'pointer' }}
91+
onClick={() => {
92+
handleMainNavIconClick();
93+
}}
94+
>
95+
<HumanLogoNavbarIcon />
96+
</Stack>
97+
)}
98+
<Stack
99+
justifyContent="space-between"
100+
sx={{
101+
height: '100%',
102+
}}
103+
>
104+
<TopMenuItemsList
105+
handleItemClick={handleItemClick}
106+
items={topMenuItems}
107+
/>
108+
<BottomMenuItemsList
109+
handleItemClick={handleItemClick}
110+
items={bottomMenuItems}
111+
/>
112+
</Stack>
113+
<Button
114+
onClick={() => {
115+
if (isMobile) setDrawerOpen(false);
116+
signOut();
117+
}}
118+
size="large"
119+
sx={{
120+
marginBottom: '44px',
121+
mx: isMobile ? '28px' : '16px',
122+
}}
123+
variant="outlined"
124+
>
125+
{t('components.DrawerNavigation.logout')}
126+
</Button>
127+
</Drawer>
128+
</Box>
129+
);
130+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './layout';
2+
export * from './drawer-navigation';

0 commit comments

Comments
 (0)