-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Feat/#65 로그인, 회원가입 API 연결
- Loading branch information
Showing
6 changed files
with
194 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
const API_BASE_URL = 'http://localhost:3000'; | ||
|
||
// 임시 토큰 발급 함수 | ||
const fetchToken = async () => { | ||
try { | ||
const response = await fetch(`${API_BASE_URL}/temp-token`, { | ||
method: 'POST', // POST 요청 | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify({ | ||
// 필요한 경우 바디 데이터를 추가 | ||
}), | ||
}); | ||
|
||
if (!response.ok) { | ||
throw new Error('Failed to fetch token'); | ||
} | ||
|
||
const data = await response.json(); | ||
return data.token; // 가져온 토큰을 반환 | ||
} catch (error) { | ||
console.error('Error fetching token:', error); | ||
throw error; | ||
} | ||
}; | ||
|
||
export const submitUserInfo = async (data, imageFile) => { | ||
const formData = new FormData(); | ||
|
||
// JSON 데이터를 문자열로 변환해서 추가 | ||
formData.append('data', JSON.stringify(data)); | ||
|
||
// 이미지 파일 추가 | ||
if (imageFile) { | ||
formData.append('image', imageFile); | ||
} | ||
|
||
try { | ||
// 임시 토큰 발급 | ||
const token = await fetchToken(); | ||
|
||
// 사용자 정보 제출 | ||
const response = await fetch(`${API_BASE_URL}/FITple/myprofile`, { | ||
method: 'POST', | ||
headers: { | ||
'Authorization': `Bearer ${token}`, | ||
}, | ||
body: formData, | ||
credentials: 'include', | ||
}); | ||
|
||
if (!response.ok) { | ||
if (response.status === 407) { | ||
console.error('이미 존재하는 닉네임입니다.'); | ||
} | ||
throw new Error(`Network response was not ok: ${response.status}`); | ||
} | ||
|
||
const responseData = await response.json(); | ||
console.log('submit User Info!'); | ||
console.log(responseData); | ||
|
||
return response; | ||
} catch (error) { | ||
console.error('Error:', error); | ||
throw error; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
const API_BASE_URL = 'http://localhost:3000'; | ||
|
||
export const signup = async (userData) => { | ||
try { | ||
const response = await fetch(`${API_BASE_URL}/FITple/signup`, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify(userData), | ||
}); | ||
|
||
const data = await response.json(); | ||
|
||
if (response.status === 200) { | ||
console.log(response.status); | ||
console.log(response.statusText); | ||
return data; | ||
} else { | ||
throw { status: response.status, message: data.message || '오류가 발생했습니다.' }; | ||
} | ||
} catch (error) { | ||
throw { status: error.status || 500, message: error.message || '서버 에러가 발생했습니다.' }; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { create } from 'zustand'; | ||
|
||
const useAuthStore = create((set) => ({ | ||
token: null, | ||
setToken: (newToken) => set({ token: newToken }), | ||
clearToken: () => set({ token: null }), | ||
})); | ||
|
||
export default useAuthStore; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
import logo from "../../../assets/Logo.svg"; | ||
import { useState } from "react"; | ||
import React, { useState } from "react"; | ||
import { useNavigate } from "react-router-dom"; | ||
import { signup } from "../../../data/SignupApi"; | ||
import logo from "../../../assets/Logo.svg"; | ||
import { | ||
SignupPageWrapper, | ||
FormWrapper, | ||
|
@@ -25,18 +26,12 @@ function SignupPage() { | |
const [pwError, setPwError] = useState("영어, 소문자, 숫자를 조합하여 입력해주세요."); | ||
const [pwConfirmError, setPwConfirmError] = useState(""); | ||
const [emailError, setEmailError] = useState(""); | ||
const [signupError, setSignupError] = useState(""); | ||
|
||
const handleIdChange = (e) => { | ||
const id = e.target.value; | ||
setLoginId(id); | ||
|
||
if (id === "umc") { | ||
setIdError("중복된 아이디입니다."); | ||
} else if (id) { | ||
setIdError("사용할 수 있는 아이디입니다."); | ||
} else { | ||
setIdError(" "); | ||
} | ||
setIdError(""); | ||
}; | ||
|
||
const handlePwChange = (e) => { | ||
|
@@ -47,7 +42,7 @@ function SignupPage() { | |
if (!pwRegex.test(pw)) { | ||
setPwError("영어 소문자, 숫자를 조합하여 8글자 이상 입력해주세요."); | ||
} else { | ||
setPwError(" "); | ||
setPwError(""); | ||
} | ||
}; | ||
|
||
|
@@ -58,74 +53,102 @@ function SignupPage() { | |
if (pwConfirm !== loginPw) { | ||
setPwConfirmError("입력한 비밀번호와 일치하지 않습니다."); | ||
} else { | ||
setPwConfirmError(" "); | ||
setPwConfirmError(""); | ||
} | ||
}; | ||
|
||
const handleEmailChange = (e) => { | ||
const email = e.target.value; | ||
setLoginEmail(email); | ||
|
||
if (email === "[email protected]") { | ||
setEmailError("이미 가입된 이메일입니다."); | ||
} else if (email) { | ||
setEmailError("사용할 수 있는 이메일입니다."); | ||
} else { | ||
setEmailError(" "); | ||
} | ||
setEmailError(""); | ||
}; | ||
|
||
const handleCheckboxChange = (event) => { | ||
setIsChecked(event.target.checked); | ||
}; | ||
|
||
const handleButtonClick = () => { | ||
navigate('/userinfo'); | ||
const handleSubmit = async () => { | ||
if (!loginId || !loginPw || !loginPwConfirm || !loginEmail) { | ||
setSignupError("모든 필드를 입력해주세요."); | ||
return; | ||
} | ||
if (loginPw !== loginPwConfirm) { | ||
setSignupError("비밀번호가 일치하지 않습니다."); | ||
return; | ||
} | ||
|
||
try { | ||
const userData = { | ||
user_id: loginId, | ||
password: loginPw, | ||
email: loginEmail, | ||
}; | ||
|
||
const result = await signup(userData); | ||
console.log("--------------"); | ||
console.log(result); | ||
|
||
if (result.code === 200) { | ||
setIdError("사용 가능한 아이디입니다."); | ||
alert("회원 가입 성공!"); | ||
navigate("/userinfo"); | ||
} else if (result.code === 'SIGNUP001') { | ||
setIdError("이미 존재하는 아이디입니다."); | ||
} | ||
} catch (error) { | ||
if (error.status === 401) { | ||
setIdError("중복된 아이디입니다."); | ||
} else { | ||
setSignupError( | ||
error.message || "알 수 없는 오류가 발생했습니다." | ||
); | ||
} | ||
} | ||
}; | ||
|
||
return ( | ||
<SignupPageWrapper> | ||
<img width="50px" src={logo} alt="FITple Logo" /> | ||
<FormWrapper> | ||
<InputText>아이디</InputText> | ||
<InputBox | ||
type="text" | ||
id="login-id" | ||
<InputBox | ||
type="text" | ||
id="login-id" | ||
value={loginId} | ||
onChange={handleIdChange} | ||
placeholder="" | ||
placeholder="" | ||
/> | ||
<ErrorText isError={idError.includes("중복된")}>{idError}</ErrorText> | ||
<ErrorText isError={!!idError}>{idError}</ErrorText> | ||
|
||
<InputText>비밀번호</InputText> | ||
<InputBox | ||
type="password" | ||
id="login-pw" | ||
<InputBox | ||
type="password" | ||
id="login-pw" | ||
value={loginPw} | ||
onChange={handlePwChange} | ||
placeholder="" | ||
placeholder="" | ||
/> | ||
<ErrorText isError={!!pwError}>{pwError}</ErrorText> | ||
|
||
<InputText>비밀번호 확인</InputText> | ||
<InputBox | ||
type="password" | ||
id="login-pw2" | ||
<InputBox | ||
type="password" | ||
id="login-pw2" | ||
value={loginPwConfirm} | ||
onChange={handlePwConfirmChange} | ||
placeholder="" | ||
placeholder="" | ||
/> | ||
<ErrorText isError={!!pwConfirmError}>{pwConfirmError}</ErrorText> | ||
|
||
<InputText>이메일</InputText> | ||
<InputBox | ||
type="email" | ||
id="login-email" | ||
<InputBox | ||
type="email" | ||
id="login-email" | ||
value={loginEmail} | ||
onChange={handleEmailChange} | ||
placeholder="" | ||
placeholder="" | ||
/> | ||
<ErrorText isError={emailError.includes("가입된")}>{emailError}</ErrorText> | ||
<ErrorText isError={!!emailError}>{emailError}</ErrorText> | ||
|
||
<InputText>이메일 마케팅 정보 수신 동의</InputText> | ||
<CheckboxContainer> | ||
|
@@ -143,7 +166,8 @@ function SignupPage() { | |
<CheckboxLabel>동의하지 않음</CheckboxLabel> | ||
</CheckboxContainer> | ||
|
||
<SubmitButton onClick={handleButtonClick}>회원정보 작성하기</SubmitButton> | ||
<SubmitButton onClick={handleSubmit}>회원정보 작성하기</SubmitButton> | ||
{signupError && <ErrorText isError={true}>{signupError}</ErrorText>} | ||
</FormWrapper> | ||
</SignupPageWrapper> | ||
); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters