From 159a675b360c840d496fb4707d942827dc412592 Mon Sep 17 00:00:00 2001 From: lepitaaar Date: Thu, 14 Aug 2025 00:49:57 +0900 Subject: [PATCH 1/5] =?UTF-8?q?fix:=20ApplicationStatus=20=EB=A7=A4?= =?UTF-8?q?=ED=95=91=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DRAFT는 작성중으로 사용중인 지원상태가 아님 --- frontend/src/utils/mapStatusToGroup.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/src/utils/mapStatusToGroup.ts b/frontend/src/utils/mapStatusToGroup.ts index a86752003..349bd09df 100644 --- a/frontend/src/utils/mapStatusToGroup.ts +++ b/frontend/src/utils/mapStatusToGroup.ts @@ -2,10 +2,9 @@ import { ApplicationStatus } from "@/types/applicants"; const mapStatusToGroup = (status: ApplicationStatus): { status: ApplicationStatus, label: string } => { switch (status) { - case ApplicationStatus.DRAFT: case ApplicationStatus.SUBMITTED: case ApplicationStatus.SCREENING: - return { status: ApplicationStatus.DRAFT, label: '서류검토' }; + return { status: ApplicationStatus.SUBMITTED, label: '서류검토' }; case ApplicationStatus.SCREENING_PASSED: case ApplicationStatus.INTERVIEW_SCHEDULED: case ApplicationStatus.INTERVIEW_IN_PROGRESS: @@ -15,7 +14,7 @@ const mapStatusToGroup = (status: ApplicationStatus): { status: ApplicationStatu case ApplicationStatus.ACCEPTED: return { status: ApplicationStatus.ACCEPTED, label: '합격' }; default: - return { status: ApplicationStatus.DRAFT, label: '서류검토'}; + return { status: ApplicationStatus.SUBMITTED, label: '서류검토'}; } } From b2b6fae1af0aa13c892279caa154d40d5d43c806 Mon Sep 17 00:00:00 2001 From: lepitaaar Date: Thu, 14 Aug 2025 01:43:18 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=EC=97=90=EC=85=8B=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/assets/images/icons/back_arrow_icon.svg | 1 + frontend/src/assets/images/icons/forward_arrow_icon.svg | 1 + 2 files changed, 2 insertions(+) create mode 100644 frontend/src/assets/images/icons/back_arrow_icon.svg create mode 100644 frontend/src/assets/images/icons/forward_arrow_icon.svg diff --git a/frontend/src/assets/images/icons/back_arrow_icon.svg b/frontend/src/assets/images/icons/back_arrow_icon.svg new file mode 100644 index 000000000..0a00b873e --- /dev/null +++ b/frontend/src/assets/images/icons/back_arrow_icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/assets/images/icons/forward_arrow_icon.svg b/frontend/src/assets/images/icons/forward_arrow_icon.svg new file mode 100644 index 000000000..96483cd33 --- /dev/null +++ b/frontend/src/assets/images/icons/forward_arrow_icon.svg @@ -0,0 +1 @@ + \ No newline at end of file From 7757b9a21b811f99060eb54e853a3c6f43d32e4e Mon Sep 17 00:00:00 2001 From: lepitaaar Date: Thu, 14 Aug 2025 01:43:40 +0900 Subject: [PATCH 3/5] =?UTF-8?q?fix:=20=ED=83=9C=EA=B7=B8=20=EB=B9=A0?= =?UTF-8?q?=EC=A7=90=20=EC=9D=B4=EC=8A=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tabs/ApplicantsTab/ApplicantsTab.tsx | 88 ++++++++++--------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantsTab.tsx b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantsTab.tsx index 2d4a0ca4b..a873bbaab 100644 --- a/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantsTab.tsx +++ b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantsTab.tsx @@ -102,50 +102,52 @@ const ApplicantsTab = () => { - {filteredApplicants.map((item: Applicant, index: number) => ( - navigate(`/admin/applicants/${item.id}`)} - > - - ) => - e.stopPropagation() + + {filteredApplicants.map((item: Applicant, index: number) => ( + navigate(`/admin/applicants/${item.id}`)} + > + + ) => + e.stopPropagation() + } + /> + + + {mapStatusToGroup(item.status).label} + + + {item.answers[0].value} + + + { + item.memo && item.memo.length > 0 ? ( + item.memo + ) : ( + 메모를 입력하지 않았습니다. + ) } - /> - - - {mapStatusToGroup(item.status).label} - - - {item.answers[0].value} - - - { - item.memo && item.memo.length > 0 ? ( - item.memo - ) : ( - 메모를 입력하지 않았습니다. - ) - } - - - { - // createdAt을 yyyy-mm-dd 형식으로 변환 - // 임시로.. 나중에 변경해야함 - (() => { - const date = new Date(item.createdAt); - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, '0'); - const day = String(date.getDate()).padStart(2, '0'); - return `${year}-${month}-${day}`; - })() - } - - - ))} + + + { + // createdAt을 yyyy-mm-dd 형식으로 변환 + // 임시로.. 나중에 변경해야함 + (() => { + const date = new Date(item.createdAt); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; + })() + } + + + ))} + From 347de42dd33d973de212446599f985ba5d4208ca Mon Sep 17 00:00:00 2001 From: lepitaaar Date: Thu, 14 Aug 2025 01:44:40 +0900 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20=EC=A7=80=EC=9B=90=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EC=A0=84=20=EC=9D=B4=ED=9B=84=20=EC=9D=B4=EB=8F=99,?= =?UTF-8?q?=20=EC=A7=80=EC=9B=90=EC=84=9C=20=EB=94=94=ED=85=8C=EC=9D=BC=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=8B=9C=20=EB=A1=9C=EC=BB=AC=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=EC=99=80=20=EC=8B=B1=ED=81=AC,=20=EB=AA=A9=EB=A1=9D?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=82=AC=EC=9A=A9=EC=9E=90=EB=A5=BC=20?= =?UTF-8?q?=EC=84=A0=ED=83=9D=ED=95=B4=20=EB=B3=80=EA=B2=BD=EA=B0=80?= =?UTF-8?q?=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ApplicantsTab/ApplicantDetailPage.tsx | 62 ++++++++++++++----- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage.tsx b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage.tsx index 85a8068dd..19b51f2c8 100644 --- a/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage.tsx +++ b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage.tsx @@ -8,11 +8,13 @@ import QuestionContainer from '@/pages/ApplicationFormPage/components/QuestionCo import QuestionAnswerer from '@/pages/ApplicationFormPage/components/QuestionAnswerer/QuestionAnswerer'; import { useGetApplication } from '@/hooks/queries/application/useGetApplication'; import Spinner from '@/components/common/Spinner/Spinner'; -import backButtonIcon from '@/assets/images/icons/back_button_icon.svg'; +import BackButton from '@/assets/images/icons/back_arrow_icon.svg'; +import ForwardButton from '@/assets/images/icons/forward_arrow_icon.svg'; import debounce from '@/utils/debounce'; import updateApplicantMemo from '@/apis/application/updateApplicantDetail'; import { ApplicationStatus } from '@/types/applicants'; import mapStatusToGroup from '@/utils/mapStatusToGroup'; +import { Question } from '@/types/application'; const AVAILABLE_STATUSES = [ ApplicationStatus.SCREENING, // 서류검토 @@ -25,14 +27,16 @@ const ApplicantDetailPage = () => { const navigate = useNavigate(); const [applicantMemo, setAppMemo] = useState(''); const [applicantStatus, setApplicantStatus] = useState(); - const { applicantsData, clubId } = useAdminClubContext(); + const { applicantsData, clubId, setApplicantsData } = useAdminClubContext(); const { data: formData, isLoading, isError } = useGetApplication(clubId!); - const applicant = useMemo( - () => applicantsData?.applicants.find((a) => a.id === questionId), - [applicantsData, questionId], - ); + const { applicant, applicantIndex } = useMemo(() => { + const index = applicantsData?.applicants.findIndex((a) => a.id === questionId) ?? -1; + const _applicant = applicantsData?.applicants[index]; + + return { applicant: _applicant, applicantIndex: index }; + }, [applicantsData, questionId]); useEffect(() => { if (applicant) { @@ -67,19 +71,43 @@ const ApplicantDetailPage = () => { .map((ans) => ans.value); }; + const updateApplicantInContext = (memo: string, status: ApplicationStatus) => { + if (!applicantsData || applicantIndex === -1) return; + + const updatedApplicants = [...applicantsData.applicants]; + updatedApplicants[applicantIndex] = { ...applicant, memo, status }; - const handleMemoChange = (e: any) => { + setApplicantsData({ ...applicantsData, applicants: updatedApplicants }); + }; + + const handleMemoChange = (e: React.ChangeEvent) => { const newMemo = e.target.value; setAppMemo(newMemo); + updateApplicantInContext(newMemo, applicantStatus!); updateApplicantDetail(newMemo, applicantStatus); }; const handleStatusChange = (e: React.ChangeEvent) => { const newStatus = e.target.value as ApplicationStatus; setApplicantStatus(newStatus); + updateApplicantInContext(applicantMemo, newStatus); updateApplicantDetail(applicantMemo, newStatus); }; + const previousApplicant = () => { + const previousData = applicantsData.applicants[applicantIndex - 1]; + if (applicantIndex < 0 || !previousData) return; + + navigate(`/admin/applicants/${previousData.id}`); + }; + + const nextApplicant = () => { + const nextData = applicantsData.applicants[applicantIndex + 1]; + if (applicantIndex < 0 || !nextData) return; + + navigate(`/admin/applicants/${nextData.id}`); + }; + return ( <>
@@ -96,13 +124,19 @@ const ApplicantDetailPage = () => { marginBottom: 16, }} > -