Skip to content

Commit 9d3acae

Browse files
committed
Merge remote-tracking branch 'origin/sunwoong'
2 parents df1c006 + cc56693 commit 9d3acae

4 files changed

Lines changed: 171 additions & 16 deletions

File tree

src/components/login/Login.jsx

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,61 @@
1-
// src/components/Login.jsx
2-
import React from 'react';
3-
import './Login.css'; // CSS 파일 import
1+
import React, { useState } from 'react';
2+
import axios from 'axios';
3+
import config from '../../config';
4+
import './Login.css';
45

56
function Login() {
7+
const [formData, setFormData] = useState({
8+
username: '',
9+
password: '',
10+
});
11+
12+
const handleChange = (e) => {
13+
setFormData({
14+
...formData,
15+
[e.target.id]: e.target.value,
16+
});
17+
};
18+
19+
const handleSubmit = async (e) => {
20+
e.preventDefault();
21+
22+
try {
23+
const response = await axios.post(`${config.API_BASE_URL}/api/users/login`, {
24+
userId: formData.username,
25+
password: formData.password,
26+
});
27+
28+
const { token, name, role, userId } = response.data;
29+
30+
console.log('✅ 로그인 성공:', response.data);
31+
32+
localStorage.setItem('token', token);
33+
localStorage.setItem('username', name);
34+
localStorage.setItem('userId', userId);
35+
localStorage.setItem('role', role);
36+
37+
alert('로그인 성공!');
38+
// window.location.href = '/'; // 필요한 경우 이동
39+
} catch (error) {
40+
console.error('❌ 로그인 실패:', error.response?.data || error.message);
41+
alert(error.response?.data?.message || '로그인에 실패했습니다.');
42+
}
43+
};
44+
645
return (
746
<div className="login-container">
847
<div className="login-box">
948
<h1 className="login-title">로그인</h1>
1049
<p className="login-subtitle">계정에 로그인하여 CodeViz를 시작하세요</p>
11-
<form className="login-form">
50+
51+
<form className="login-form" onSubmit={handleSubmit}>
1252
<label htmlFor="username">아이디</label>
1353
<input
1454
id="username"
1555
type="text"
1656
placeholder="사용자 아이디 입력"
57+
value={formData.username}
58+
onChange={handleChange}
1759
required
1860
/>
1961
<div className="password-container">
@@ -24,14 +66,19 @@ function Login() {
2466
id="password"
2567
type="password"
2668
placeholder="••••••••"
69+
value={formData.password}
70+
onChange={handleChange}
2771
required
2872
/>
73+
2974
<div className="remember-me">
3075
<input type="checkbox" id="remember" />
3176
<label htmlFor="remember">로그인 상태 유지</label>
3277
</div>
78+
3379
<button type="submit">로그인</button>
3480
</form>
81+
3582
<div className="divider">또는 소셜 계정으로 로그인</div>
3683
<div className="social-buttons">
3784
<button disabled>Google</button>

src/components/signup/SignUp.jsx

Lines changed: 92 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,120 @@
1-
// src/components/SignUp.jsx
2-
import React from 'react';
3-
import '../login/Login.css'; // 로그인과 같은 스타일 사용
1+
import React, { useState } from 'react';
2+
import axios from 'axios';
3+
import config from '../../config';
4+
5+
import '../login/Login.css';
46

57
function SignUp() {
8+
const [formData, setFormData] = useState({
9+
username: '',
10+
email: '',
11+
password: '',
12+
confirmPassword: '',
13+
name: '',
14+
});
15+
16+
const handleChange = (e) => {
17+
setFormData({
18+
...formData,
19+
[e.target.id]: e.target.value,
20+
});
21+
};
22+
23+
const handleSubmit = async (e) => {
24+
e.preventDefault();
25+
26+
if (formData.password !== formData.confirmPassword) {
27+
alert('비밀번호가 일치하지 않습니다.');
28+
return;
29+
}
30+
31+
try {
32+
const response = await axios.post(`${config.API_BASE_URL}/api/users/signup`, {
33+
userId: formData.username,
34+
email: formData.email,
35+
password: formData.password,
36+
name: formData.name,
37+
});
38+
39+
console.log('회원가입 성공:', response.data);
40+
alert('회원가입이 완료되었습니다!');
41+
} catch (error) {
42+
console.error('회원가입 오류:', error.response?.data || error.message);
43+
alert(error.response?.data?.message || '회원가입에 실패했습니다.');
44+
}
45+
};
46+
647
return (
748
<div className="login-container">
849
<div className="login-box">
950
<h1 className="login-title">회원가입</h1>
1051
<p className="login-subtitle">CodeViz 계정을 만들고 코드 시각화를 시작하세요</p>
1152

12-
<form className="login-form">
53+
<form className="login-form" onSubmit={handleSubmit}>
1354
<label htmlFor="username">아이디 *</label>
14-
<input id="username" type="text" placeholder="사용할 아이디 입력" required />
55+
<input
56+
id="username"
57+
type="text"
58+
placeholder="사용할 아이디 입력"
59+
value={formData.username}
60+
onChange={handleChange}
61+
required
62+
/>
1563

1664
<label htmlFor="email">이메일 *</label>
17-
<input id="email" type="email" placeholder="name@example.com" required />
65+
<input
66+
id="email"
67+
type="email"
68+
placeholder="name@example.com"
69+
value={formData.email}
70+
onChange={handleChange}
71+
required
72+
/>
1873
<small>인증번호를 받을 이메일 주소를 입력해주세요.</small>
1974

2075
<label htmlFor="password">비밀번호 *</label>
21-
<input id="password" type="password" required />
76+
<input
77+
id="password"
78+
type="password"
79+
value={formData.password}
80+
onChange={handleChange}
81+
required
82+
/>
2283
<small>비밀번호는 8자 이상이어야 합니다.</small>
2384

24-
<label htmlFor="confirm-password">비밀번호 확인 *</label>
25-
<input id="confirm-password" type="password" required />
85+
<label htmlFor="confirmPassword">비밀번호 확인 *</label>
86+
<input
87+
id="confirmPassword"
88+
type="password"
89+
value={formData.confirmPassword}
90+
onChange={handleChange}
91+
required
92+
/>
2693

2794
<label htmlFor="name">이름 *</label>
28-
<input id="name" type="text" placeholder="홍길동" required />
95+
<input
96+
id="name"
97+
type="text"
98+
placeholder="홍길동"
99+
value={formData.name}
100+
onChange={handleChange}
101+
required
102+
/>
29103

30104
<div className="remember-me">
31105
<input type="checkbox" id="terms" required />
32-
<label htmlFor="terms"><strong>이용약관에 동의합니다.</strong><br />이용약관을 읽고 동의합니다.</label>
106+
<label htmlFor="terms">
107+
<strong>이용약관에 동의합니다.</strong><br />
108+
이용약관을 읽고 동의합니다.
109+
</label>
33110
</div>
34111

35112
<div className="remember-me">
36113
<input type="checkbox" id="privacy" required />
37-
<label htmlFor="privacy"><strong>개인정보 처리방침에 동의합니다.</strong><br />개인정보 처리방침을 확인 후 동의합니다.</label>
114+
<label htmlFor="privacy">
115+
<strong>개인정보 처리방침에 동의합니다.</strong><br />
116+
개인정보 처리방침을 확인 후 동의합니다.
117+
</label>
38118
</div>
39119

40120
<button type="submit">회원가입 완료</button>

src/config.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// 개발 환경에서는 프록시를 통해 우회해야 하므로 ''로 설정
2+
const isDev = process.env.NODE_ENV === 'development';
3+
4+
const config = {
5+
API_BASE_URL: isDev ? '' : 'http://3.38.244.234:8080',
6+
};
7+
8+
export default config;
9+
10+
11+
// 아래는 프록시 코드를 제거하면 활성화 후 위 코드들 지우기
12+
//const config = {
13+
//API_BASE_URL: 'http://3.38.244.234:8080', // 절대경로로 고정
14+
//};
15+
16+
// default config;

src/setupProxy.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// src/setupProxy.js
2+
const { createProxyMiddleware } = require('http-proxy-middleware');
3+
4+
module.exports = function (app) {
5+
app.use(
6+
'/api',
7+
createProxyMiddleware({
8+
target: 'http://3.38.244.234:8080',
9+
changeOrigin: true,
10+
})
11+
);
12+
};

0 commit comments

Comments
 (0)