Skip to content

Commit cfec6ea

Browse files
committed
feat: 모집 지원서 생성 api 연결 완료
1 parent 3e0b644 commit cfec6ea

File tree

13 files changed

+156
-135
lines changed

13 files changed

+156
-135
lines changed

src/api/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const API_URLS = {
88
MANAGER_LOGIN: "/backend/auth/manager/login",
99
CREATE_CLUB: "/backend/councils",
1010
CHANGE_COUNCIL_NAME: "/backend/councils/:councilId/names",
11+
GET_COUNCIL_MEMBERS: "/backend/councils/:councilId/members",
1112
} as const;
1213

1314
export const getApiUrl = (endpoint: string): string => {

src/api/formDataConverter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ const convertQuestionToApiItem = (
8282
* 폼 에디터 데이터를 API 요청 형식으로 변환
8383
*/
8484
export const convertFormDataToApiRequest = (
85-
formName: string,
85+
name: string,
8686
endDate: Date | null,
8787
endTime: string,
8888
questions: QuestionConfig[]
@@ -102,7 +102,7 @@ export const convertFormDataToApiRequest = (
102102
);
103103

104104
return {
105-
name: formName,
105+
name,
106106
endAt,
107107
isActive: false,
108108
recruitmentStatus: "DOCUMENT_SCREENING",

src/api/getCouncilMembers.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { API_URLS, apiClient } from "./config";
2+
import { useQuery } from "@tanstack/react-query";
3+
4+
export type CouncilMember = {
5+
councilManagerId: number;
6+
memberName: string;
7+
memberEmail: string;
8+
councilRole: "VICE" | "MANAGER";
9+
};
10+
11+
export type GetCouncilMembersResponse = {
12+
code: number;
13+
message: string;
14+
data: CouncilMember[];
15+
};
16+
17+
async function getCouncilMembers(
18+
councilId: number | string
19+
): Promise<GetCouncilMembersResponse> {
20+
const { data } = await apiClient.get(
21+
API_URLS.GET_COUNCIL_MEMBERS.replace(":councilId", String(councilId))
22+
);
23+
return data as GetCouncilMembersResponse;
24+
}
25+
26+
export function useGetCouncilMembers(councilId: number | string | undefined) {
27+
return useQuery({
28+
queryKey: ["councilMembers", councilId],
29+
queryFn: () => getCouncilMembers(councilId!),
30+
enabled: !!councilId,
31+
});
32+
}

src/app/layout/RootLayout.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import { useLocation } from "react-router-dom";
66

77
const RootLayout = () => {
88
const location = useLocation();
9-
const isFormEditPage = location.pathname === "/applicationform/edit";
9+
const isFormEditPage =
10+
location.pathname === "/applicationform/edit" ||
11+
location.pathname.includes("/applicationform/edit");
1012

1113
if (isFormEditPage) {
1214
return (
Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
import FormEditPage from "./FormEditPage";
2-
import { FormEditProvider } from "@/widget/formEdit/context/FormEditProvider";
32

43
const FormEditPageWrapper = () => {
5-
return (
6-
<FormEditProvider>
7-
<FormEditPage />
8-
</FormEditProvider>
9-
);
4+
return <FormEditPage />;
105
};
116

127
export default FormEditPageWrapper;

src/pages/recruitApplicant/RecruitApplicantPage.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ import { useMemo } from "react";
22
import { useLocation, useNavigate, useParams } from "react-router-dom";
33
import { ArrowLeft } from "lucide-react";
44
import RecruitApplicantMain from "@/widget/recruitApplicant/ui/RecruitApplicantMain";
5-
import {
6-
REVIEWER_DISPLAY_NAME,
7-
findApplicantById,
8-
} from "@/widget/recruitdetail/constants/applicants";
5+
import { findApplicantById } from "@/widget/recruitdetail/constants/applicants";
96
import type { ApplicantDetail } from "@/widget/recruitdetail/types";
107

118
interface ApplicantLocationState {
@@ -50,9 +47,6 @@ const RecruitApplicantPage = () => {
5047
<ArrowLeft className="h-4 w-4" />
5148
돌아가기
5249
</button>
53-
<span className="text-xs text-gray-400">
54-
담당자 메모 기본 작성자: {REVIEWER_DISPLAY_NAME}
55-
</span>
5650
</div>
5751
</div>
5852

src/shared/components/Header.tsx

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
import { ArrowLeft, Plus } from "lucide-react";
2-
import { useLocation, useNavigate } from "react-router-dom";
2+
import { useLocation, useNavigate, useParams } from "react-router-dom";
33
import { createRecruitment } from "@/api/recruitment";
44
import { convertFormDataToApiRequest } from "@/api/formDataConverter";
55
import { useContext } from "react";
66
import { FormEditContext } from "@/widget/formEdit/context/FormEditContext";
7+
import { toast } from "sonner";
78

89
const Header = () => {
910
const location = useLocation();
1011
const navigate = useNavigate();
12+
const { councilId } = useParams<{ councilId: string }>();
1113

1214
// FormEditContext가 존재하는지 확인
1315
const formEditContext = useContext(FormEditContext);
14-
const { formName, endDate, endTime, questions } = formEditContext || {
15-
formName: "",
16-
endDate: null,
17-
endTime: "00:00",
18-
questions: [],
19-
};
2016

21-
const isFormEditPage = location.pathname === "/applicationform/edit";
17+
const isFormEditPage =
18+
location.pathname === "/applicationform/edit" ||
19+
location.pathname.includes("/applicationform/edit");
2220

2321
const handleBack = () => {
2422
navigate(-1);
@@ -31,41 +29,54 @@ const Header = () => {
3129
return;
3230
}
3331

32+
// formEditContext에서 최신 값 가져오기
33+
const currentName = formEditContext.name;
34+
const currentEndDate = formEditContext.endDate;
35+
const currentEndTime = formEditContext.endTime;
36+
const currentQuestions = formEditContext.questions;
37+
3438
// 유효성 검사
35-
if (!formName.trim()) {
39+
if (!currentName || !currentName.trim()) {
3640
alert("지원서 제목을 입력해주세요.");
3741
return;
3842
}
3943

40-
if (!endDate) {
44+
if (!currentEndDate) {
4145
alert("지원 기간 종료일을 선택해주세요.");
4246
return;
4347
}
4448

45-
if (!endTime) {
49+
if (!currentEndTime) {
4650
alert("지원 기간 종료 시간을 선택해주세요.");
4751
return;
4852
}
4953

50-
if (questions.length === 0) {
54+
if (currentQuestions.length === 0) {
5155
alert("최소 1개 이상의 질문을 추가해주세요.");
5256
return;
5357
}
5458

5559
try {
5660
// 폼 데이터를 API 형식으로 변환
5761
const recruitmentData = convertFormDataToApiRequest(
58-
formName.trim(),
59-
endDate,
60-
endTime,
61-
questions
62+
currentName.trim(),
63+
currentEndDate,
64+
currentEndTime,
65+
currentQuestions
6266
);
6367

6468
// API 호출
6569
await createRecruitment(recruitmentData);
6670

71+
// 성공 토스트 표시
72+
toast.success("모집 지원서 생성이 완료되었습니다.");
73+
6774
// 성공 시 페이지 이동
68-
navigate("/applicationform");
75+
if (councilId) {
76+
navigate(`/${councilId}/recruit`);
77+
} else {
78+
navigate("/applicationform");
79+
}
6980
} catch (error) {
7081
console.error("지원서 양식 생성 실패:", error);
7182

@@ -102,7 +113,7 @@ const Header = () => {
102113
className="flex items-center gap-2 rounded-xl bg-primary px-5 py-2 text-title-14-semibold text-white transition hover:opacity-90"
103114
>
104115
<Plus className="h-4 w-4" />
105-
<span>지원서 양식 생성</span>
116+
<span>모집 생성하기</span>
106117
</button>
107118
</div>
108119
)}

src/widget/formEdit/context/FormEditContext.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { createContext } from "react";
22
import type { QuestionConfig } from "../types";
33

44
export type FormEditContextValue = {
5-
formName: string;
6-
setFormName: (value: string) => void;
5+
name: string;
6+
setName: (value: string) => void;
77
endDate: Date | null;
88
setEndDate: (value: Date | null) => void;
99
endTime: string;

src/widget/formEdit/context/FormEditProvider.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ type FormEditProviderProps = {
88
};
99

1010
export const FormEditProvider = ({ children }: FormEditProviderProps) => {
11-
const [formName, setFormName] = useState("");
11+
const [name, setName] = useState("");
1212
const [endDate, setEndDate] = useState<Date | null>(null);
1313
const [endTime, setEndTime] = useState("00:00");
1414
const [questions, setQuestions] = useState<QuestionConfig[]>([]);
@@ -19,15 +19,15 @@ export const FormEditProvider = ({ children }: FormEditProviderProps) => {
1919
}, []);
2020

2121
const resetAll = useCallback(() => {
22-
setFormName("");
22+
setName("");
2323
resetPeriod();
2424
setQuestions([]);
2525
}, [resetPeriod]);
2626

2727
const value = useMemo<FormEditContextValue>(
2828
() => ({
29-
formName,
30-
setFormName,
29+
name,
30+
setName,
3131
endDate,
3232
setEndDate,
3333
endTime,
@@ -37,7 +37,7 @@ export const FormEditProvider = ({ children }: FormEditProviderProps) => {
3737
resetPeriod,
3838
resetAll,
3939
}),
40-
[formName, endDate, endTime, questions, resetPeriod, resetAll]
40+
[name, endDate, endTime, questions, resetPeriod, resetAll]
4141
);
4242

4343
return (

src/widget/formEdit/ui/FormEditMain.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ const FormEditMain = ({
152152
onRemoveQuestion,
153153
}: FormEditMainProps) => {
154154
const {
155-
formName,
156-
setFormName,
155+
name,
156+
setName,
157157
endDate,
158158
setEndDate,
159159
endTime,
@@ -346,8 +346,8 @@ const FormEditMain = ({
346346
<div className="flex h-full w-full gap-6 bg-black-15 px-10 pt-10 pb-24 overflow-y-auto">
347347
<div className="flex h-full w-full flex-col gap-6 pb-12">
348348
<input
349-
value={formName}
350-
onChange={(event) => setFormName(event.target.value)}
349+
value={name}
350+
onChange={(event) => setName(event.target.value)}
351351
className="w-full rounded-xl bg-white px-5 py-4 text-title-16-semibold text-black-100 shadow-sm placeholder:text-black-35 focus:outline-none focus:ring-2 focus:ring-primary/60"
352352
placeholder="지원서 양식의 제목을 입력해주세요"
353353
/>

0 commit comments

Comments
 (0)