diff --git a/src/App.js b/src/App.js
index e8d3380..7a98a38 100644
--- a/src/App.js
+++ b/src/App.js
@@ -9,6 +9,7 @@ import PostEditPage from "./routes/PostEditPage";
import SignUpPage from "./routes/SignUpPage";
import PostDetailPage from "./routes/PostDetailPage";
import SignInPage from "./routes/SignInPage";
+import MyPage from "./routes/MyPage";
function App() {
return (
@@ -28,6 +29,7 @@ function App() {
} />
{/* sign up */}
} />
+ } />
diff --git a/src/apis/api.js b/src/apis/api.js
index be2d366..2f7af3b 100644
--- a/src/apis/api.js
+++ b/src/apis/api.js
@@ -1,4 +1,5 @@
import { instance, instanceWithToken } from "./axios";
+import { removeCookie } from "../utils/cookie";
// Account 관련 API들
export const signIn = async (data) => {
@@ -135,9 +136,45 @@ export const deleteComment = async (id) => {
const response = await instanceWithToken.delete(`/comment/${id}/`);
if (response.status === 204) {
console.log("DELETE COMMENT SUCCESS");
- window.location.reload();
+ // window.location.reload();
} else {
console.log("[ERROR] error while removing comment");
}
}
};
+
+
+export const updateInfo = async (data) => {
+ const response = await instanceWithToken.patch("/account/info/", data);
+ if (response.status === 200) {
+ console.log("INFO UPDATE SUCCESS");
+ window.location.reload();
+ } else {
+ console.log("[ERROR] error while updating info");
+ }
+};
+
+export const refreshToken = async (token) => {
+ const response = await instance.post("/account/refresh/", { refresh: token });
+ if (response.status === 200) {
+ console.log("REFRESH TOKEN SUCCESS");
+ } else {
+ console.log("[ERROR] error while refreshing token");
+ }
+};
+
+export const logOut = async (token) => {
+ const response = await instanceWithToken.post("/account/logout/", {
+ refresh: token,
+ });
+ if (response.status === 204) {
+ console.log("REFRESH TOKEN SUCCESS");
+
+ removeCookie("refresh_token");
+ removeCookie("access_token");
+
+ window.location.reload();
+ } else {
+ console.log("[ERROR] error while refreshing token");
+ }
+};
\ No newline at end of file
diff --git a/src/apis/axios.js b/src/apis/axios.js
index e50f3a1..711f79a 100644
--- a/src/apis/axios.js
+++ b/src/apis/axios.js
@@ -1,5 +1,6 @@
import axios from "axios";
-import { getCookie } from "../utils/cookie";
+import { getCookie, removeCookie } from "../utils/cookie";
+import { refreshToken } from "./api";
// baseURL, credential, 헤더 세팅
axios.defaults.baseURL = 'http://localhost:8000/api';
@@ -39,16 +40,24 @@ instanceWithToken.interceptors.request.use(
}
);
+
+
instanceWithToken.interceptors.response.use(
(response) => {
- // 서버 응답 데이터를 프론트에 넘겨주기 전 수행할 일
console.log("Interceptor Response!!");
return response;
},
- (error) => {
- // 서버가 오류를 응답했을 때 처리 - 콘솔 찍어주고, 프론트에게 보내지 않고 오류를 발생시킴
+ async (error) => {
console.log("Response Error!!");
- console.log(error);
+
+ const originalRequest = error.config;
+ if (error.response.status === 401) { //토큰이 만료됨에 따른 에러인지 확인
+ const token = getCookie("refresh_token");
+ await refreshToken(token); //refresh token 을 활용하여 access token 을 refresh
+
+ return instanceWithToken(originalRequest); //refresh된 access token 을 활용하여 재요청 보내기
+ }
return Promise.reject(error);
}
-);
\ No newline at end of file
+);
+
diff --git a/src/components/Comment/CommentElement.jsx b/src/components/Comment/CommentElement.jsx
index 290477d..3566704 100644
--- a/src/components/Comment/CommentElement.jsx
+++ b/src/components/Comment/CommentElement.jsx
@@ -17,7 +17,7 @@ export const CommentElement = (props) => {
day = day < 10 ? `0${day}` : day;
// 추가
- const handleEditComment = (e) => {
+ const handleEditComment = () => {
updateComment(comment.id, { content: content });
};
// updateComment 활용
diff --git a/src/components/Header/index.jsx b/src/components/Header/index.jsx
index a11e2c3..b76d6a9 100644
--- a/src/components/Header/index.jsx
+++ b/src/components/Header/index.jsx
@@ -1,7 +1,9 @@
import { Link } from "react-router-dom";
import lion from "../../assets/images/lion.jpeg";
-import { getCookie, removeCookie } from "../../utils/cookie";
+import { getCookie } from "../../utils/cookie";
import { useEffect, useState } from "react";
+import { logOut } from "../../apis/api";
+
const Header = () => {
const [isLoggedIn, setIsLoggedIn] = useState("");
@@ -14,9 +16,8 @@ const Header = () => {
// getCookie를 통해 access token을 가져올 수 있으면 로그인 된 것으로 설정
const handleLogout = () => {
- removeCookie("access_token");
- removeCookie("refresh_token");
- window.location.href = "/"; // 새로고침 - 로그아웃 되었다는 것을 인지시켜주기 위해
+ const token = getCookie("refresh_token");
+ logOut(token);
};
return (
@@ -42,6 +43,9 @@ const Header = () => {
>
) : (
<>
+
+ MY PAGE
+
log out
diff --git a/src/components/Info/InfoElement.jsx b/src/components/Info/InfoElement.jsx
new file mode 100644
index 0000000..26ea3bc
--- /dev/null
+++ b/src/components/Info/InfoElement.jsx
@@ -0,0 +1,58 @@
+import { useEffect, useState } from "react";
+import { updateInfo } from "../../apis/api";
+
+export const InfoElement = (props) => {
+ const { infoLabel, infoContent } = props;
+ const [content, setContent] = useState(infoContent);
+ const [isEdit, setIsEdit] = useState(false);
+
+ const handleEditInfo = (e) => {
+ e.preventDefault();
+ updateInfo({ [infoLabel]: content });
+ setContent(infoContent);
+ };
+
+ useEffect(() => {
+ setContent(infoContent);
+ }, [infoContent]);
+
+ return (
+
+
{infoLabel}:
+
+
+ {isEdit ? (
+
+
setContent(e.target.value)}
+ />
+
+
+
+
+
+ ) : (
+
+
{infoContent}
+
+
+ )}
+
+
+
+ );
+};
diff --git a/src/routes/MyPage.jsx b/src/routes/MyPage.jsx
new file mode 100644
index 0000000..2649561
--- /dev/null
+++ b/src/routes/MyPage.jsx
@@ -0,0 +1,60 @@
+import { useState, useEffect } from "react";
+import { InfoElement } from "../components/Info/InfoElement";
+import { getUser, getPosts } from "../apis/api";
+import { SmallPost } from "../components/Posts";
+
+const MyPage = () => {
+ const [email, setEmail] = useState("");
+ const [username, setUsername] = useState("");
+ const [college, setCollege] = useState("");
+ const [major, setMajor] = useState("");
+ const [postList, setPostList] = useState([]);
+ const [user, setUser] = useState(null);
+
+ useEffect(() => {
+ const getPostsAPI = async () => {
+ const posts = await getPosts();
+ setPostList(posts);
+ console.log(posts);
+ };
+ getPostsAPI();
+ }, []);
+
+
+ useEffect(() => {
+ const getInfoAPI = async () => {
+ const info = await getUser();
+ setEmail(info.user.email);
+ setUsername(info.user.username);
+ setCollege(info.college);
+ setMajor(info.major);
+ setUser(info.user);
+ };
+ getInfoAPI();
+ }, []);
+
+ return (
+ <>
+
+
My Info
+
+
+
+
+
+
+
My Posts
+
+ {postList.filter((post) => post?.author.id === user?.id
+ ).map((post) => (
+
+ ))}
+
+
+
+
+ >
+ );
+};
+
+export default MyPage;
diff --git a/src/routes/PostDetailPage.jsx b/src/routes/PostDetailPage.jsx
index d6b0ead..969a736 100644
--- a/src/routes/PostDetailPage.jsx
+++ b/src/routes/PostDetailPage.jsx
@@ -30,7 +30,7 @@ const PostDetailPage = () => {
if (getCookie("access_token")) {
const getUserAPI = async () => {
const user = await getUser();
- setUser(user);
+ setUser(user.user);
};
getUserAPI();
}
@@ -40,7 +40,8 @@ const PostDetailPage = () => {
const navigate = useNavigate();
const onClickDelete = () => {
deletePost(postId, navigate);
- };
+ };
+
return (
post && (