Skip to content

Commit e0ff39c

Browse files
committed
Revert "fix: 지원 시스템 전체를 실제 백엔드 GraphQL 스키마에 맞춰 수정"
This reverts commit 2c611c5.
1 parent 2c611c5 commit e0ff39c

12 files changed

Lines changed: 532 additions & 487 deletions

File tree

src/api/applications.ts

Lines changed: 90 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,135 @@
11
import { gql } from "graphql-request";
22
import { gqlClient } from "./graphql-client";
3-
import type { Form, Application, SubmitInput } from "@/types/application";
4-
5-
const FORM_QUERY = gql`
6-
query Form($id: ID!) {
7-
form(id: $id) {
8-
id title description recruitmentId type isActive createdBy createdAt updatedAt
9-
questions { id label type options required sortOrder }
3+
import type {
4+
FormTemplate,
5+
MyApplication,
6+
RecruitmentPeriod,
7+
ApplicationSubmission,
8+
ApplicationListItem,
9+
} from "@/types/application";
10+
import type { PagedResponse } from "@/types/common";
11+
12+
const MY_APPLICATION_QUERY = gql`
13+
query MyApplication {
14+
myApplication {
15+
id status formTemplateId track submittedAt
16+
answers { questionId value }
17+
paymentInfo { bank account amount holder }
1018
}
1119
}
1220
`;
1321

14-
const FORMS_QUERY = gql`
15-
query Forms($recruitmentId: String!) {
16-
forms(recruitmentId: $recruitmentId) {
17-
id title description recruitmentId type isActive createdBy createdAt updatedAt
18-
questions { id label type options required sortOrder }
22+
const FORM_TEMPLATE_QUERY = gql`
23+
query FormTemplate($type: String!) {
24+
formTemplate(type: $type) {
25+
id type updatedAt
26+
questions { id type label required options order }
1927
}
2028
}
2129
`;
2230

23-
const MY_APPLICATIONS_QUERY = gql`
24-
query MyApplications {
25-
myApplications {
26-
id formId memberId status submittedAt approvedAt approvedBy updatedAt
27-
answers { id questionId value }
31+
const RECRUITMENT_PERIOD_QUERY = gql`
32+
query RecruitmentPeriod($type: String!) {
33+
recruitmentPeriod(type: $type) {
34+
id type startDate endDate isActive
2835
}
2936
}
3037
`;
3138

32-
const APPLICATIONS_QUERY = gql`
33-
query Applications($formId: String!) {
34-
applications(formId: $formId) {
35-
id formId memberId status submittedAt approvedAt approvedBy updatedAt
36-
answers { id questionId value }
37-
}
39+
const SUBMIT_APPLICATION = gql`
40+
mutation SubmitApplication($input: ApplicationSubmissionInput!) {
41+
submitApplication(input: $input) { id status }
3842
}
3943
`;
4044

41-
const APPLICATION_QUERY = gql`
42-
query Application($id: ID!) {
43-
application(id: $id) {
44-
id formId memberId status submittedAt approvedAt approvedBy updatedAt
45-
answers { id questionId value }
46-
}
45+
const CANCEL_APPLICATION = gql`
46+
mutation CancelApplication($id: ID!) {
47+
cancelApplication(id: $id) { id status }
4748
}
4849
`;
4950

50-
const SUBMIT_APPLICATION = gql`
51-
mutation SubmitApplication($input: SubmitInput!) {
52-
submitApplication(input: $input) {
53-
id formId status submittedAt
51+
const APPLICATIONS_QUERY = gql`
52+
query Applications($filter: ApplicationFilterInput) {
53+
applications(filter: $filter) {
54+
items { id applicantName applicantEmail track status submittedAt }
55+
total page size
5456
}
5557
}
5658
`;
5759

58-
const APPROVE_APPLICATIONS = gql`
59-
mutation ApproveApplications($ids: [ID!]!) {
60-
approveApplications(ids: $ids) {
61-
id status approvedAt
62-
}
60+
const APPROVE_APPLICATION = gql`
61+
mutation ApproveApplication($id: ID!) {
62+
approveApplication(id: $id) { id status }
6363
}
6464
`;
6565

66-
const CANCEL_APPLICATION = gql`
67-
mutation CancelApplication($id: ID!) {
68-
cancelApplication(id: $id) {
69-
id status
70-
}
66+
const BATCH_APPROVE = gql`
67+
mutation BatchApproveApplications($ids: [ID!]!) {
68+
batchApproveApplications(ids: $ids) { count }
7169
}
7270
`;
7371

74-
export async function getForm(id: string): Promise<Form> {
75-
const data = await gqlClient.request<{ form: Form }>(FORM_QUERY, { id });
76-
return data.form;
72+
export async function getMyApplication(): Promise<MyApplication | null> {
73+
const data = await gqlClient.request<{ myApplication: MyApplication | null }>(
74+
MY_APPLICATION_QUERY,
75+
);
76+
return data.myApplication;
7777
}
7878

79-
export async function getForms(recruitmentId: string): Promise<Form[]> {
80-
const data = await gqlClient.request<{ forms: Form[] }>(FORMS_QUERY, { recruitmentId });
81-
return data.forms;
79+
export async function getFormTemplate(type: string): Promise<FormTemplate> {
80+
const data = await gqlClient.request<{ formTemplate: FormTemplate }>(
81+
FORM_TEMPLATE_QUERY,
82+
{ type },
83+
);
84+
return data.formTemplate;
8285
}
8386

84-
export async function getMyApplications(): Promise<Application[]> {
85-
const data = await gqlClient.request<{ myApplications: Application[] }>(MY_APPLICATIONS_QUERY);
86-
return data.myApplications;
87+
export async function getRecruitmentPeriod(type: string): Promise<RecruitmentPeriod | null> {
88+
const data = await gqlClient.request<{ recruitmentPeriod: RecruitmentPeriod | null }>(
89+
RECRUITMENT_PERIOD_QUERY,
90+
{ type },
91+
);
92+
return data.recruitmentPeriod;
8793
}
8894

89-
export async function getApplications(formId: string): Promise<Application[]> {
90-
const data = await gqlClient.request<{ applications: Application[] }>(APPLICATIONS_QUERY, { formId });
91-
return data.applications;
95+
export async function submitApplication(input: ApplicationSubmission): Promise<MyApplication> {
96+
const data = await gqlClient.request<{ submitApplication: MyApplication }>(
97+
SUBMIT_APPLICATION,
98+
{ input },
99+
);
100+
return data.submitApplication;
92101
}
93102

94-
export async function getApplication(id: string): Promise<Application> {
95-
const data = await gqlClient.request<{ application: Application }>(APPLICATION_QUERY, { id });
96-
return data.application;
103+
export async function cancelApplication(id: string): Promise<MyApplication> {
104+
const data = await gqlClient.request<{ cancelApplication: MyApplication }>(
105+
CANCEL_APPLICATION,
106+
{ id },
107+
);
108+
return data.cancelApplication;
97109
}
98110

99-
export async function submitApplication(input: SubmitInput): Promise<Application> {
100-
const data = await gqlClient.request<{ submitApplication: Application }>(SUBMIT_APPLICATION, { input });
101-
return data.submitApplication;
111+
export async function getApplications(
112+
filter: Record<string, unknown>,
113+
): Promise<PagedResponse<ApplicationListItem>> {
114+
const data = await gqlClient.request<{ applications: PagedResponse<ApplicationListItem> }>(
115+
APPLICATIONS_QUERY,
116+
{ filter },
117+
);
118+
return data.applications;
102119
}
103120

104-
export async function approveApplications(ids: string[]): Promise<Application[]> {
105-
const data = await gqlClient.request<{ approveApplications: Application[] }>(APPROVE_APPLICATIONS, { ids });
106-
return data.approveApplications;
121+
export async function approveApplication(id: string): Promise<MyApplication> {
122+
const data = await gqlClient.request<{ approveApplication: MyApplication }>(
123+
APPROVE_APPLICATION,
124+
{ id },
125+
);
126+
return data.approveApplication;
107127
}
108128

109-
export async function cancelApplication(id: string): Promise<Application> {
110-
const data = await gqlClient.request<{ cancelApplication: Application }>(CANCEL_APPLICATION, { id });
111-
return data.cancelApplication;
129+
export async function batchApproveApplications(ids: string[]): Promise<{ count: number }> {
130+
const data = await gqlClient.request<{ batchApproveApplications: { count: number } }>(
131+
BATCH_APPROVE,
132+
{ ids },
133+
);
134+
return data.batchApproveApplications;
112135
}

src/components/common/DynamicForm.tsx

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,40 @@ import { Label } from "@/components/ui/label";
55
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
66
import { Checkbox } from "@/components/ui/checkbox";
77
import { Button } from "@/components/ui/button";
8-
import type { FormQuestion, AnswerInput } from "@/types/application";
8+
import {
9+
Select,
10+
SelectContent,
11+
SelectItem,
12+
SelectTrigger,
13+
SelectValue,
14+
} from "@/components/ui/select";
15+
import type { FormQuestion, ApplicationAnswer } from "@/types/application";
16+
17+
interface FixedFields {
18+
name: string;
19+
email: string;
20+
schoolEmail: string;
21+
track: string;
22+
}
923

1024
interface DynamicFormProps {
1125
questions: FormQuestion[];
12-
onSubmit: (answers: AnswerInput[]) => void;
26+
fixedFields: FixedFields;
27+
trackOptions: string[];
28+
onSubmit: (answers: ApplicationAnswer[], track: string) => void;
1329
isPending: boolean;
1430
submitLabel?: string;
1531
}
1632

1733
export function DynamicForm({
1834
questions,
35+
fixedFields,
36+
trackOptions,
1937
onSubmit,
2038
isPending,
2139
submitLabel = "제출",
2240
}: DynamicFormProps) {
41+
const [track, setTrack] = useState(fixedFields.track);
2342
const [answers, setAnswers] = useState<Record<string, string | string[]>>(() => {
2443
const init: Record<string, string | string[]> = {};
2544
for (const q of questions) {
@@ -28,7 +47,7 @@ export function DynamicForm({
2847
return init;
2948
});
3049

31-
const sorted = [...questions].sort((a, b) => a.sortOrder - b.sortOrder);
50+
const sorted = [...questions].sort((a, b) => a.order - b.order);
3251

3352
const setAnswer = (questionId: string, value: string | string[]) => {
3453
setAnswers((prev) => ({ ...prev, [questionId]: value }));
@@ -45,6 +64,7 @@ export function DynamicForm({
4564
};
4665

4766
const isValid = () => {
67+
if (!track) return false;
4868
for (const q of sorted) {
4969
if (!q.required) continue;
5070
const val = answers[q.id];
@@ -55,17 +75,44 @@ export function DynamicForm({
5575

5676
const handleSubmit = (e: React.FormEvent) => {
5777
e.preventDefault();
58-
const result: AnswerInput[] = sorted.map((q) => ({
78+
const result: ApplicationAnswer[] = sorted.map((q) => ({
5979
questionId: q.id,
60-
value: Array.isArray(answers[q.id])
61-
? (answers[q.id] as string[]).join(",")
62-
: (answers[q.id] as string),
80+
value: answers[q.id],
6381
}));
64-
onSubmit(result);
82+
onSubmit(result, track);
6583
};
6684

6785
return (
6886
<form onSubmit={handleSubmit} className="space-y-6">
87+
<div className="space-y-4 rounded-lg border p-4">
88+
<h3 className="text-sm font-medium text-muted-foreground">기본 정보</h3>
89+
<div className="space-y-2">
90+
<Label>이름</Label>
91+
<Input value={fixedFields.name} disabled className="bg-muted" />
92+
</div>
93+
<div className="space-y-2">
94+
<Label>이메일</Label>
95+
<Input value={fixedFields.email} disabled className="bg-muted" />
96+
</div>
97+
<div className="space-y-2">
98+
<Label>학교 이메일</Label>
99+
<Input value={fixedFields.schoolEmail} disabled className="bg-muted" />
100+
</div>
101+
<div className="space-y-2">
102+
<Label>희망 트랙</Label>
103+
<Select value={track} onValueChange={(v) => setTrack(v ?? "")}>
104+
<SelectTrigger>
105+
<SelectValue placeholder="트랙 선택" />
106+
</SelectTrigger>
107+
<SelectContent>
108+
{trackOptions.map((t) => (
109+
<SelectItem key={t} value={t}>{t}</SelectItem>
110+
))}
111+
</SelectContent>
112+
</Select>
113+
</div>
114+
</div>
115+
69116
{sorted.map((q) => (
70117
<div key={q.id} className="space-y-2">
71118
<Label>

0 commit comments

Comments
 (0)