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
diff --git a/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage.tsx b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage.tsx
index 85a8068dd..4ee8c92b2 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,
}}
>
-
+ {applicantsData.applicants.map((a) => (
+
+ ))}
+
+
@@ -115,7 +149,7 @@ const ApplicantDetailPage = () => {
- {formData.questions.map((q: import('@/types/application').Question, i: number) => (
+ {formData.questions.map((q: Question, i: number) => (
{
- {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}`;
+ })()
+ }
+
+
+ ))}
+
>
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: '서류검토'};
}
}