Skip to content

Commit a8172d0

Browse files
ImTotemclaude
andcommitted
feat: 회원가입 프로필 단계에 학년 필드 추가
- GRADE_OPTIONS 상수 + isHighGrade 헬퍼 (src/lib/grade.ts) - ProfileStep에 학년 Select 추가 (필수) - RegisterRequest 타입에 grade 추가 - 위저드 상태 + reducer에 grade 반영 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 97bb215 commit a8172d0

4 files changed

Lines changed: 44 additions & 7 deletions

File tree

src/lib/grade.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export const GRADE_OPTIONS = [
2+
{ value: "1", label: "1학년" },
3+
{ value: "2", label: "2학년" },
4+
{ value: "3", label: "3학년" },
5+
{ value: "4", label: "4학년" },
6+
{ value: "grad", label: "대학원" },
7+
];
8+
9+
export function isHighGrade(grade: string): boolean {
10+
return ["3", "4", "grad"].includes(grade);
11+
}

src/pages/register/RegisterPage.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@ interface WizardState {
2525
department: string;
2626
studentId: string;
2727
phone: string;
28+
grade: string;
2829
schoolEmail: string;
2930
track: string;
3031
}
3132

3233
type WizardAction =
3334
| { type: "SET_GOOGLE"; googleToken: string; googleName: string }
34-
| { type: "SET_PROFILE"; name: string; department: string; studentId: string; phone: string }
35+
| { type: "SET_PROFILE"; name: string; department: string; studentId: string; phone: string; grade: string }
3536
| { type: "SET_EMAIL"; schoolEmail: string }
3637
| { type: "SET_TRACK"; track: string }
3738
| { type: "GO_BACK" };
@@ -57,7 +58,7 @@ function reducer(state: WizardState, action: WizardAction): WizardState {
5758
googleName: action.googleName,
5859
};
5960
case "SET_PROFILE":
60-
return { ...state, step: 3, name: action.name, department: action.department, studentId: action.studentId, phone: action.phone };
61+
return { ...state, step: 3, name: action.name, department: action.department, studentId: action.studentId, phone: action.phone, grade: action.grade };
6162
case "SET_EMAIL":
6263
return { ...state, step: 4, schoolEmail: action.schoolEmail };
6364
case "SET_TRACK":
@@ -82,6 +83,7 @@ export function RegisterPage() {
8283
department: "",
8384
studentId: "",
8485
phone: "",
86+
grade: "",
8587
schoolEmail: "",
8688
track: "",
8789
});
@@ -98,6 +100,7 @@ export function RegisterPage() {
98100
school_email: state.schoolEmail,
99101
phone: state.phone,
100102
track,
103+
grade: state.grade,
101104
});
102105
};
103106

@@ -131,8 +134,8 @@ export function RegisterPage() {
131134
<ProfileStep
132135
defaultName={state.name || state.googleName}
133136
onBack={() => dispatch({ type: "GO_BACK" })}
134-
onComplete={(name, department, studentId, phone) =>
135-
dispatch({ type: "SET_PROFILE", name, department, studentId, phone })
137+
onComplete={(name, department, studentId, phone, grade) =>
138+
dispatch({ type: "SET_PROFILE", name, department, studentId, phone, grade })
136139
}
137140
/>
138141
)}

src/pages/register/steps/ProfileStep.tsx

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,19 @@ import { ArrowLeft } from "lucide-react";
33
import { Button } from "@/components/ui/button";
44
import { Input } from "@/components/ui/input";
55
import { Label } from "@/components/ui/label";
6+
import {
7+
Select,
8+
SelectContent,
9+
SelectItem,
10+
SelectTrigger,
11+
SelectValue,
12+
} from "@/components/ui/select";
13+
import { GRADE_OPTIONS } from "@/lib/grade";
614

715
interface ProfileStepProps {
816
defaultName: string;
917
onBack: () => void;
10-
onComplete: (name: string, department: string, studentId: string, phone: string) => void;
18+
onComplete: (name: string, department: string, studentId: string, phone: string, grade: string) => void;
1119
}
1220

1321
function formatPhone(value: string): string {
@@ -21,6 +29,7 @@ export function ProfileStep({ defaultName, onBack, onComplete }: ProfileStepProp
2129
const [department, setDepartment] = useState("");
2230
const [studentId, setStudentId] = useState("");
2331
const [phone, setPhone] = useState("");
32+
const [grade, setGrade] = useState("");
2433

2534
return (
2635
<div className="space-y-4">
@@ -64,10 +73,23 @@ export function ProfileStep({ defaultName, onBack, onComplete }: ProfileStepProp
6473
onChange={(e) => setPhone(formatPhone(e.target.value))}
6574
/>
6675
</div>
76+
<div className="space-y-2">
77+
<Label>학년</Label>
78+
<Select value={grade} onValueChange={(v) => setGrade(v ?? "")}>
79+
<SelectTrigger>
80+
<SelectValue placeholder="학년 선택" />
81+
</SelectTrigger>
82+
<SelectContent>
83+
{GRADE_OPTIONS.map((opt) => (
84+
<SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>
85+
))}
86+
</SelectContent>
87+
</Select>
88+
</div>
6789
<Button
6890
className="w-full"
69-
onClick={() => onComplete(name, department, studentId, phone)}
70-
disabled={!name.trim() || !department.trim() || !studentId.trim() || phone.replace(/\D/g, "").length < 7}
91+
onClick={() => onComplete(name, department, studentId, phone, grade)}
92+
disabled={!name.trim() || !department.trim() || !studentId.trim() || phone.replace(/\D/g, "").length < 7 || !grade}
7193
>
7294
다음
7395
</Button>

src/types/auth.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export interface RegisterRequest {
4040
school_email: string;
4141
phone: string;
4242
track: string;
43+
grade: string;
4344
}
4445

4546
export interface MessageResponse {

0 commit comments

Comments
 (0)