diff --git a/src/components/admin/adminUserDetail/AdminUserDetail.styled.ts b/src/components/admin/adminUserDetail/AdminUserDetail.styled.ts new file mode 100644 index 00000000..fed21314 --- /dev/null +++ b/src/components/admin/adminUserDetail/AdminUserDetail.styled.ts @@ -0,0 +1,84 @@ +// src/components/admin/userDetail/AdminUserDetail.styled.ts +import styled from 'styled-components'; +import { SpinnerContainer } from '../../user/mypage/Spinner.styled'; +import { Link } from 'react-router-dom'; +import Button from '../../common/Button/Button'; + +export const Container = styled.div` + width: 100%; + height: 800px; + margin: 6rem auto 0; + display: flex; + flex-direction: column; +`; + +export const Spinner = styled(SpinnerContainer)``; + +export const HeaderArea = styled.div` + display: flex; + justify-content: right; + align-items: center; + margin-bottom: 10px; +`; + +export const ContentHeader = styled(Button)``; + +export const BackToList = styled(Link)` + display: flex; + justify-content: center; + align-items: center; +`; + +export const Wrapper = styled.div` + height: 100%; + display: flex; + gap: 1rem; + + @media ${({ theme }) => theme.mediaQuery.tablet} { + padding: 0 10px; + } +`; + +export const UserNameArea = styled.div``; + +export const UserName = styled.h3``; + +export const MainContent = styled.div` + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + background: ${({ theme }) => theme.color.lightgrey}; + border: 1px solid ${({ theme }) => theme.color.grey}; + border-radius: ${({ theme }) => theme.borderRadius.large}; +`; + +export const Content = styled.div` + height: 100%; + display: flex; + gap: 0.5rem; + padding: 24px; +`; + +export const DetailContent = styled.div` + height: 100%; + width: 100%; + overflow-y: scroll; + + &::-webkit-scrollbar { + width: 8px; + position: relative; + left: 0px; + } + &::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.2); + border-radius: 4px; + } + &::-webkit-scrollbar-track { + background: transparent; + } + + border: 2px solid #f0f0f0; + border-radius: 30px; + padding: 2rem; +`; diff --git a/src/components/admin/adminUserDetail/AdminUserDetail.tsx b/src/components/admin/adminUserDetail/AdminUserDetail.tsx new file mode 100644 index 00000000..743aad64 --- /dev/null +++ b/src/components/admin/adminUserDetail/AdminUserDetail.tsx @@ -0,0 +1,102 @@ +import React from 'react'; +import * as S from './AdminUserDetail.styled'; +import { + InformationCircleIcon, + ClipboardDocumentListIcon, + UserGroupIcon, +} from '@heroicons/react/24/outline'; +import { ADMIN_ROUTE } from '../../../constants/routes'; +import { Outlet, useParams } from 'react-router-dom'; +import AdminTitle from '../../common/admin/title/AdminTitle'; +import useGetUserInfo from '../../../hooks/admin/useGetUserInfo'; +import Spinner from '../../user/mypage/Spinner'; +import Sidebar from '../../common/sidebar/Sidebar'; +import ScrollPreventor from '../../common/modal/ScrollPreventor'; + +type TabKey = 'basic' | 'log' | 'inquiry' | 'joined' | 'created' | 'applied'; + +const AdminUserDetail = () => { + const { userId } = useParams(); + const { userData, isLoading, isFetching } = useGetUserInfo(Number(userId)); + + if (isLoading || isFetching) { + return ( + + + + ); + } + + const tabs: { + key: TabKey; + path: string; + label: string; + icon: React.ReactNode; + }[] = [ + { + key: 'basic', + label: '기본 정보', + path: `/admin/users/${userId}/${ADMIN_ROUTE.basic}`, + icon: , + }, + { + key: 'log', + label: '활동 알림', + path: `/admin/users/${userId}/${ADMIN_ROUTE.log}`, + icon: , + }, + { + key: 'joined', + label: '참여 프로젝트', + path: `/admin/users/${userId}/${ADMIN_ROUTE.joinedProject}`, + icon: , + }, + { + key: 'created', + label: '기획 프로젝트', + path: `/admin/users/${userId}/${ADMIN_ROUTE.createdProject}`, + icon: , + }, + { + key: 'applied', + label: '지원한 프로젝트', + path: `/admin/users/${userId}/${ADMIN_ROUTE.appliedProject}`, + icon: , + }, + ]; + + return ( + + + + + + + 목록으로 이동 + + + + + + + + + + + + + + + + ); +}; + +export default AdminUserDetail; diff --git a/src/components/admin/previewComponent/allUserPreview/AllUserPreview.tsx b/src/components/admin/previewComponent/allUserPreview/AllUserPreview.tsx index 2af5e580..dd1deb6c 100644 --- a/src/components/admin/previewComponent/allUserPreview/AllUserPreview.tsx +++ b/src/components/admin/previewComponent/allUserPreview/AllUserPreview.tsx @@ -27,12 +27,16 @@ const AllUserPreview = () => { - + {user.nickname} {user.email} - + 상세 보기 diff --git a/src/components/admin/userCard/UserCard.styled.ts b/src/components/admin/userCard/UserCard.styled.ts index d70929e1..13f247ae 100644 --- a/src/components/admin/userCard/UserCard.styled.ts +++ b/src/components/admin/userCard/UserCard.styled.ts @@ -10,6 +10,33 @@ export const Container = styled.div` padding: 10px; `; +export const Wrapper = styled.div` + position: relative; + display: flex; + justify-content: center; + align-items: center; +`; + +export const BanArea = styled.div` + position: absolute; + top: 0px; + right: 0px; +`; + +export const BanButton = styled.button` + width: 40px; + height: 25px; + border: 1px solid ${({ theme }) => theme.color.lightgrey}; + border-radius: ${({ theme }) => theme.borderRadius.primary}; + background-color: ${({ theme }) => theme.color.red}; + color: ${({ theme }) => theme.color.white}; + font-weight: 600; + + &:hover { + background-color: #ff8789; + } +`; + export const ProfileHeader = styled.div` display: flex; flex-direction: column; diff --git a/src/components/admin/userCard/UserCard.tsx b/src/components/admin/userCard/UserCard.tsx index d51db4c2..430814b2 100644 --- a/src/components/admin/userCard/UserCard.tsx +++ b/src/components/admin/userCard/UserCard.tsx @@ -1,20 +1,35 @@ import React from 'react'; import * as S from './UserCard.styled'; import Avatar from '../../common/avatar/Avatar'; -import { type AllUser } from '../../../models/auth'; +import type { AllUser } from '../../../models/auth'; import { formatDate } from '../../../util/formatDate'; interface UserCardProps { userData: AllUser; + onBan: (userId: number) => void; } -const UserCard = ({ userData }: UserCardProps) => { +const UserCard = ({ userData, onBan }: UserCardProps) => { return ( - - - {userData.nickname} - + + + + {userData.nickname} + + {/* {userData.userState !== '정지' && */} + + { + e.preventDefault(); + e.stopPropagation(); + onBan(userData.id); + }} + > + 퇴출 + + {/* } */} + 이메일 {userData.email} diff --git a/src/components/common/noContent/NoContent.tsx b/src/components/common/noContent/NoContent.tsx index c1245928..1d360c03 100644 --- a/src/components/common/noContent/NoContent.tsx +++ b/src/components/common/noContent/NoContent.tsx @@ -17,8 +17,8 @@ export default function NoContent({ type }: NoContentProps) { applicants: '지원자가', passNonPass: '합/불합격자 리스트가', notification: '알림이', - comment: '내 댓글이', - inquiries: '내 문의글이', + comment: '댓글이', + inquiries: '문의글이', }; return ( diff --git a/src/components/common/sidebar/Sidebar.styled.ts b/src/components/common/sidebar/Sidebar.styled.ts index fe188e68..544831ef 100644 --- a/src/components/common/sidebar/Sidebar.styled.ts +++ b/src/components/common/sidebar/Sidebar.styled.ts @@ -1,13 +1,12 @@ import styled from 'styled-components'; -export const Container = styled.div` +export const Container = styled.div<{ $isAdmin: boolean }>` display: flex; flex-direction: column; border: 2px solid #f0f0f0; border-radius: ${({ theme }) => theme.borderRadius.large}; width: 22%; - min-width: 130px; - height: 80vh; + min-width: ${({ $isAdmin }) => ($isAdmin ? `200px` : `130px`)}; margin-right: 1.25rem; padding-bottom: 1rem; `; @@ -49,16 +48,22 @@ export const MenuList = styled.div` export const MenuItem = styled.div<{ $isActive: boolean; $isHidden?: boolean; + $isAdmin?: boolean; }>` display: ${({ $isHidden }) => ($isHidden ? 'none' : 'flex')}; align-items: center; padding: 0.625rem 1.25rem; margin: 0.5rem 0; - background-color: ${({ $isActive }) => - $isActive ? '#f9f9f9' : 'transparent'}; + background-color: ${({ theme, $isActive, $isAdmin }) => + $isActive + ? $isAdmin + ? theme.color.white + : theme.color.lightgrey + : 'transparent'}; &:hover { - background-color: #f9f9f9; + background-color: ${({ theme, $isAdmin }) => + $isAdmin ? theme.color.white : theme.color.lightgrey}; } svg { diff --git a/src/components/common/sidebar/Sidebar.tsx b/src/components/common/sidebar/Sidebar.tsx index 6a42d0e9..754607a8 100644 --- a/src/components/common/sidebar/Sidebar.tsx +++ b/src/components/common/sidebar/Sidebar.tsx @@ -24,15 +24,20 @@ const Sidebar = ({ menuItems, profileImage, nickname }: SidebarProps) => { const location = useLocation(); const isUserPage = location.pathname.includes('/user'); const isManagePage = location.pathname.includes('/manage'); + const isAdmin = location.pathname.includes('/admin'); const isMyProfile = isLoggedIn && !isUserPage && !isManagePage; const getActiveIndex = useCallback(() => { const currentPath = location.pathname; - return menuItems.findIndex((item) => currentPath === item.path) ?? 0; + return ( + menuItems.findIndex((item) => { + return currentPath === item.path; + }) ?? 0 + ); }, [location.pathname, menuItems]); return ( - + {profileImage === MainLogo ? ( @@ -53,6 +58,7 @@ const Sidebar = ({ menuItems, profileImage, nickname }: SidebarProps) => { {icon && {icon}} {icon && {label}} diff --git a/src/components/user/mypage/ContentTab.tsx b/src/components/user/mypage/ContentTab.tsx index 51d99bf3..2c2329f6 100644 --- a/src/components/user/mypage/ContentTab.tsx +++ b/src/components/user/mypage/ContentTab.tsx @@ -20,6 +20,7 @@ interface ContentProps { export default function ContentTab({ filter, $justifyContent }: ContentProps) { const { pathname } = useLocation(); const [filterId, setFilterId] = useState(); + const isAdmin = pathname.includes('/admin'); function handleChangeId(id: number) { setFilterId(id); @@ -59,7 +60,7 @@ export default function ContentTab({ filter, $justifyContent }: ContentProps) { {pathname.includes('inquiries') ? ( <> - + {!isAdmin && } diff --git a/src/components/user/mypage/activityLog/ActivityLog.tsx b/src/components/user/mypage/activityLog/ActivityLog.tsx index 7a80902e..62bd6087 100644 --- a/src/components/user/mypage/activityLog/ActivityLog.tsx +++ b/src/components/user/mypage/activityLog/ActivityLog.tsx @@ -1,6 +1,18 @@ -import { ACTIVITY_FILTER } from '../../../../constants/user/myPageFilter'; +import { useLocation } from 'react-router-dom'; +import { + ACTIVITY_FILTER, + ACTIVITY_FILTER_ADMIN, +} from '../../../../constants/user/myPageFilter'; import ContentTab from '../ContentTab'; export default function ActivityLog() { - return ; + const { pathname } = useLocation(); + const isAdmin = pathname.includes('/admin'); + + return ( + + ); } diff --git a/src/components/user/mypage/myProfile/profile/Profile.styled.ts b/src/components/user/mypage/myProfile/profile/Profile.styled.ts index 17e46c7d..f76afa42 100644 --- a/src/components/user/mypage/myProfile/profile/Profile.styled.ts +++ b/src/components/user/mypage/myProfile/profile/Profile.styled.ts @@ -132,8 +132,10 @@ export const LabelBox = styled.div` `; export const ChartBox = styled.div` - width: 250px; - height: 250px; + width: 100%; + max-width: 250px; + aspect-ratio: 1 / 1; + margin: 0 auto; `; export const ExplainBox = styled.div` diff --git a/src/components/user/mypage/myProfile/profile/Profile.tsx b/src/components/user/mypage/myProfile/profile/Profile.tsx index dbe1c1f2..bc6ae0d5 100644 --- a/src/components/user/mypage/myProfile/profile/Profile.tsx +++ b/src/components/user/mypage/myProfile/profile/Profile.tsx @@ -4,20 +4,25 @@ import { Link, useLocation, useOutletContext } from 'react-router-dom'; import { Radar } from 'react-chartjs-2'; import { useEffect } from 'react'; import MyProfileWrapper from '../MyProfileWrapper'; -import type { UserInfo } from '../../../../../models/userInfo'; import { PROFILE_DEFAULT_MESSAGE } from '../../../../../constants/user/myPageProfile'; import { ROUTES } from '../../../../../constants/routes'; import 'chart.js/auto'; import { chartOptions } from '../../../../../constants/evaluationChartData'; +import { formatDate } from '../../../../../util/formatDate'; +import { UserInfoAll } from '../../../../../models/userInfo'; export default function Profile() { const { userInfoData, scrollRef, - }: { userInfoData: UserInfo; scrollRef: React.RefObject } = - useOutletContext(); + }: { + userInfoData: UserInfoAll; + scrollRef?: React.RefObject; + } = useOutletContext(); + const location = useLocation(); const myPage = location.pathname.includes('mypage') ? true : false; + const admin = location.pathname.includes('admin') ? true : false; const chartData = { labels: ['책임감', '기획력', '협업능력', '성실도', '문제해결', '기술력'], @@ -31,8 +36,10 @@ export default function Profile() { }; useEffect(() => { - if (scrollRef.current) { - scrollRef.current.scrollTop = 0; + if (scrollRef) { + if (scrollRef.current) { + scrollRef.current.scrollTop = 0; + } } }, [scrollRef]); @@ -49,6 +56,31 @@ export default function Profile() { )} + + {admin && ( + <> + + + + {userInfoData.email} + + + + + + {userInfoData.warning}번 + + + + + + + {formatDate(userInfoData.createdAt)} + + + + + )} diff --git a/src/components/user/userPage/userProjectList/UserProjectList.tsx b/src/components/user/userPage/userProjectList/UserProjectList.tsx index 829b60b6..86220b42 100644 --- a/src/components/user/userPage/userProjectList/UserProjectList.tsx +++ b/src/components/user/userPage/userProjectList/UserProjectList.tsx @@ -1,4 +1,4 @@ -import { Link } from 'react-router-dom'; +import { Link, useLocation } from 'react-router-dom'; import * as S from '../../mypage/joinedProject/MyJoinProjects.styled'; import { ROUTES } from '../../../../constants/routes'; import NoContent from '../../../common/noContent/NoContent'; @@ -8,6 +8,8 @@ import Project from '../../mypage/joinedProject/Project'; import { useGetUserProjectList } from '../../../../hooks/user/useGetUserProjectList'; export default function UserProjects() { + const { pathname } = useLocation(); + const isAdmin = pathname.includes('/admin'); const { userProjectData, isLoading, title } = useGetUserProjectList(); if (isLoading) { @@ -26,6 +28,8 @@ export default function UserProjects() { diff --git a/src/constants/admin/mainItems.ts b/src/constants/admin/mainItems.ts index 74c17c8d..85a40fa3 100644 --- a/src/constants/admin/mainItems.ts +++ b/src/constants/admin/mainItems.ts @@ -15,8 +15,8 @@ export interface CardItem { export const cardList: CardItem[] = [ { key: 'allUsers', - title: '전체 회원 조회', - link: `${ADMIN_ROUTE.allUser}`, + title: '회원 조회', + link: `${ADMIN_ROUTE.users}`, Component: AllUserPreview, }, { diff --git a/src/constants/routes.ts b/src/constants/routes.ts index 3f1cc3c1..18c66d4d 100644 --- a/src/constants/routes.ts +++ b/src/constants/routes.ts @@ -51,4 +51,7 @@ export const ADMIN_ROUTE = { joinedProject: 'joined-project', createdProject: 'created-project', appliedProject: 'apply-project', + comments: 'comments', + checkingApplicant: 'checked-applicants', + applyingProject: 'applied-projects', }; diff --git a/src/constants/user/myPageFilter.ts b/src/constants/user/myPageFilter.ts index eeab4fb6..be89a4ba 100644 --- a/src/constants/user/myPageFilter.ts +++ b/src/constants/user/myPageFilter.ts @@ -26,3 +26,8 @@ export const ACTIVITY_FILTER = [ { title: '내 댓글', url: ROUTES.comments, id: 0 }, { title: '내 문의글', url: ROUTES.activityInquiries, id: 1 }, ] as const; + +export const ACTIVITY_FILTER_ADMIN = [ + { title: '댓글', url: ROUTES.comments, id: 0 }, + { title: '문의글', url: ROUTES.activityInquiries, id: 1 }, +] as const; diff --git a/src/hooks/admin/useGetUserInfo.ts b/src/hooks/admin/useGetUserInfo.ts new file mode 100644 index 00000000..b109461f --- /dev/null +++ b/src/hooks/admin/useGetUserInfo.ts @@ -0,0 +1,17 @@ +import { useQuery } from '@tanstack/react-query'; +import { ApiUserInfo } from '../../models/userInfo'; +import { getUserInfo } from '../../api/userpage.api'; +import { userInfoKey } from '../queries/keys'; + +const useGetUserInfo = (id: number) => { + const { data, isLoading, isFetching } = useQuery({ + queryKey: [userInfoKey.userProfile, id], + queryFn: () => getUserInfo(id), + staleTime: 1 * 60 * 1000, + enabled: !!id, + }); + + return { userData: data?.data, isLoading, isFetching }; +}; + +export default useGetUserInfo; diff --git a/src/models/auth.ts b/src/models/auth.ts index aa4e95d6..dc22a4b7 100644 --- a/src/models/auth.ts +++ b/src/models/auth.ts @@ -62,7 +62,13 @@ export interface AllUser extends AllUserPreview { position: PositionTag[]; } +export interface AllUserInfo extends AllUser { + email: string; + warning: number; + createdAt: string; +} + export interface AllUserList { users: AllUser[]; - totalPages: number; + totalPage: number; } diff --git a/src/models/userInfo.ts b/src/models/userInfo.ts index 8567722a..9a0f0f05 100644 --- a/src/models/userInfo.ts +++ b/src/models/userInfo.ts @@ -16,6 +16,7 @@ export interface UserInfo { profileImg?: string; beginner: boolean; github?: string; + warning: number; career?: Career[]; positions: Omit[]; skills: Omit[]; @@ -23,6 +24,12 @@ export interface UserInfo { averageScores: number[]; } +export interface UserInfoAll extends UserInfo { + email: string; + warning: number; + createdAt: string; +} + export interface ApiUserInfo extends ApiCommonType { data: UserInfo | null; } diff --git a/src/pages/admin/adminUser/AdminUser.styled.ts b/src/pages/admin/adminUser/AdminUser.styled.ts index 74b4443f..808e2ffc 100644 --- a/src/pages/admin/adminUser/AdminUser.styled.ts +++ b/src/pages/admin/adminUser/AdminUser.styled.ts @@ -1,9 +1,12 @@ import styled from 'styled-components'; +import { SpinnerContainer } from '../../../components/user/mypage/Spinner.styled'; export const Container = styled.div``; +export const Spinner = styled(SpinnerContainer)``; + export const SearchBar = styled.div` - margin-top: 20px; + margin-top: 120px; `; export const ScrollArea = styled.div` diff --git a/src/pages/admin/adminUser/AdminUser.tsx b/src/pages/admin/adminUser/AdminUser.tsx index cac91bb4..a1243f5d 100644 --- a/src/pages/admin/adminUser/AdminUser.tsx +++ b/src/pages/admin/adminUser/AdminUser.tsx @@ -1,7 +1,6 @@ import * as S from './AdminUser.styled'; import AdminTitle from '../../../components/common/admin/title/AdminTitle'; import { useGetAllUsers } from '../../../hooks/admin/useGetAllUsers'; -import LoadingSpinner from '../../../components/common/loadingSpinner/LoadingSpinner'; import UserCard from '../../../components/admin/userCard/UserCard'; import ScrollPreventor from '../../../components/common/modal/ScrollPreventor'; import SearchBar from '../../../components/common/admin/searchBar/SearchBar'; @@ -10,6 +9,7 @@ import useSearchBar from '../../../hooks/admin/useSearchBar'; import { ADMIN_MODAL_MESSAGE } from '../../../constants/admin/adminModal'; import { Link } from 'react-router-dom'; import { ADMIN_ROUTE } from '../../../constants/routes'; +import Spinner from '../../../components/user/mypage/Spinner'; const AdminUser = () => { const { searchUnit, value, handleGetKeyword, handleChangePagination } = @@ -17,13 +17,21 @@ const AdminUser = () => { const { allUserData, isLoading, isFetching } = useGetAllUsers(searchUnit); if (isLoading || isFetching) { - return ; + return ( + + + + ); } if (!allUserData || allUserData.users.length === 0) { return {ADMIN_MODAL_MESSAGE.NO_RESULT}; } + const onBan = (userId: number) => { + // TODO : 버튼을 누르면 해당 유저 강퇴 조치 API 전송. + }; + return ( <> @@ -32,7 +40,7 @@ const AdminUser = () => { @@ -43,13 +51,12 @@ const AdminUser = () => { - + ))} diff --git a/src/routes/AdminRoutes.tsx b/src/routes/AdminRoutes.tsx index 675ca8bd..a961e4fa 100644 --- a/src/routes/AdminRoutes.tsx +++ b/src/routes/AdminRoutes.tsx @@ -3,6 +3,7 @@ import { lazy, Suspense } from 'react'; import { ADMIN_ROUTE } from '../constants/routes'; import ProtectAdminRoute from './ProtectAdminRoute'; import { Spinner } from '../components/common/loadingSpinner/LoadingSpinner.styled'; +import { Navigate } from 'react-router-dom'; const Sidebar = lazy( () => import('../components/common/admin/sidebar/AdminSidebar') @@ -19,6 +20,21 @@ const NoticeWrite = lazy( const NoticeDetail = lazy( () => import('../pages/admin/adminNoticeDetail/AdminNoticeDetail') ); +const AdminUserDetail = lazy( + () => import('../components/admin/adminUserDetail/AdminUserDetail') +); +const Profile = lazy( + () => import('../components/user/mypage/myProfile/profile/Profile') +); +const ActivityLog = lazy( + () => import('../components/user/mypage/activityLog/ActivityLog') +); +const Notifications = lazy( + () => import('../components/user/mypage/notifications/Notifications') +); +const UserProjects = lazy( + () => import('../components/user/userPage/userProjectList/UserProjectList') +); const FAQ = lazy(() => import('../pages/admin/adminFAQ/AdminFAQ')); const FAQList = lazy( () => import('../pages/admin/adminFAQ/adminFAQList/AdminFAQListPage') @@ -66,6 +82,25 @@ const InquiryAnswerWrite = lazy( ) ); const Manage = lazy(() => import('../pages/admin/adminManage/AdminManage')); +const ActivityLogComments = lazy( + () => + import( + '../components/user/mypage/activityLog/commentsActivity/CommentsActivity' + ) +); +const ActivityLogInquiries = lazy( + () => import('../components/user/mypage/activityLog/inquiries/Inquiries') +); + +const NotificationsAppliedProjects = lazy( + () => + import( + '../components/user/mypage/notifications/appliedProjects/AppliedProjects' + ) +); +const NotificationsAll = lazy( + () => import('../components/user/mypage/notifications/all/All') +); export const AdminRoutes = () => { const routeList = [ @@ -132,6 +167,68 @@ export const AdminRoutes = () => { path: ADMIN_ROUTE.users, element: , }, + { + path: `${ADMIN_ROUTE.users}/:userId`, + element: , + children: [ + { + index: true, + element: , + }, + { + path: `${ADMIN_ROUTE.basic}`, + element: , + }, + { + path: `${ADMIN_ROUTE.log}`, + element: , + children: [ + { + index: true, + element: , + }, + { + path: `${ADMIN_ROUTE.comments}`, + element: , + }, + { + path: `${ADMIN_ROUTE.inquiries}`, + element: , + }, + ], + }, + { + path: `${ADMIN_ROUTE.appliedProject}`, + element: , + children: [ + { + index: true, + element: , + }, + { + path: `${ADMIN_ROUTE.checkingApplicant}`, + element: , + }, + { + path: `${ADMIN_ROUTE.comments}`, + element: , + }, + { + path: `${ADMIN_ROUTE.applyingProject}`, + element: , + }, + ], + }, + { + path: `${ADMIN_ROUTE.joinedProject}`, + element: , + }, + { + path: `${ADMIN_ROUTE.createdProject}`, + element: , + }, + ], + }, { path: ADMIN_ROUTE.reports, element: ,