From b40b6c8c0d1787959f84a17ec49d62bc275b209a Mon Sep 17 00:00:00 2001
From: seongwon030 <105052068+seongwon030@users.noreply.github.com>
Date: Sat, 16 Aug 2025 12:51:54 +0900
Subject: [PATCH 1/7] =?UTF-8?q?fix:=20=EA=B8=B0=EB=B3=B8=20padding=20?=
=?UTF-8?q?=EC=A0=81=EC=9A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../AdminPage/tabs/ApplicantsTab/ApplicantsTab.styles.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantsTab.styles.ts b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantsTab.styles.ts
index b2190cddd..72933b873 100644
--- a/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantsTab.styles.ts
+++ b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantsTab.styles.ts
@@ -141,7 +141,7 @@ export const ApplicantTableHeader = styled.th<{
color: var(--78, #787878);
width: ${({ width }) => (width ? `${width}px` : 'auto')};
text-align: ${({ isMemo }) => (isMemo ? 'left' : 'center')};
- padding-left: ${({ isMemo }) => (isMemo ? '30px' : 'none')};
+ padding-left: ${({ isMemo }) => (isMemo ? '30px' : '8px')};
${({ borderLeft }) =>
borderLeft &&
@@ -171,7 +171,7 @@ export const ApplicantTableCol = styled.td<{ isMemo?: boolean }>`
padding: 12px 8px;
font-size: 16px;
text-align: ${({ isMemo }) => (isMemo ? 'left' : 'center')};
- padding-left: ${({ isMemo }) => (isMemo ? '30px' : 'none')};
+ padding-left: ${({ isMemo }) => (isMemo ? '30px' : '8px')};
`;
export const ApplicantTableCheckbox = styled.input.attrs({ type: 'checkbox' })`
From 0f3f5fa24eac4facefc0cea67b6217b4122332f7 Mon Sep 17 00:00:00 2001
From: seongwon030 <105052068+seongwon030@users.noreply.github.com>
Date: Sat, 16 Aug 2025 17:02:08 +0900
Subject: [PATCH 2/7] =?UTF-8?q?fix:=20dropdown=20svg=EB=B3=80=EA=B2=BD?=
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 -
frontend/src/assets/images/icons/next_applicant.svg | 4 ++++
frontend/src/assets/images/icons/prev_applicant.svg | 4 ++++
4 files changed, 8 insertions(+), 2 deletions(-)
delete mode 100644 frontend/src/assets/images/icons/back_arrow_icon.svg
delete mode 100644 frontend/src/assets/images/icons/forward_arrow_icon.svg
create mode 100644 frontend/src/assets/images/icons/next_applicant.svg
create mode 100644 frontend/src/assets/images/icons/prev_applicant.svg
diff --git a/frontend/src/assets/images/icons/back_arrow_icon.svg b/frontend/src/assets/images/icons/back_arrow_icon.svg
deleted file mode 100644
index 0a00b873e..000000000
--- a/frontend/src/assets/images/icons/back_arrow_icon.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ 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
deleted file mode 100644
index 96483cd33..000000000
--- a/frontend/src/assets/images/icons/forward_arrow_icon.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/frontend/src/assets/images/icons/next_applicant.svg b/frontend/src/assets/images/icons/next_applicant.svg
new file mode 100644
index 000000000..88790aeb2
--- /dev/null
+++ b/frontend/src/assets/images/icons/next_applicant.svg
@@ -0,0 +1,4 @@
+
diff --git a/frontend/src/assets/images/icons/prev_applicant.svg b/frontend/src/assets/images/icons/prev_applicant.svg
new file mode 100644
index 000000000..b3715b669
--- /dev/null
+++ b/frontend/src/assets/images/icons/prev_applicant.svg
@@ -0,0 +1,4 @@
+
From 01572277f91b2ef0ca38dae89a210b56c69e35ce Mon Sep 17 00:00:00 2001
From: seongwon030 <105052068+seongwon030@users.noreply.github.com>
Date: Sat, 16 Aug 2025 17:17:32 +0900
Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=EC=A7=80=EC=9B=90=EC=9E=90=20?=
=?UTF-8?q?=EB=AA=A9=EB=A1=9D=20dropdown=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?=
=?UTF-8?q?=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
frontend/src/assets/images/icons/applicant_drop.svg | 3 +++
1 file changed, 3 insertions(+)
create mode 100644 frontend/src/assets/images/icons/applicant_drop.svg
diff --git a/frontend/src/assets/images/icons/applicant_drop.svg b/frontend/src/assets/images/icons/applicant_drop.svg
new file mode 100644
index 000000000..810f11bf2
--- /dev/null
+++ b/frontend/src/assets/images/icons/applicant_drop.svg
@@ -0,0 +1,3 @@
+
From f9910c124e0c00a1f7053556c8add49c3cc5d87a Mon Sep 17 00:00:00 2001
From: seongwon030 <105052068+seongwon030@users.noreply.github.com>
Date: Sat, 16 Aug 2025 17:17:59 +0900
Subject: [PATCH 4/7] =?UTF-8?q?refactor:=20ApplicationDetailPage=20?=
=?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
frontend/src/App.tsx | 6 +-
.../ApplicantsTab/ApplicantDetailPage.tsx | 167 ------------------
2 files changed, 3 insertions(+), 170 deletions(-)
delete mode 100644 frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage.tsx
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 71c0e5e0d..5e2e23096 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -18,7 +18,7 @@ import PrivateRoute from '@/pages/AdminPage/auth/PrivateRoute/PrivateRoute';
import PhotoEditTab from '@/pages/AdminPage/tabs/PhotoEditTab/PhotoEditTab';
import ApplicationFormPage from './pages/ApplicationFormPage/ApplicationFormPage';
import ApplicantsTab from './pages/AdminPage/tabs/ApplicantsTab/ApplicantsTab';
-import ApplicantDetailPage from './pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage';
+import ApplicantDetailPage from './pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage';
const queryClient = new QueryClient();
@@ -78,11 +78,11 @@ const App = () => {
path='application-edit'
element={}
/>
- }
/>
- }
/>
diff --git a/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage.tsx b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage.tsx
deleted file mode 100644
index 4ee8c92b2..000000000
--- a/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage.tsx
+++ /dev/null
@@ -1,167 +0,0 @@
-import React, { useEffect, useMemo, useState } from 'react';
-import { useParams, useNavigate } from 'react-router-dom';
-import { useAdminClubContext } from '@/context/AdminClubContext';
-import Header from '@/components/common/Header/Header';
-import { PageContainer } from '@/styles/PageContainer.styles';
-import * as Styled from '@/pages/ApplicationFormPage/ApplicationFormPage.styles';
-import QuestionContainer from '@/pages/ApplicationFormPage/components/QuestionContainer/QuestionContainer';
-import QuestionAnswerer from '@/pages/ApplicationFormPage/components/QuestionAnswerer/QuestionAnswerer';
-import { useGetApplication } from '@/hooks/queries/application/useGetApplication';
-import Spinner from '@/components/common/Spinner/Spinner';
-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, // 서류검토
- ApplicationStatus.INTERVIEW_SCHEDULED, // 면접예정
- ApplicationStatus.ACCEPTED, // 합격
-];
-
-const ApplicantDetailPage = () => {
- const { questionId } = useParams<{ questionId: string }>();
- const navigate = useNavigate();
- const [applicantMemo, setAppMemo] = useState('');
- const [applicantStatus, setApplicantStatus] = useState();
- const { applicantsData, clubId, setApplicantsData } = useAdminClubContext();
-
- const { data: formData, isLoading, isError } = useGetApplication(clubId!);
-
- 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) {
- setAppMemo(applicant.memo);
- setApplicantStatus(mapStatusToGroup(applicant.status).status);
- }
- }, [applicant]);
-
- const updateApplicantDetail = useMemo(
- () =>
- debounce((memo: any, status: any) => {
- updateApplicantMemo(memo as string, status as ApplicationStatus, clubId!, questionId!);
- }, 400),
- [clubId, questionId],
- );
-
- if (!applicantsData) {
- return 지원자 데이터를 불러올 수 없습니다.
;
- }
- if (isLoading) return ;
- if (isError || !formData) return 지원서 정보를 불러올 수 없습니다.
;
-
- // questionId로 지원자 찾기
- if (!applicant) {
- return 해당 지원자를 찾을 수 없습니다.
;
- }
-
- // 답변 매핑 함수
- const getAnswerByQuestionId = (qId: number) => {
- return applicant.answers
- .filter((ans) => ans.id === qId)
- .map((ans) => ans.value);
- };
-
- const updateApplicantInContext = (memo: string, status: ApplicationStatus) => {
- if (!applicantsData || applicantIndex === -1) return;
-
- const updatedApplicants = [...applicantsData.applicants];
- updatedApplicants[applicantIndex] = { ...applicant, memo, status };
-
- 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 (
- <>
-
-
-
-

-
-

-
-
-
-
-
-
- {formData.questions.map((q: Question, i: number) => (
-
- {}}
- />
-
- ))}
-
-
- >
- );
-};
-
-export default ApplicantDetailPage;
\ No newline at end of file
From 4c6ead20cc5ef3bcbc942c4422a9de0da2a05dd4 Mon Sep 17 00:00:00 2001
From: seongwon030 <105052068+seongwon030@users.noreply.github.com>
Date: Sat, 16 Aug 2025 17:19:24 +0900
Subject: [PATCH 5/7] =?UTF-8?q?feat:=20=EC=A7=80=EC=9B=90=EC=9E=90=20?=
=?UTF-8?q?=EC=83=81=EC=84=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20UI=20?=
=?UTF-8?q?=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20=EC=83=81=ED=83=9C=EB=B3=84=20?=
=?UTF-8?q?=EC=83=89=EC=83=81=20=EC=A0=81=EC=9A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 지원자 상세 페이지 레이아웃 및 스타일 개선
- 헤더 컨테이너 구조화 (ApplicantContainer, StatusSelect 분리)
- 메모 영역 UI 개선 (MemoContainer, MemoLabel, MemoTextarea)
- 커스텀 드롭다운 화살표 적용 (DropdownArrow SVG)
- 상태별 배경색 동적 적용
- getStatusColor 함수로 상태별 색상 매핑
- SUBMITTED/SCREENING 동일 색상 처리
- StatusSelect 컴포넌트에 $backgroundColor prop 적용
---
.../ApplicantDetailPage.styles.ts | 148 +++++++++++++
.../ApplicantDetailPage.tsx | 200 ++++++++++++++++++
2 files changed, 348 insertions(+)
create mode 100644 frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.styles.ts
create mode 100644 frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.tsx
diff --git a/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.styles.ts b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.styles.ts
new file mode 100644
index 000000000..81b8498fb
--- /dev/null
+++ b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.styles.ts
@@ -0,0 +1,148 @@
+import styled from 'styled-components';
+import * as ApplicationFormPageStyles from '@/pages/ApplicationFormPage/ApplicationFormPage.styles';
+import DropdownArrow from '@/assets/images/icons/applicant_drop.svg';
+
+export const Wrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 20px;
+ margin-bottom: 10px;
+`;
+
+export const HeaderContainer = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ width: 100%;
+ height: 58px;
+`;
+
+export const ApplicantContainer = styled.div`
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ gap: 240px;
+ width: 82%;
+ height: 100%;
+ border: none;
+ border-radius: 10px;
+ background: var(--f5, #f5f5f5);
+
+ select {
+ font-size: 24px;
+ font-style: normal;
+ font-weight: 700;
+ border: none;
+ background-color: transparent;
+
+ background-image: url(${DropdownArrow});
+ background-repeat: no-repeat;
+ background-position: right 8px center;
+ background-size: 11px 11px;
+
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ }
+`;
+
+export const StatusSelect = styled.select<{ $backgroundColor: string }>`
+ border: none;
+ border-radius: 10px;
+ padding: 8px 12px;
+ width: 18%;
+ height: 100%;
+ cursor: pointer;
+
+ color: var(--4B, #4b4b4b);
+ text-align: center;
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 600;
+
+ background-color: ${(props) => props.$backgroundColor};
+
+ background-image: url(${DropdownArrow});
+ background-repeat: no-repeat;
+ background-position: right 15px center;
+ padding-right: 30px;
+ background-size: 9px 9px;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+
+ &:focus {
+ outline: none;
+ }
+`;
+
+export const MemoContainer = styled.div`
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+ width: 100%;
+ gap: 24px;
+ padding: 12px 12px;
+ min-height: 100px;
+ background: var(--f5, #f5f5f5);
+ border-radius: 10px;
+`;
+
+export const MemoLabel = styled.label`
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ align-self: flex-start;
+ width: 60px;
+ height: 32px;
+ background: #fff;
+ border-radius: 10px;
+ padding: 6px 14px;
+ color: var(--, #111);
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 600;
+
+ &::after {
+ content: '';
+ position: absolute;
+ right: -20px;
+ top: 30%;
+ height: 40%;
+ width: 4px;
+ height: 14px;
+ background: #d9d9d9;
+ }
+`;
+
+export const MemoTextarea = styled.textarea`
+ flex: 1;
+ min-height: 80px;
+ border: none;
+ border-radius: 10px;
+ background: var(--f5, #f5f5f5);
+ padding: 12px;
+ resize: none;
+ font-size: 14px;
+ font-style: normal;
+ font-weight: 400;
+ color: var(--4B, #4b4b4b);
+
+ &:focus {
+ outline: none;
+ }
+`;
+
+export const QuestionsWrapper = styled(
+ ApplicationFormPageStyles.QuestionsWrapper,
+)`
+ cursor: default;
+`;
+
+export const NavigationButton = styled.img`
+ cursor: pointer;
+`;
diff --git a/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.tsx b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.tsx
new file mode 100644
index 000000000..3dc827ec8
--- /dev/null
+++ b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.tsx
@@ -0,0 +1,200 @@
+import React, { useEffect, useMemo, useState } from 'react';
+import * as Styled from './ApplicantDetailPage.styles';
+import { useParams, useNavigate } from 'react-router-dom';
+import { useAdminClubContext } from '@/context/AdminClubContext';
+import Header from '@/components/common/Header/Header';
+import QuestionContainer from '@/pages/ApplicationFormPage/components/QuestionContainer/QuestionContainer';
+import QuestionAnswerer from '@/pages/ApplicationFormPage/components/QuestionAnswerer/QuestionAnswerer';
+import Spinner from '@/components/common/Spinner/Spinner';
+import debounce from '@/utils/debounce';
+import updateApplicantMemo from '@/apis/application/updateApplicantDetail';
+import { useGetApplication } from '@/hooks/queries/application/useGetApplication';
+import { ApplicationStatus } from '@/types/applicants';
+import mapStatusToGroup from '@/utils/mapStatusToGroup';
+import { Question } from '@/types/application';
+import PrevApplicantButton from '@/assets/images/icons/prev_applicant.svg';
+import NextApplicantButton from '@/assets/images/icons/next_applicant.svg';
+
+const AVAILABLE_STATUSES = [
+ ApplicationStatus.SCREENING, // 서류검토 (SUBMITTED 포함)
+ ApplicationStatus.INTERVIEW_SCHEDULED, // 면접예정
+ ApplicationStatus.ACCEPTED, // 합격
+] as const;
+
+const getStatusColor = (status: ApplicationStatus | undefined): string => {
+ switch (status) {
+ case ApplicationStatus.ACCEPTED:
+ return 'var(--f5, #F5F5F5)';
+ case ApplicationStatus.SCREENING:
+ case ApplicationStatus.SUBMITTED:
+ return '#E5F6FF';
+ case ApplicationStatus.INTERVIEW_SCHEDULED:
+ return '#E9FFF1';
+ default:
+ return 'var(--f5, #F5F5F5)';
+ }
+};
+
+const ApplicantDetailPage = () => {
+ const { questionId } = useParams<{ questionId: string }>();
+ const navigate = useNavigate();
+ const [applicantMemo, setAppMemo] = useState('');
+ const [applicantStatus, setApplicantStatus] = useState();
+ const { applicantsData, clubId, setApplicantsData } = useAdminClubContext();
+
+ const { data: formData, isLoading, isError } = useGetApplication(clubId!);
+
+ 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) {
+ setAppMemo(applicant.memo);
+ setApplicantStatus(mapStatusToGroup(applicant.status).status);
+ }
+ }, [applicant]);
+
+ const updateApplicantDetail = useMemo(
+ () =>
+ debounce((memo: any, status: any) => {
+ updateApplicantMemo(
+ memo as string,
+ status as ApplicationStatus,
+ clubId!,
+ questionId!,
+ );
+ }, 400),
+ [clubId, questionId],
+ );
+
+ if (!applicantsData) {
+ return 지원자 데이터를 불러올 수 없습니다.
;
+ }
+ if (isLoading) return ;
+ if (isError || !formData) return 지원서 정보를 불러올 수 없습니다.
;
+
+ // questionId로 지원자 찾기
+ if (!applicant) {
+ return 해당 지원자를 찾을 수 없습니다.
;
+ }
+
+ // 답변 매핑 함수
+ const getAnswerByQuestionId = (qId: number) => {
+ return applicant.answers
+ .filter((ans) => ans.id === qId)
+ .map((ans) => ans.value);
+ };
+
+ const updateApplicantInContext = (
+ memo: string,
+ status: ApplicationStatus,
+ ) => {
+ if (!applicantsData || applicantIndex === -1) return;
+
+ const updatedApplicants = [...applicantsData.applicants];
+ updatedApplicants[applicantIndex] = { ...applicant, memo, status };
+
+ 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 (
+ <>
+
+
+
+
+
+
+
+
+
+ {AVAILABLE_STATUSES.map((status) => (
+
+ ))}
+
+
+
+
+ 메모
+
+
+
+
+
+ {formData.questions.map((q: Question, i: number) => (
+
+ {}}
+ />
+
+ ))}
+
+ >
+ );
+};
+
+export default ApplicantDetailPage;
From 150bdee7361f5b154b3e94e73c95e246b623446f Mon Sep 17 00:00:00 2001
From: seongwon030 <105052068+seongwon030@users.noreply.github.com>
Date: Sat, 16 Aug 2025 17:26:47 +0900
Subject: [PATCH 6/7] =?UTF-8?q?feat:=20=EC=A7=80=EC=9B=90=EC=84=9C=20?=
=?UTF-8?q?=ED=85=8C=EB=91=90=EB=A6=AC=20=EC=A0=81=EC=9A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../ApplicantDetailPage.styles.ts | 8 +++++++
.../ApplicantDetailPage.tsx | 24 ++++++++++---------
2 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.styles.ts b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.styles.ts
index 81b8498fb..f0b4a38be 100644
--- a/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.styles.ts
+++ b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.styles.ts
@@ -137,6 +137,14 @@ export const MemoTextarea = styled.textarea`
}
`;
+export const ApplicantInfoContainer = styled.div`
+ display: block;
+ width: 100%;
+ padding: 10px 30px;
+ border-radius: 10px;
+ border: 1px solid #f2f2f2;
+`;
+
export const QuestionsWrapper = styled(
ApplicationFormPageStyles.QuestionsWrapper,
)`
diff --git a/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.tsx b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.tsx
index 3dc827ec8..9e5b8994d 100644
--- a/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.tsx
+++ b/frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantDetailPage/ApplicantDetailPage.tsx
@@ -182,17 +182,19 @@ const ApplicantDetailPage = () => {
-
- {formData.questions.map((q: Question, i: number) => (
-
- {}}
- />
-
- ))}
-
+
+
+ {formData.questions.map((q: Question, i: number) => (
+
+ {}}
+ />
+
+ ))}
+
+
>
);
};
From 61ad983e4f71bce281260cb3fbfcc8c4cba8013b Mon Sep 17 00:00:00 2001
From: seongwon030 <105052068+seongwon030@users.noreply.github.com>
Date: Sun, 17 Aug 2025 14:45:09 +0900
Subject: [PATCH 7/7] =?UTF-8?q?refactor:=20=EC=A7=80=EC=9B=90=EC=9E=90=20?=
=?UTF-8?q?=EA=B4=80=EB=A6=AC=20->=20=EC=A7=80=EC=9B=90=EC=9E=90=20?=
=?UTF-8?q?=ED=98=84=ED=99=A9=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/pages/AdminPage/components/SideBar/SideBar.tsx | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/frontend/src/pages/AdminPage/components/SideBar/SideBar.tsx b/frontend/src/pages/AdminPage/components/SideBar/SideBar.tsx
index 24f8270e0..07776e311 100644
--- a/frontend/src/pages/AdminPage/components/SideBar/SideBar.tsx
+++ b/frontend/src/pages/AdminPage/components/SideBar/SideBar.tsx
@@ -15,7 +15,7 @@ const tabs = [
{ label: '모집 정보 수정', path: '/admin/recruit-edit' },
{ label: '활동 사진 수정', path: '/admin/photo-edit' },
{ label: '지원서 관리', path: '/admin/application-edit' },
- { label: '지원자 관리', path: '/admin/applicants' },
+ { label: '지원자 현황', path: '/admin/applicants' },
{ label: '계정 관리', path: '/admin/account-edit' },
];
@@ -41,7 +41,11 @@ const SideBar = ({ clubLogo, clubName }: SideBarProps) => {
if (!confirmed) return;
try {
- if (document.cookie.split(';').some((cookie) => cookie.trim().startsWith('refreshToken='))) {
+ if (
+ document.cookie
+ .split(';')
+ .some((cookie) => cookie.trim().startsWith('refreshToken='))
+ ) {
await logout();
}
localStorage.removeItem('accessToken');