Skip to content

Commit 946e4a5

Browse files
authored
[EC-58] FE/refactor: 권한에 따른 자동화 추가 (#50)
* [EC-58] refactor: sideBarItem 자동 전환 기능 구현 * [EC-58] refactor: 권한에 따른 sidebarItemIcon 자동 적용 추가 * [EC-58] refactor: sidebar 이동에 따른 자동화 기능으로 수정 * [EC-58] chore: utils 파일 간소화 * [EC-58] refactor: sidebar와 tab에 따른 페이지 이동 자동화 추가 * [EC-58] refactor: path 변경에 따른 navigate 이동 * [EC-58] style: utils switch문에서 object 형식으로 변환
1 parent cfa3cf5 commit 946e4a5

File tree

14 files changed

+182
-169
lines changed

14 files changed

+182
-169
lines changed

client/src/components/sideBar/SideBar.jsx

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,17 @@ import React, { useEffect, useState, useRef } from 'react';
22
import { useSelector } from 'react-redux';
33

44
import styles from './SideBar.module.css';
5-
import { studentSideBarList, staffSideBarList } from '../../utils/sideBarList';
6-
import { roleList } from '../../utils/dashBoardList';
75

86
import SideBarItem from './sidebarItem/SidebarItem';
97
import MainButton from '../buttons/mainButton/MainButton';
108

119
export default function SideBar() {
1210
const infoRef = useRef(null);
1311
const [isOpen, setIsOpen] = useState(false);
14-
const [itemList, setItemList] = useState([]);
15-
const { name, role, courseName, phoneNumber, birthDate, email } = useSelector(
12+
const { name, courseName, phoneNumber, birthDate, email } = useSelector(
1613
(state) => state.auth.user,
1714
);
15+
const { sidebarItemList } = useSelector((state) => state.sideBarItem);
1816

1917
useEffect(() => {
2018
const handleClickOutside = (event) => {
@@ -29,15 +27,7 @@ export default function SideBar() {
2927
};
3028
}, []);
3129

32-
useEffect(() => {
33-
if (role === roleList[0]) {
34-
setItemList(studentSideBarList);
35-
} else {
36-
setItemList(staffSideBarList);
37-
}
38-
}, [role]);
39-
40-
const sideBarItems = itemList.map((item, index) => {
30+
const sideBarItems = sidebarItemList.map((item, index) => {
4131
return <SideBarItem key={index} index={index} item={item}></SideBarItem>;
4232
});
4333

client/src/components/sideBar/SideBar.module.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
}
3838

3939
.memberInfoImg img {
40-
width: 100%;
40+
min-width: 100%;
4141
height: 100%;
4242
}
4343

client/src/components/sideBar/sidebarItem/SidebarItem.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import { updateNav } from '../../../store/slices/sideBarItemSlice';
77
export default function SidebarItem({ index, item }) {
88
const dispatch = useDispatch();
99

10-
const currentSideBarItem = useSelector((state) => state.sideBarItem.nav);
11-
const isActive = currentSideBarItem === item;
10+
const { nav } = useSelector((state) => state.sideBarItem);
11+
const isActive = nav === item;
1212

1313
const handleClick = () => {
1414
dispatch(updateNav(item));
Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,13 @@
1-
import React, { useEffect, useState } from 'react';
1+
import React from 'react';
22
import { useSelector } from 'react-redux';
33
import styles from './SidebarItemIcon.module.css';
4-
import { studentSideBarIconList, staffSideBarIconList } from '../../../utils/sideBarList';
5-
import { roleList } from '../../../utils/dashBoardList';
64

75
export default function SidebarItemIcon({ isActive, index }) {
8-
const { role } = useSelector((state) => state.auth.user);
9-
const [icons, setIcons] = useState([]);
10-
11-
useEffect(() => {
12-
if (role === roleList[0]) {
13-
setIcons(studentSideBarIconList);
14-
} else {
15-
setIcons(staffSideBarIconList);
16-
}
17-
}, [role]);
6+
const { sidebarIconList } = useSelector((state) => state.sideBarItem);
187

198
return (
209
<div className={styles.iconBox}>
21-
<img className={isActive ? `${styles.active}` : ''} src={icons[index]} alt="icon" />
10+
<img className={isActive ? `${styles.active}` : ''} src={sidebarIconList[index]} alt="icon" />
2211
</div>
2312
);
2413
}

client/src/components/tab/Tab.jsx

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,12 @@
1-
import React, { useEffect, useState } from 'react';
1+
import React from 'react';
22
import { useSelector } from 'react-redux';
33
import styles from './Tab.module.css';
44
import TabButton from './tabButton/TabButton';
5-
import { roleList } from '../../utils/dashBoardList';
6-
import { getStudentTabContent, getStaffTabContent } from '../../utils/tabContentList';
75

8-
export default function Tab({ menuType }) {
9-
const [tabContents, setTabContents] = useState([]);
10-
const { role } = useSelector((state) => state.auth.user);
6+
export default function Tab() {
7+
const { tabContentsList } = useSelector((state) => state.sideBarItem);
118

12-
useEffect(() => {
13-
if (role === roleList[0]) {
14-
const result = getStudentTabContent(menuType);
15-
setTabContents(result);
16-
} else {
17-
const result = getStaffTabContent(menuType);
18-
setTabContents(result);
19-
}
20-
}, [role, menuType]);
21-
22-
const tabContent = tabContents.map((item, index) => {
9+
const tabContent = tabContentsList.map((item, index) => {
2310
return <TabButton key={index} index={index} item={item}></TabButton>;
2411
});
2512

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React, { useEffect } from 'react'
2+
import { useSelector } from 'react-redux'
3+
import { useNavigate } from 'react-router-dom'
4+
5+
export default function NavigationHandler() {
6+
const path = useSelector((state) => state.sideBarItem.path);
7+
const navigate = useNavigate();
8+
9+
useEffect(() => {
10+
console.log(path)
11+
if (path) {
12+
navigate(path);
13+
}
14+
}, [])
15+
16+
return null;
17+
}

client/src/pages/dashBoard/DashBoard.jsx

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,27 @@
1-
import React, { useEffect, useState } from 'react';
2-
import { useSelector } from 'react-redux';
3-
import { Outlet, useNavigate } from 'react-router-dom';
1+
import React, { useEffect } from 'react';
2+
import { Outlet } from 'react-router-dom';
43

54
import styles from './DashBoard.module.css';
6-
import { roleList } from '../../utils/dashBoardList';
7-
import { studentSideBarList, staffSideBarList } from '../../utils/sideBarList';
8-
import {
9-
studentNavList,
10-
getStudentTabList,
11-
staffNavList,
12-
getStaffTabList,
13-
} from '../../utils/dashBoardList';
145

156
import Tab from '../../components/tab/Tab';
167
import SideBar from '../../components/sideBar/SideBar';
178
import DashBoardItem from '../../components/dashBoardItem/DashBoardItem';
9+
import { useSelector } from 'react-redux';
10+
import { useNavigate } from 'react-router-dom';
1811

1912
export default function DashBoard() {
13+
const { path } = useSelector((state) => state.sideBarItem);
2014
const navigate = useNavigate();
21-
const currentSideBarItem = useSelector((state) => state.sideBarItem.nav);
22-
const { nav, tab } = useSelector((state) => state.sideBarItem);
23-
const { role } = useSelector((state) => state.auth.user);
2415

2516
useEffect(() => {
26-
if (role === roleList[0]) {
27-
const navIndex = studentSideBarList.indexOf(nav);
28-
29-
if (tab > 0) {
30-
const tabList = getStudentTabList(nav, tab);
31-
navigate(`${studentNavList[navIndex]}/${tabList}`);
32-
} else {
33-
navigate(`${studentNavList[navIndex]}`);
34-
}
35-
} else {
36-
const navIndex = staffSideBarList.indexOf(nav);
37-
38-
if (tab > 0) {
39-
const tabList = getStaffTabList(nav, tab);
40-
navigate(`${staffNavList[navIndex]}/${tabList}`);
41-
} else {
42-
navigate(`${staffNavList[navIndex]}`);
43-
}
44-
}
45-
}, [role, nav, tab]);
17+
navigate(path);
18+
}, [path]);
4619

4720
return (
4821
<div className={`container ${styles.dashBoard}`}>
4922
<SideBar />
5023
<div className={styles.dashBoardBox}>
51-
<Tab menuType={currentSideBarItem}></Tab>
24+
<Tab />
5225

5326
{/* TODO : dashBoardContent 내부에 대시보드 및 컴포넌트 사용 */}
5427
<div className={styles.dashBoardContent}>

client/src/pages/login/Login.jsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import React, { useEffect, useState } from 'react';
2+
import { useNavigate } from 'react-router-dom';
3+
import { useDispatch, useSelector } from 'react-redux';
4+
25
import styles from './Login.module.css';
3-
import InputBox from '../../components/inputBox/InputBox';
4-
import MainButton from '../../components/buttons/mainButton/MainButton';
56
import { authApi } from '../../api/authApi';
6-
import { useDispatch, useSelector } from 'react-redux';
77
import { login } from '../../store/slices/authSlice';
8-
import { useNavigate } from 'react-router-dom';
98
import { setRole } from '../../store/slices/sideBarItemSlice';
9+
10+
import InputBox from '../../components/inputBox/InputBox';
11+
import MainButton from '../../components/buttons/mainButton/MainButton';
12+
1013
export default function Login() {
1114
const isLoggedIn = useSelector((state) => state.auth.isLoggedIn);
1215
const dispatch = useDispatch();

client/src/router/index.jsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createBrowserRouter } from 'react-router-dom';
1+
import { Navigate, createBrowserRouter } from 'react-router-dom';
22
import RootLayout from '../layout/RootLayout';
33

44
import NotFound from '../pages/error/NotFound';
@@ -18,6 +18,8 @@ import StaffAttendanceAbsence from '../pages/staffAttendanceAbsence/StaffAttenda
1818
import StaffStudentManage from '../pages/staffStudentManage/StaffStudentManage';
1919
import StaffRoomReservation from '../pages/staffRoomReservation/StaffRoomReservation';
2020

21+
import NavigationHandler from '../handler/NavigationHandler';
22+
2123
const router = createBrowserRouter([
2224
{
2325
path: '/',
@@ -82,6 +84,14 @@ const router = createBrowserRouter([
8284
},
8385
],
8486
},
87+
{
88+
path: '/notfound',
89+
element: <NotFound />,
90+
},
91+
{
92+
path: '*',
93+
element: <Navigate to="/notfound" replace />,
94+
},
8595
],
8696
},
8797
]);
Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,40 @@
1-
import { createSlice } from '@reduxjs/toolkit';
1+
import { createAction, createSlice } from '@reduxjs/toolkit';
22
import { login, logout } from './authSlice';
33
import { jwtDecode } from 'jwt-decode';
44

5+
import {
6+
studentSideBarList,
7+
staffSideBarList,
8+
studentSideBarIconList,
9+
staffSideBarIconList,
10+
getStudentTabContent,
11+
getStaffTabContent,
12+
} from '../../utils/sideBarList';
13+
14+
import { getStudentPath, getStaffPath } from '../../utils/dashBoardList';
15+
16+
export const updateNav = createAction('sideBarItem/updateNav');
17+
export const updateTab = createAction('sideBarItem/updateTab');
18+
519
const initialState = {
620
nav: '',
721
tab: 0,
22+
sidebarItemList: [],
23+
sidebarIconList: [],
24+
tabContentsList: [],
25+
role: null,
26+
path: '/',
827
};
928

1029
const sideBarItemSlice = createSlice({
1130
name: 'sideBarItem',
1231
initialState,
1332
reducers: {
14-
updateNav: (state, action) => {
15-
state.nav = action.payload;
16-
state.tab = 0;
17-
},
18-
updateTab: (state, action) => {
19-
state.tab = action.payload;
20-
},
2133
setRole: (state, action) => {
2234
state.nav = action.payload;
35+
state.sidebarItemList = action.payload;
36+
state.sidebarIconList = action.payload;
37+
state.tabContentsList = action.payload;
2338
},
2439
},
2540
extraReducers: (builder) => {
@@ -28,13 +43,50 @@ const sideBarItemSlice = createSlice({
2843
const accessToken = action.payload.accessToken.replace('Bearer ', '');
2944
const decodedToken = jwtDecode(accessToken);
3045
const role = decodedToken.roles[0];
46+
47+
state.role = role;
3148
state.nav = role === 'STUDENT' ? '출석' : '출결';
49+
state.sidebarItemList = role === 'STUDENT' ? studentSideBarList : staffSideBarList;
50+
state.sidebarIconList = role === 'STUDENT' ? studentSideBarIconList : staffSideBarIconList;
51+
state.tabContentsList =
52+
role === 'STUDENT' ? getStudentTabContent(state.nav) : getStaffTabContent(state.nav);
53+
state.path =
54+
state.role === 'STUDENT'
55+
? getStudentPath(state.nav, state.tab)
56+
: getStaffPath(state.nav, state.tab);
3257
})
3358
.addCase(logout, (state) => {
59+
state.role = null;
3460
state.nav = '';
61+
state.sidebarItemList = [];
62+
state.sidebarIconList = [];
63+
state.tabContentsList = [];
64+
})
65+
.addCase(updateNav, (state, action) => {
66+
if (state.role) {
67+
state.nav = action.payload;
68+
state.tab = 0;
69+
state.tabContentsList =
70+
state.role === 'STUDENT'
71+
? getStudentTabContent(state.nav)
72+
: getStaffTabContent(state.nav);
73+
state.path =
74+
state.role === 'STUDENT'
75+
? getStudentPath(state.nav, state.tab)
76+
: getStaffPath(state.nav, state.tab);
77+
}
78+
})
79+
.addCase(updateTab, (state, action) => {
80+
if (state.role) {
81+
state.tab = action.payload;
82+
state.path =
83+
state.role === 'STUDENT'
84+
? getStudentPath(state.nav, state.tab)
85+
: getStaffPath(state.nav, state.tab);
86+
}
3587
});
3688
},
3789
});
3890

39-
export const { updateNav, updateTab, setRole } = sideBarItemSlice.actions;
91+
export const { setRole } = sideBarItemSlice.actions;
4092
export default sideBarItemSlice.reducer;

0 commit comments

Comments
 (0)