diff --git a/apps/member/src/pages/ApplicationPage/ApplicationPage.tsx b/apps/member/src/pages/ApplicationPage/ApplicationPage.tsx
deleted file mode 100644
index 44d5716d..00000000
--- a/apps/member/src/pages/ApplicationPage/ApplicationPage.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import { Suspense } from 'react';
-
-import ApplicationListSection from '@components/application/ApplicationListSection/ApplicationListSection';
-import Content from '@components/common/Content/Content';
-import Header from '@components/common/Header/Header';
-
-import { ROLE_LEVEL } from '@constants/state';
-import { useMyProfile } from '@hooks/queries';
-import { useRecruitment } from '@hooks/queries/recruitment/useRecruitment';
-import { formattedDate } from '@utils/date';
-
-const ApplicationPage = () => {
- const { data } = useMyProfile();
- const { data: recruitmentList } = useRecruitment();
-
- const optionList = recruitmentList.map((item) => ({
- id: item.id,
- value: item.id,
- name: `${item.applicationType} - ${formattedDate(item.startDate)} ~ ${formattedDate(item.endDate)}`,
- }));
-
- if (data.roleLevel! < ROLE_LEVEL.ADMIN) {
- throw new Error('접근 권한이 없습니다.');
- }
-
- return (
-
-
-
-
-
-
- );
-};
-
-export default ApplicationPage;
diff --git a/apps/member/src/components/application/ApplicationListSection/ApplicationListSection.tsx b/apps/member/src/pages/ApplicationPage/components/ApplicationListSection.tsx
similarity index 71%
rename from apps/member/src/components/application/ApplicationListSection/ApplicationListSection.tsx
rename to apps/member/src/pages/ApplicationPage/components/ApplicationListSection.tsx
index 2a62a5b8..0eb0edab 100644
--- a/apps/member/src/components/application/ApplicationListSection/ApplicationListSection.tsx
+++ b/apps/member/src/pages/ApplicationPage/components/ApplicationListSection.tsx
@@ -1,5 +1,4 @@
-import { useEffect, useState } from 'react';
-import { useNavigate } from 'react-router-dom';
+import { useMemo, useState } from 'react';
import { Badge, Button, Table } from '@clab-platforms/design-system';
@@ -8,53 +7,50 @@ import { Section } from '@components/common/Section';
import Select from '@components/common/Select/Select';
import { TABLE_HEAD } from '@constants/head';
-import { useModal } from '@hooks/common/useModal';
import { usePagination } from '@hooks/common/usePagination';
+import { formattedDate } from '@utils/date';
+import { toKoreanApplicationType } from '@utils/string';
+
import {
useApplicationAllMemberMutation,
useApplicationConditions,
+ useApplicationInoModal,
useApplicationMemberMutation,
useApplicationNonePassMutation,
useApplicationPassMutation,
-} from '@hooks/queries/application';
-
-import type { ApplicationMemberType } from '@type/application';
-
-import { ApplicationInfoModal } from './ApplicationInfoModal';
-
-interface RecruitmentItem {
- id: number;
- value: number;
- name: string;
-}
+ useRecruitment,
+} from '../hooks';
-interface ApplicationListSectionProps {
- recruitmentList: RecruitmentItem[];
-}
+export function ApplicationListSection() {
+ const { open } = useApplicationInoModal();
+ const { data: recruitmentList } = useRecruitment();
-const ApplicationListSection = ({
- recruitmentList,
-}: ApplicationListSectionProps) => {
- const navigate = useNavigate();
- const { open } = useModal();
const [selectRecruitment, setSelectRecruitment] = useState(
- recruitmentList.length, // 가장 최신의 모집공고
+ recruitmentList.length,
);
const { page, size, handlePageChange } = usePagination();
- const { data } = useApplicationConditions({
+
+ const { mutate: applicationMemberMutate } = useApplicationMemberMutation();
+ const { mutate: applicationAllMemberMutate } =
+ useApplicationAllMemberMutation();
+ const { mutate: applicationNonePassMutate } =
+ useApplicationNonePassMutation();
+ const { mutate: applicationPassMutate } = useApplicationPassMutation();
+ const { data: applicationConditions } = useApplicationConditions({
recruitmentId: selectRecruitment,
page,
size,
});
- const { applicationMemberMutate } = useApplicationMemberMutation();
- const { applicationAllMemberMutate } = useApplicationAllMemberMutation();
- const { applicationNonePassMutate } = useApplicationNonePassMutation();
- const { applicationPassMutate } = useApplicationPassMutation();
- useEffect(() => {
- navigate('');
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [selectRecruitment]);
+ const options = useMemo(
+ () =>
+ recruitmentList.map(({ id, applicationType, startDate, endDate }) => ({
+ id: id,
+ value: id,
+ name: `${id}. ${toKoreanApplicationType(applicationType)} / ${formattedDate(startDate)} ~ ${formattedDate(endDate)}`,
+ })),
+ [recruitmentList],
+ );
const handleRecruitmentChange = (e: React.ChangeEvent) => {
setSelectRecruitment(+e.target.value);
@@ -79,13 +75,6 @@ const ApplicationListSection = ({
applicationAllMemberMutate(selectRecruitment);
};
- const handleViewButtonClick = (info: ApplicationMemberType) => {
- return open({
- title: '지원서',
- content: ,
- });
- };
-
return (
- {data.items.map((application, index) => (
+ {applicationConditions.items.map((application, index) => (
{index + 1 + page * 20}
{application.name}
{application.studentId}
-
@@ -172,7 +158,7 @@ const ApplicationListSection = ({
);
-};
-
-export default ApplicationListSection;
+}
diff --git a/apps/member/src/hooks/queries/application/index.ts b/apps/member/src/pages/ApplicationPage/hooks/index.ts
similarity index 75%
rename from apps/member/src/hooks/queries/application/index.ts
rename to apps/member/src/pages/ApplicationPage/hooks/index.ts
index 7f8cc9f3..b9eb2df8 100644
--- a/apps/member/src/hooks/queries/application/index.ts
+++ b/apps/member/src/pages/ApplicationPage/hooks/index.ts
@@ -1,5 +1,7 @@
export * from './useApplicationAllMemberMutation';
export * from './useApplicationConditions';
+export * from './useApplicationInoModal';
export * from './useApplicationMemberMutation';
export * from './useApplicationNonePassMutation';
export * from './useApplicationPassMutation';
+export * from './useRecruitment';
diff --git a/apps/member/src/hooks/queries/application/useApplicationAllMemberMutation.ts b/apps/member/src/pages/ApplicationPage/hooks/useApplicationAllMemberMutation.ts
similarity index 86%
rename from apps/member/src/hooks/queries/application/useApplicationAllMemberMutation.ts
rename to apps/member/src/pages/ApplicationPage/hooks/useApplicationAllMemberMutation.ts
index dcf518d9..2e18f271 100644
--- a/apps/member/src/hooks/queries/application/useApplicationAllMemberMutation.ts
+++ b/apps/member/src/pages/ApplicationPage/hooks/useApplicationAllMemberMutation.ts
@@ -9,7 +9,7 @@ import useToast from '@hooks/common/useToast';
export function useApplicationAllMemberMutation() {
const toast = useToast();
- const mutation = useMutation({
+ return useMutation({
mutationFn: postApplicationAllMember,
onSuccess: () => {
toast({
@@ -19,6 +19,4 @@ export function useApplicationAllMemberMutation() {
});
},
});
-
- return { applicationAllMemberMutate: mutation.mutate };
}
diff --git a/apps/member/src/hooks/queries/application/useApplicationConditions.ts b/apps/member/src/pages/ApplicationPage/hooks/useApplicationConditions.tsx
similarity index 75%
rename from apps/member/src/hooks/queries/application/useApplicationConditions.ts
rename to apps/member/src/pages/ApplicationPage/hooks/useApplicationConditions.tsx
index 78223628..05f3d9f5 100644
--- a/apps/member/src/hooks/queries/application/useApplicationConditions.ts
+++ b/apps/member/src/pages/ApplicationPage/hooks/useApplicationConditions.tsx
@@ -3,9 +3,9 @@ import { useSuspenseQuery } from '@tanstack/react-query';
import { getApplicationConditions } from '@api/application';
import { APPLICATION_QUERY_KEY } from '@constants/key';
-import { WithPaginationParams } from '@type/api';
+import type { WithPaginationParams } from '@type/api';
-interface useApplicationConditionsParams extends WithPaginationParams {
+export interface UseApplicationConditionsOptions extends WithPaginationParams {
recruitmentId: number;
}
@@ -16,12 +16,12 @@ export function useApplicationConditions({
recruitmentId,
page = 0,
size = 6,
-}: useApplicationConditionsParams) {
+}: UseApplicationConditionsOptions) {
return useSuspenseQuery({
+ queryFn: () => getApplicationConditions({ recruitmentId, page, size }),
queryKey: APPLICATION_QUERY_KEY.RECRUITMENT_PAGE(recruitmentId, {
page,
size,
}),
- queryFn: () => getApplicationConditions({ recruitmentId, page, size }),
});
}
diff --git a/apps/member/src/components/application/ApplicationListSection/ApplicationInfoModal.tsx b/apps/member/src/pages/ApplicationPage/hooks/useApplicationInoModal.tsx
similarity index 64%
rename from apps/member/src/components/application/ApplicationListSection/ApplicationInfoModal.tsx
rename to apps/member/src/pages/ApplicationPage/hooks/useApplicationInoModal.tsx
index 1b69b2b4..f8053856 100644
--- a/apps/member/src/components/application/ApplicationListSection/ApplicationInfoModal.tsx
+++ b/apps/member/src/pages/ApplicationPage/hooks/useApplicationInoModal.tsx
@@ -1,14 +1,33 @@
+import { useMemo } from 'react';
+
import { DetailsList } from '@clab-platforms/design-system';
+import { useModal } from '@hooks/common/useModal';
+
import { ApplicationMemberType } from '@type/application';
-interface ApplicationInfoModalProps {
- applicationInfo: ApplicationMemberType;
+interface Options {
+ data: ApplicationMemberType;
+}
+
+export function useApplicationInoModal() {
+ const { open } = useModal();
+
+ return useMemo(
+ () => ({
+ open: (options: Options) =>
+ open({
+ title: '지원서',
+ content: ,
+ }),
+ }),
+ [open],
+ );
}
-export const ApplicationInfoModal = ({
- applicationInfo,
-}: ApplicationInfoModalProps) => {
+interface Props extends Options {}
+
+function ApplicationInfoModal({ data }: Props) {
const {
studentId,
name,
@@ -21,7 +40,7 @@ export const ApplicationInfoModal = ({
interests,
otherActivities,
githubUrl,
- } = applicationInfo;
+ } = data;
return (
@@ -34,8 +53,8 @@ export const ApplicationInfoModal = ({
{birth}
{address}
{interests}
- {githubUrl || '-'}
+ {githubUrl ?? '-'}
{otherActivities}
);
-};
+}
diff --git a/apps/member/src/hooks/queries/application/useApplicationMemberMutation.ts b/apps/member/src/pages/ApplicationPage/hooks/useApplicationMemberMutation.ts
similarity index 88%
rename from apps/member/src/hooks/queries/application/useApplicationMemberMutation.ts
rename to apps/member/src/pages/ApplicationPage/hooks/useApplicationMemberMutation.ts
index bb6534d9..26c11882 100644
--- a/apps/member/src/hooks/queries/application/useApplicationMemberMutation.ts
+++ b/apps/member/src/pages/ApplicationPage/hooks/useApplicationMemberMutation.ts
@@ -9,7 +9,7 @@ import useToast from '@hooks/common/useToast';
export function useApplicationMemberMutation() {
const toast = useToast();
- const mutation = useMutation({
+ return useMutation({
mutationFn: postApplicationMember,
onSuccess: (data) => {
if (data === null) {
@@ -24,6 +24,4 @@ export function useApplicationMemberMutation() {
});
},
});
-
- return { applicationMemberMutate: mutation.mutate };
}
diff --git a/apps/member/src/hooks/queries/application/useApplicationNonePassMutation.ts b/apps/member/src/pages/ApplicationPage/hooks/useApplicationNonePassMutation.ts
similarity index 88%
rename from apps/member/src/hooks/queries/application/useApplicationNonePassMutation.ts
rename to apps/member/src/pages/ApplicationPage/hooks/useApplicationNonePassMutation.ts
index 29056a5f..76466968 100644
--- a/apps/member/src/hooks/queries/application/useApplicationNonePassMutation.ts
+++ b/apps/member/src/pages/ApplicationPage/hooks/useApplicationNonePassMutation.ts
@@ -11,7 +11,7 @@ export function useApplicationNonePassMutation() {
const queryClient = useQueryClient();
const toast = useToast();
- const mutation = useMutation({
+ return useMutation({
mutationFn: patchApplicationNonePass,
onSuccess: () => {
queryClient.invalidateQueries({
@@ -23,6 +23,4 @@ export function useApplicationNonePassMutation() {
});
},
});
-
- return { applicationNonePassMutate: mutation.mutate };
}
diff --git a/apps/member/src/hooks/queries/application/useApplicationPassMutation.ts b/apps/member/src/pages/ApplicationPage/hooks/useApplicationPassMutation.ts
similarity index 88%
rename from apps/member/src/hooks/queries/application/useApplicationPassMutation.ts
rename to apps/member/src/pages/ApplicationPage/hooks/useApplicationPassMutation.ts
index ee969e7d..4be7dc57 100644
--- a/apps/member/src/hooks/queries/application/useApplicationPassMutation.ts
+++ b/apps/member/src/pages/ApplicationPage/hooks/useApplicationPassMutation.ts
@@ -11,7 +11,7 @@ export function useApplicationPassMutation() {
const queryClient = useQueryClient();
const toast = useToast();
- const mutation = useMutation({
+ return useMutation({
mutationFn: patchApplicationPass,
onSuccess: () => {
queryClient.invalidateQueries({
@@ -23,6 +23,4 @@ export function useApplicationPassMutation() {
});
},
});
-
- return { applicationPassMutate: mutation.mutate };
}
diff --git a/apps/member/src/hooks/queries/recruitment/useRecruitment.ts b/apps/member/src/pages/ApplicationPage/hooks/useRecruitment.ts
similarity index 100%
rename from apps/member/src/hooks/queries/recruitment/useRecruitment.ts
rename to apps/member/src/pages/ApplicationPage/hooks/useRecruitment.ts
diff --git a/apps/member/src/pages/ApplicationPage/index.tsx b/apps/member/src/pages/ApplicationPage/index.tsx
new file mode 100644
index 00000000..4f9d3f2f
--- /dev/null
+++ b/apps/member/src/pages/ApplicationPage/index.tsx
@@ -0,0 +1,40 @@
+import { Suspense } from 'react';
+
+import { QueryErrorResetBoundary } from '@tanstack/react-query';
+
+import Content from '@components/common/Content/Content';
+import ErrorSection from '@components/common/ErrorSection/ErrorSection';
+import Header from '@components/common/Header/Header';
+
+import { ROLE_LEVEL } from '@constants/state';
+import { useMyProfile } from '@hooks/queries';
+import { ErrorBoundary } from '@suspensive/react';
+
+import { ApplicationListSection } from './components/ApplicationListSection';
+
+export default function ApplicationPage() {
+ const { data } = useMyProfile();
+
+ if (data.roleLevel < ROLE_LEVEL.ADMIN) {
+ throw new Error('접근 권한이 없습니다.');
+ }
+
+ return (
+
+ {({ reset }) => (
+ }
+ >
+
+
+
+
+
+
+
+
+ )}
+
+ );
+}
diff --git a/apps/member/src/pages/Routes.tsx b/apps/member/src/pages/Routes.tsx
index 23025692..67e0b04e 100644
--- a/apps/member/src/pages/Routes.tsx
+++ b/apps/member/src/pages/Routes.tsx
@@ -7,6 +7,7 @@ import ProtectAuth from '@components/router/ProtectAuth';
import { PATH } from '@constants/path';
import MainPage from '@pages/MainPage';
+import ApplicationPage from './ApplicationPage';
import { GlobalErrorPage } from './GlobalErrorPage';
import { PageLayout } from './PageLayout';
@@ -45,9 +46,6 @@ const LoginPage = lazy(() => import('@pages/LoginPage'));
const AuthPage = lazy(() => import('@pages/AuthPage/AuthPage'));
const BlogPage = lazy(() => import('@pages/BlogPage/BlogPage'));
const ManagePage = lazy(() => import('@pages/ManagePage/ManagePage'));
-const ApplicationPage = lazy(
- () => import('@pages/ApplicationPage/ApplicationPage'),
-);
const router = createBrowserRouter([
{
diff --git a/apps/member/src/utils/string.ts b/apps/member/src/utils/string.ts
index 7bb4cc0f..90f95a2c 100644
--- a/apps/member/src/utils/string.ts
+++ b/apps/member/src/utils/string.ts
@@ -7,9 +7,10 @@ import {
ActivityMemberRoleType,
MemberStatusType,
} from '@type/activity';
+import type { ApplicationType } from '@type/application';
import type { Bookstore, BookstoreKorean } from '@type/book';
import type { CareerLevel, EmploymentType } from '@type/community';
-import { RoleLevelKey, RoleLevelType } from '@type/member';
+import type { RoleLevelKey, RoleLevelType } from '@type/member';
import type { MembershipStatusType } from '@type/membershipFee';
import type { SchedulePriority } from '@type/schedule';
@@ -158,6 +159,19 @@ export function toKoreaMemberLevel(
}
}
+export function toKoreanApplicationType(type: ApplicationType) {
+ switch (type) {
+ case 'NORMAL':
+ return '회원';
+ case 'OPERATION':
+ return '운영진';
+ case 'CORE_TEAM':
+ return '코어팀';
+ default:
+ return '알수없음';
+ }
+}
+
export const createQueryParams = (name: string, page: number | string) => {
return `?${name}=${page}`;
};