Skip to content

Commit 8258c6d

Browse files
committed
feat(front): 로그인 기능 & 회원가입 기능 구현 완료
1 parent 598474f commit 8258c6d

File tree

4 files changed

+86
-21
lines changed

4 files changed

+86
-21
lines changed

front/src/app/(auth)/login/page.tsx

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
1010
import { Label } from '@/components/ui/label';
1111
import { Input } from '@/components/ui/input';
1212
import { Button } from '@/components/ui/Button';
13+
import Link from 'next/link';
14+
import { Github } from 'lucide-react';
1315

1416
export default function LoginPage() {
1517
const toast = useToast();
@@ -37,6 +39,10 @@ export default function LoginPage() {
3739
}
3840
}
3941

42+
const handleGithubLogin = () => {
43+
alert("아직 개발중!");
44+
};
45+
4046
return (
4147
<div className="min-h-screen bg-background">
4248
<div className="container mx-auto px-4 sm:px-6 lg:px-8 py-16">
@@ -48,7 +54,7 @@ export default function LoginPage() {
4854
<CardContent>
4955
<form className="space-y-6" onSubmit={submit}>
5056
<div className="space-y-2">
51-
<Label htmlFor="username">아이디</Label>
57+
<Label htmlFor="username">아이디/email</Label>
5258
<Input id="username" value={username} onChange={(e) => setUsername(e.target.value)} required />
5359
</div>
5460
<div className="space-y-2">
@@ -58,7 +64,22 @@ export default function LoginPage() {
5864
<Button type="submit" className="w-full" size="lg" disabled={loading}>
5965
{loading ? '처리중...' : '로그인'}
6066
</Button>
61-
<p className="text-xs text-muted-foreground">스프링 엔드포인트: POST /api/v1/auth/login</p>
67+
<Button
68+
type="button"
69+
variant="outline"
70+
className="w-full"
71+
size="lg"
72+
onClick={handleGithubLogin}
73+
>
74+
<Github className="mr-2 h-4 w-4" />
75+
Github으로 로그인하기
76+
</Button>
77+
<div className="text-center">
78+
<span className="text-sm text-muted-foreground">처음이신가요? </span>
79+
<Link href="/signup" className="text-sm text-primary hover:underline">
80+
회원가입하기
81+
</Link>
82+
</div>
6283
</form>
6384
</CardContent>
6485
</Card>

front/src/app/(auth)/signup/page.tsx

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,26 @@ import { Button } from '@/components/ui/Button';
1313
export default function SignupPage() {
1414
const toast = useToast();
1515
const router = useRouter();
16-
const [username, setUsername] = useState('');
1716
const [email, setEmail] = useState('');
17+
const [name, setName] = useState('');
1818
const [password, setPassword] = useState('');
19-
const [confirmPassword, setConfirmPassword] = useState('');
19+
const [passwordCheck, setPasswordCheck] = useState('');
20+
const [imageUrl, setImageUrl] = useState('');
2021
const [loading, setLoading] = useState(false);
2122

2223
async function submit(e: FormEvent) {
2324
e.preventDefault();
24-
if (password !== confirmPassword) {
25+
if (password !== passwordCheck) {
2526
toast.push('비밀번호가 일치하지 않습니다.');
2627
return;
2728
}
28-
const payload: SignupRequest = { username, email, password, confirmPassword };
29+
const payload: SignupRequest = {
30+
email,
31+
name,
32+
password,
33+
passwordCheck,
34+
imageUrl: imageUrl || undefined
35+
};
2936
try {
3037
setLoading(true);
3138
const res = await authApi.signup(payload);
@@ -49,25 +56,61 @@ export default function SignupPage() {
4956
<CardContent>
5057
<form className="space-y-6" onSubmit={submit}>
5158
<div className="space-y-2">
52-
<Label htmlFor="username">아이디</Label>
53-
<Input id="username" value={username} onChange={(e) => setUsername(e.target.value)} required />
59+
<Label htmlFor="email">이메일</Label>
60+
<Input
61+
id="email"
62+
type="email"
63+
value={email}
64+
onChange={(e) => setEmail(e.target.value)}
65+
placeholder="[email protected]"
66+
required
67+
/>
5468
</div>
5569
<div className="space-y-2">
56-
<Label htmlFor="email">이메일</Label>
57-
<Input id="email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} required />
70+
<Label htmlFor="name">이름</Label>
71+
<Input
72+
id="name"
73+
value={name}
74+
onChange={(e) => setName(e.target.value)}
75+
placeholder="사용할 이름을 입력하세요"
76+
required
77+
/>
5878
</div>
5979
<div className="space-y-2">
6080
<Label htmlFor="password">비밀번호</Label>
61-
<Input id="password" type="password" value={password} onChange={(e) => setPassword(e.target.value)} required />
81+
<Input
82+
id="password"
83+
type="password"
84+
value={password}
85+
onChange={(e) => setPassword(e.target.value)}
86+
placeholder="8자 이상 입력하세요"
87+
required
88+
/>
89+
</div>
90+
<div className="space-y-2">
91+
<Label htmlFor="passwordCheck">비밀번호 확인</Label>
92+
<Input
93+
id="passwordCheck"
94+
type="password"
95+
value={passwordCheck}
96+
onChange={(e) => setPasswordCheck(e.target.value)}
97+
placeholder="비밀번호를 다시 입력하세요"
98+
required
99+
/>
62100
</div>
63101
<div className="space-y-2">
64-
<Label htmlFor="confirmPassword">비밀번호 확인</Label>
65-
<Input id="confirmPassword" type="password" value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} required />
102+
<Label htmlFor="imageUrl">사진 주소 (선택사항)</Label>
103+
<Input
104+
id="imageUrl"
105+
type="url"
106+
value={imageUrl}
107+
onChange={(e) => setImageUrl(e.target.value)}
108+
placeholder="https://example.com/profile.jpg"
109+
/>
66110
</div>
67111
<Button type="submit" className="w-full" size="lg" disabled={loading}>
68112
{loading ? '처리중...' : '회원가입'}
69113
</Button>
70-
<p className="text-xs text-muted-foreground">스프링 엔드포인트: POST /api/v1/auth/signup</p>
71114
</form>
72115
</CardContent>
73116
</Card>

front/src/lib/api/auth.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ export const authApi = {
1212

1313
/**
1414
* 회원가입
15-
* POST /api/v1/auth/signup
15+
* POST /user
1616
*/
1717
signup: (data: SignupRequest): Promise<SignupResponse> =>
18-
http.post('/api/v1/auth/signup', data, 'none'),
18+
http.post('/user', data, 'none'),
1919

2020
/**
2121
* 로그아웃

front/src/types/auth.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
// auth 도메인 타입
22
export interface LoginRequest {
3-
username: string;
3+
username: string; // email 또는 username
44
password: string;
55
}
66

77
export interface SignupRequest {
8-
username: string;
98
email: string;
109
password: string;
11-
confirmPassword: string;
10+
passwordCheck: string;
11+
name: string;
12+
imageUrl?: string; // 선택사항
1213
}
1314

1415
export interface LoginResponse {
@@ -24,7 +25,7 @@ export interface SignupResponse {
2425

2526
export interface User {
2627
id: number;
27-
username: string;
2828
email: string;
29-
createdAt: string;
29+
name: string;
30+
imageUrl?: string;
3031
}

0 commit comments

Comments
 (0)