Skip to content

Commit

Permalink
refactor(member): Application 새로운 프로젝트 구조 적용 (#238)
Browse files Browse the repository at this point in the history
  • Loading branch information
gwansikk committed Sep 20, 2024
1 parent d893353 commit fa44587
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 113 deletions.
36 changes: 0 additions & 36 deletions apps/member/src/pages/ApplicationPage/ApplicationPage.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -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<HTMLSelectElement>) => {
setSelectRecruitment(+e.target.value);
Expand All @@ -79,13 +75,6 @@ const ApplicationListSection = ({
applicationAllMemberMutate(selectRecruitment);
};

const handleViewButtonClick = (info: ApplicationMemberType) => {
return open({
title: '지원서',
content: <ApplicationInfoModal applicationInfo={info} />,
});
};

return (
<Section>
<Section.Header
Expand All @@ -95,7 +84,7 @@ const ApplicationListSection = ({
<Section.Body className="space-y-4">
<div className="flex gap-8">
<Select
options={recruitmentList}
options={options}
label="모집 공고"
onChange={handleRecruitmentChange}
className="h-fit w-full"
Expand All @@ -109,16 +98,13 @@ const ApplicationListSection = ({
</Button>
</div>
<Table head={TABLE_HEAD.APPLY_TABLE}>
{data.items.map((application, index) => (
{applicationConditions.items.map((application, index) => (
<Table.Row key={application.studentId}>
<Table.Cell>{index + 1 + page * 20}</Table.Cell>
<Table.Cell>{application.name}</Table.Cell>
<Table.Cell>{application.studentId}</Table.Cell>
<Table.Cell>
<Button
size="sm"
onClick={() => handleViewButtonClick(application)}
>
<Button size="sm" onClick={() => open({ data: application })}>
보기
</Button>
</Table.Cell>
Expand Down Expand Up @@ -172,14 +158,12 @@ const ApplicationListSection = ({
</Table>
<Pagination
className="mt-4 justify-center"
totalItems={data.totalItems}
totalItems={applicationConditions.totalItems}
postLimit={size}
onChange={handlePageChange}
page={page}
/>
</Section.Body>
</Section>
);
};

export default ApplicationListSection;
}
Original file line number Diff line number Diff line change
@@ -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';
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand All @@ -19,6 +19,4 @@ export function useApplicationAllMemberMutation() {
});
},
});

return { applicationAllMemberMutate: mutation.mutate };
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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 }),
});
}
Original file line number Diff line number Diff line change
@@ -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: <ApplicationInfoModal {...options} />,
}),
}),
[open],
);
}

export const ApplicationInfoModal = ({
applicationInfo,
}: ApplicationInfoModalProps) => {
interface Props extends Options {}

function ApplicationInfoModal({ data }: Props) {

Check warning on line 30 in apps/member/src/pages/ApplicationPage/hooks/useApplicationInoModal.tsx

View workflow job for this annotation

GitHub Actions / quality-and-build (lint)

Fast refresh only works when a file only exports components. Move your component(s) to a separate file
const {
studentId,
name,
Expand All @@ -21,7 +40,7 @@ export const ApplicationInfoModal = ({
interests,
otherActivities,
githubUrl,
} = applicationInfo;
} = data;

return (
<DetailsList className="max-h-[540px] overflow-auto">
Expand All @@ -34,8 +53,8 @@ export const ApplicationInfoModal = ({
<DetailsList.Item label="생년월일">{birth}</DetailsList.Item>
<DetailsList.Item label="거주지">{address}</DetailsList.Item>
<DetailsList.Item label="희망분야">{interests}</DetailsList.Item>
<DetailsList.Item label="Github">{githubUrl || '-'}</DetailsList.Item>
<DetailsList.Item label="Github">{githubUrl ?? '-'}</DetailsList.Item>
<p className="mt-8">{otherActivities}</p>
</DetailsList>
);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -24,6 +24,4 @@ export function useApplicationMemberMutation() {
});
},
});

return { applicationMemberMutate: mutation.mutate };
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export function useApplicationNonePassMutation() {
const queryClient = useQueryClient();
const toast = useToast();

const mutation = useMutation({
return useMutation({
mutationFn: patchApplicationNonePass,
onSuccess: () => {
queryClient.invalidateQueries({
Expand All @@ -23,6 +23,4 @@ export function useApplicationNonePassMutation() {
});
},
});

return { applicationNonePassMutate: mutation.mutate };
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export function useApplicationPassMutation() {
const queryClient = useQueryClient();
const toast = useToast();

const mutation = useMutation({
return useMutation({
mutationFn: patchApplicationPass,
onSuccess: () => {
queryClient.invalidateQueries({
Expand All @@ -23,6 +23,4 @@ export function useApplicationPassMutation() {
});
},
});

return { applicationPassMutate: mutation.mutate };
}
40 changes: 40 additions & 0 deletions apps/member/src/pages/ApplicationPage/index.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallback={({ reset }) => <ErrorSection reset={reset} />}
>
<Content>
<Header title="지원" />

<Suspense>
<ApplicationListSection />
</Suspense>
</Content>
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
);
}
Loading

0 comments on commit fa44587

Please sign in to comment.