Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ 카카오 회원가입 추가 정보 입력 #52

Merged
merged 2 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/api/useGetCourse.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// useGetCourse.jsx
import { useState, useEffect } from "react";
import api from "../api/config";

export const useGetCourse = () => {
const [courses, setCourses] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);

useEffect(() => {
const fetchCourses = async () => {
setIsLoading(true);
try {
const response = await api.get("/api/v1/members/course");
setCourses(response.data.courses);
setError(null);
} catch (error) {
console.error("Error fetching courses:", error);
setError("코스 목록을 불러오는데 실패했습니다.");
setCourses([]);
} finally {
setIsLoading(false);
}
};

fetchCourses();
}, []);

return { courses, isLoading, error };
};
32 changes: 32 additions & 0 deletions src/api/usePatchMember.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// usePatchMember.jsx
import { useState } from "react";
import api from "../api/config";

export const usePatchMember = () => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);

const updateMember = async (memberId, memberData) => {
setIsLoading(true);
setError(null);

try {
const response = await api.patch(`/api/v1/members/${memberId}`, {
name: memberData.memberName,
nameEnglish: memberData.memberNameEnglish,
course: memberData.course,
});

return response.data;
} catch (err) {
setError(
err.response?.data?.message || "회원 정보 수정 중 오류가 발생했습니다."
);
throw err;
} finally {
setIsLoading(false);
}
};

return { updateMember, isLoading, error };
};
55 changes: 24 additions & 31 deletions src/containers/LoginHandler.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,55 +22,48 @@ export default function KakaoLogin() {

const response = await api.get(
`/api/v1/auth/login/oauth2/callback/kakao`,
{
params: { code },
}
{ params: { code } }
);

console.log("Full response:", response);
console.log("Response status:", response.status);
console.log("Response headers:", response.headers);
console.log("Response data:", response.data);

const data = response.data;

// 서버 에러 응답 상세 로깅
if (data.code === "COM_001" || data.status === 500) {
console.error("Server Error Details:", {
code: data.code,
status: data.status,
message: data.message,
fullData: data,
});
throw new Error(
"로그인 처리 중 문제가 발생했습니다. 잠시 후 다시 시도해주세요.\n" +
(data.message || "알 수 없는 오류가 발생했습니다.")
);
}

if (data.token && data.token.accessToken) {
// 서버 응답에서 memberId와 kakaoId, nickname 추출
if (
data.memberId &&
data.kakaoId &&
data.nickname &&
data.token.accessToken
) {
console.log("Login successful, storing tokens and user info");

// 토큰 및 사용자 정보 저장
localStorage.setItem("accessToken", data.token.accessToken);
if (data.id) localStorage.setItem("userId", data.id);
if (data.nickname) localStorage.setItem("nickname", data.nickname);
localStorage.setItem("userId", data.memberId); // memberId를 userId로 저장
localStorage.setItem("kakaoId", data.kakaoId); // kakaoId 저장
localStorage.setItem("nickname", data.nickname); // nickname 저장

console.log("Stored data in localStorage:", {
userId: localStorage.getItem("userId"),
kakaoId: localStorage.getItem("kakaoId"),
nickname: localStorage.getItem("nickname"),
});

if (data.isRegistered) {
// 이미 회원가입된 사용자의 경우, 메인 페이지로 이동
window.location.href = "/mainpage";
window.location.href = "/mainpage"; // 이미 등록된 사용자
} else {
// 회원가입이 안 된 사용자의 경우, 추가 정보 입력 페이지로 이동
window.location.href = "/kakaosignup";
setTimeout(() => {
window.location.href = "/kakaosignup"; // 등록되지 않은 사용자
}, 5000);
}
} else {
console.error("Missing access token in response:", data);
console.error("Missing required fields in response:", data);
throw new Error("로그인 정보가 올바르지 않습니다.");
}
} catch (error) {
console.error("Detailed error information:", {
message: error.message,
responseData: error.response?.data,
responseStatus: error.response?.status,
responseHeaders: error.response?.headers,
originalError: error,
errorStack: error.stack,
});
Expand Down
168 changes: 84 additions & 84 deletions src/containers/SignupForm_kakao.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,33 @@ import Sidebar from "./SideForm";
import Button from "../component/Button";
import Input from "../component/Input";
import Select from "../component/Select";
import ProfileUpload from "../component/ProfileUpload";
import api from "../api/config"; // api instance 사용
import api from "../api/config";
import "./styles/SignupForm.scss";
import { useGetCourse } from "../api/useGetCourse";

const SignupForm_kakao = () => {
const navigate = useNavigate();
const {
courses,
isLoading: coursesLoading,
error: coursesError,
} = useGetCourse();

const [formData, setFormData] = useState({
memberName: "",
memberNameEnglish: "",
member_name: "",
member_name_english: "",
course: "",
role: "",
profileImage: null,
});
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);

useEffect(() => {
// 카카오 데이터 불러오기
const tempUserData = JSON.parse(
localStorage.getItem("tempUserData") || "{}"
);
if (tempUserData.nickname) {
// localStorage에서 사용자 기본 정보 가져오기
const nickname = localStorage.getItem("nickname");
if (nickname) {
setFormData((prev) => ({
...prev,
memberName: tempUserData.nickname,
}));
}
if (tempUserData.profileImage) {
setFormData((prev) => ({
...prev,
profileImage: tempUserData.profileImage,
member_name: nickname,
}));
}
}, []);
Expand All @@ -54,70 +50,86 @@ const SignupForm_kakao = () => {
}));
};

const handleRoleChange = (e) => {
setFormData((prev) => ({
...prev,
role: e.target.value,
}));
};

const handleProfileUpload = (imageData) => {
setFormData((prev) => ({
...prev,
profileImage: imageData,
}));
};

const handleSubmit = async () => {
try {
setIsLoading(true);
setError(null);

// 입력값 검증
if (
!formData.memberName ||
!formData.memberNameEnglish ||
!formData.course ||
!formData.role
!formData.member_name ||
!formData.member_name_english ||
!formData.course
) {
throw new Error("모든 필드를 입력해주세요.");
}

const tempUserData = JSON.parse(
localStorage.getItem("tempUserData") || "{}"
);
// localStorage에서 memberId 가져오기
const memberId = localStorage.getItem("userId");
console.log("Current memberId:", memberId); // 디버깅용

if (!memberId) {
throw new Error("회원 정보를 찾을 수 없습니다.");
}

const response = await api.post("/kakaosignup", {
kakaoId: tempUserData.kakaoId,
memberName: formData.memberName,
memberNameEnglish: formData.memberNameEnglish,
// API 명세에 맞게 회원 정보 업데이트
const response = await api.patch(`/api/v1/members/${memberId}`, {
name: formData.member_name,
nameEnglish: formData.member_name_english,
course: formData.course,
role: formData.role,
profileImage: formData.profileImage,
});

if (response.data.accessToken) {
localStorage.setItem("accessToken", response.data.accessToken);
if (response.data.refreshToken) {
localStorage.setItem("refreshToken", response.data.refreshToken);
}

localStorage.removeItem("tempUserData");
navigate("/mainpage");
} else {
throw new Error("회원가입 처리 중 오류가 발생했습니다.");
if (response.data) {
// 응답 데이터 저장
const memberInfo = {
id: response.data.id,
role: response.data.role,
course: response.data.course,
name: response.data.name,
nameEnglish: response.data.nameEnglish,
};

// localStorage에 업데이트된 정보 저장
localStorage.setItem("memberInfo", JSON.stringify(memberInfo));

// 메인 페이지로 이동
navigate("/mainpage", {
state: { memberInfo },
});
}
} catch (err) {
console.error("Signup error:", err);
setError(err.response?.data?.message || err.message);
console.error("Update error:", err);
const errorMessage = err.response?.data?.message || err.message;
setError(errorMessage);
console.log("Detailed error:", {
error: err,
response: err.response,
data: err.response?.data,
currentUserId: localStorage.getItem("userId"), // 현재 저장된 userId 확인
allStorage: {
// 모든 localStorage 데이터 확인
userId: localStorage.getItem("userId"),
nickname: localStorage.getItem("nickname"),
accessToken: localStorage.getItem("accessToken"),
},
});
} finally {
setIsLoading(false);
}
};

const handleLogin = () => {
navigate("/login");
};
const courseOptions = courses.map((course) => {
switch (course) {
case "풀스택":
return "FULLSTACK";
case "클라우드":
return "CLOUD";
case "인공지능":
return "AI";
default:
return course;
}
});

return (
<div className="start-container">
Expand All @@ -126,50 +138,38 @@ const SignupForm_kakao = () => {
</div>
<div className="content-wrapper">
<div className="signup-area">
<ProfileUpload
initialImage={formData.profileImage}
onImageUpload={handleProfileUpload}
/>

<Input
type="text"
name="memberName"
value={formData.memberName}
name="member_name"
value={formData.member_name}
onChange={handleInputChange}
placeholder="이름(한글)"
/>

<Input
type="text"
name="memberNameEnglish"
value={formData.memberNameEnglish}
name="member_name_english"
value={formData.member_name_english}
onChange={handleInputChange}
placeholder="이름(영문)"
/>

<Select
options={["풀스택", "클라우드", "인공지능"]}
options={courseOptions}
onChange={handleCourseChange}
placeholder="분야 선택"
placeholder={coursesLoading ? "로딩 중..." : "분야 선택"}
disabled={coursesLoading}
/>

<Select
options={["STUDENT", "MANAGER"]}
onChange={handleRoleChange}
placeholder="역할 선택"
/>

{error && <p className="error-message">{error}</p>}
{(error || coursesError) && (
<p className="error-message">{error || coursesError}</p>
)}

<Button
text={isLoading ? "처리중..." : "회원가입"}
text={isLoading ? "처리중..." : "정보 입력"}
onClick={handleSubmit}
disabled={isLoading}
disabled={isLoading || coursesLoading}
/>

<p className="re-login" onClick={handleLogin}>
아이디로 로그인
</p>
</div>
</div>
</div>
Expand Down