From 3b48c15a036d1156ca4ecb3b58be0348faf34b75 Mon Sep 17 00:00:00 2001 From: Darkthos Date: Tue, 11 Jun 2024 14:57:07 +0900 Subject: [PATCH 1/8] fix(token, Link) --- src/pages/addboard/index.tsx | 4 ++-- src/pages/boards/[id].tsx | 6 +++--- src/utils/localStorageToken.ts | 7 ++++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/pages/addboard/index.tsx b/src/pages/addboard/index.tsx index 7c0ce680b..b63ac17d6 100644 --- a/src/pages/addboard/index.tsx +++ b/src/pages/addboard/index.tsx @@ -4,7 +4,7 @@ import Form from "@/components/addBoardComponents/Form"; import FormTitle from "@/components/addBoardComponents/FormTitle"; import Header from "@/components/shared/Header/Header"; import { css } from "@/styled-system/css"; -import { AccessTokenTOLocalStorage } from "@/utils/localStorageToken"; +import { AccessTokenToLocalStorage } from "@/utils/localStorageToken"; import { useRouter } from "next/router"; import React, { useState } from "react"; @@ -46,7 +46,7 @@ function AddBoard() { const handleSubmit = async () => { if (!isValid) return; - const token = await AccessTokenTOLocalStorage(); + const token = await AccessTokenToLocalStorage(); await postArticles(postData, token); router.push("/boards"); }; diff --git a/src/pages/boards/[id].tsx b/src/pages/boards/[id].tsx index 627106d7f..219089524 100644 --- a/src/pages/boards/[id].tsx +++ b/src/pages/boards/[id].tsx @@ -21,7 +21,7 @@ import postArticlesComment from "@/apis/comment/postArticlesIdComment"; import { ParsedUrlQuery } from "querystring"; import { boardIdPageStyle, flexStyle } from "@/css/boardsId.styled"; import PostRefreshToken from "@/apis/auth/PostRefreshToken"; -import { AccessTokenTOLocalStorage } from "@/utils/localStorageToken"; +import { AccessTokenToLocalStorage } from "@/utils/localStorageToken"; function BoardDetail() { const router = useRouter(); @@ -38,7 +38,7 @@ function BoardDetail() { const handleSubmit = async () => { if (typeof id !== "string") return; - const token = await AccessTokenTOLocalStorage(); + const token = await AccessTokenToLocalStorage(); setCommentData(""); await postArticlesComment(commentData, id, token); setIsChangeComments(!isChangeComments); @@ -134,7 +134,7 @@ function BoardDetail() { className={css({ margin: "auto" })} /> )} - + 목록으로 돌아가기 돌아가기 diff --git a/src/utils/localStorageToken.ts b/src/utils/localStorageToken.ts index 79f6578b5..dc0fde2f4 100644 --- a/src/utils/localStorageToken.ts +++ b/src/utils/localStorageToken.ts @@ -11,13 +11,14 @@ export const loadTokenToLocalStorage = (token: Token): void => { localStorage.getItem(token.refreshToken); }; -export const AccessTokenTOLocalStorage = async () => { +export const AccessTokenToLocalStorage = async () => { if ( !localStorage.getItem("accessToken") && !localStorage.getItem("refreshToken") - ) + ) { console.log("로컬스토리지 확인해봐 뭐있나 없으면 로그인 ㄱㄱ"); - return; + return; + } if (!localStorage.getItem("accessToken")) { const refreshToken = localStorage.getItem("refreshToken"); const token = await PostRefreshToken(refreshToken); From 91ed5aadb4ef6f771cd83743eaf3dea149504088 Mon Sep 17 00:00:00 2001 From: Darkthos Date: Tue, 11 Jun 2024 18:29:04 +0900 Subject: [PATCH 2/8] feat(interceptors) --- src/apis/auth/PostRefreshToken.ts | 6 ++-- src/apis/comment/postArticlesIdComment.ts | 16 ++--------- src/pages/boards/[id].tsx | 5 +--- src/utils/localStorageToken.ts | 34 ++++++++++++----------- 4 files changed, 23 insertions(+), 38 deletions(-) diff --git a/src/apis/auth/PostRefreshToken.ts b/src/apis/auth/PostRefreshToken.ts index d82011d4c..0b1ff78a4 100644 --- a/src/apis/auth/PostRefreshToken.ts +++ b/src/apis/auth/PostRefreshToken.ts @@ -1,11 +1,9 @@ import { Token } from "@/types/api"; import axiosInstance from "../axiosInstance"; -const PostRefreshToken = async ( - refreshToken: string | null -): Promise => { +const PostRefreshToken = async (refreshToken?: string): Promise => { try { - const { data } = await axiosInstance.post("/auth/refresh-token", { + const { data } = await axiosInstance.post("/auth/refresh-token", { refreshToken: refreshToken, }); return data; diff --git a/src/apis/comment/postArticlesIdComment.ts b/src/apis/comment/postArticlesIdComment.ts index 2b650f748..afe6875db 100644 --- a/src/apis/comment/postArticlesIdComment.ts +++ b/src/apis/comment/postArticlesIdComment.ts @@ -1,20 +1,8 @@ import axiosInstance from "../axiosInstance"; -const postArticlesComment = async ( - content: string, - id: string, - token?: string | null -) => { +const postArticlesComment = async (content: string, id: string) => { try { - await axiosInstance.post( - `/articles/${id}/comments`, - { content }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); + await axiosInstance.post(`/articles/${id}/comments`, { content }); } catch (error) { console.error(`Failed to fetch data: ${error}`); throw error; diff --git a/src/pages/boards/[id].tsx b/src/pages/boards/[id].tsx index 219089524..265249a8a 100644 --- a/src/pages/boards/[id].tsx +++ b/src/pages/boards/[id].tsx @@ -20,8 +20,6 @@ import Header from "@/components/shared/Header/Header"; import postArticlesComment from "@/apis/comment/postArticlesIdComment"; import { ParsedUrlQuery } from "querystring"; import { boardIdPageStyle, flexStyle } from "@/css/boardsId.styled"; -import PostRefreshToken from "@/apis/auth/PostRefreshToken"; -import { AccessTokenToLocalStorage } from "@/utils/localStorageToken"; function BoardDetail() { const router = useRouter(); @@ -38,9 +36,8 @@ function BoardDetail() { const handleSubmit = async () => { if (typeof id !== "string") return; - const token = await AccessTokenToLocalStorage(); setCommentData(""); - await postArticlesComment(commentData, id, token); + await postArticlesComment(commentData, id); setIsChangeComments(!isChangeComments); }; diff --git a/src/utils/localStorageToken.ts b/src/utils/localStorageToken.ts index dc0fde2f4..2c8275f99 100644 --- a/src/utils/localStorageToken.ts +++ b/src/utils/localStorageToken.ts @@ -6,25 +6,27 @@ export const saveTokenToLocalStorage = (token: Token): void => { localStorage.setItem("refreshToken", token.refreshToken); }; -export const loadTokenToLocalStorage = (token: Token): void => { - localStorage.getItem(token.accessToken); - localStorage.getItem(token.refreshToken); +export const loadTokenFromLocalStorage = (): Token | null => { + const accessToken = localStorage.getItem("accessToken")?.replace(/"/gi, ""); + const refreshToken = localStorage.getItem("refreshToken")?.replace(/"/gi, ""); + if (accessToken && refreshToken) { + return { accessToken, refreshToken } as Token; + } + return null; }; -export const AccessTokenToLocalStorage = async () => { - if ( - !localStorage.getItem("accessToken") && - !localStorage.getItem("refreshToken") - ) { - console.log("로컬스토리지 확인해봐 뭐있나 없으면 로그인 ㄱㄱ"); - return; +export const getToken = async (): Promise => { + const token = loadTokenFromLocalStorage(); + if (!token) { + console.log("로그인해라"); + return null; } - if (!localStorage.getItem("accessToken")) { - const refreshToken = localStorage.getItem("refreshToken"); - const token = await PostRefreshToken(refreshToken); - return token; + + if (!token.accessToken) { + const newToken = await PostRefreshToken(token.refreshToken); + saveTokenToLocalStorage(newToken); + return newToken.accessToken; } else { - const token = localStorage.getItem("accessToken"); - return token; + return token.accessToken; } }; From 19d5df6a15857865b132815fd9f83042db92b603 Mon Sep 17 00:00:00 2001 From: Darkthos Date: Tue, 11 Jun 2024 18:29:24 +0900 Subject: [PATCH 3/8] feat(interceptors) --- src/apis/axiosInstance.ts | 26 +++++++++++++++++++++++++- src/pages/addboard/index.tsx | 4 ++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/apis/axiosInstance.ts b/src/apis/axiosInstance.ts index 582d23b57..1572bb338 100644 --- a/src/apis/axiosInstance.ts +++ b/src/apis/axiosInstance.ts @@ -1,5 +1,6 @@ import axios, { AxiosRequestConfig } from "axios"; -// git push origin Next.js-김민재-sprint10 실수하지않을려고 push config설정 안했는데 브랜치이름 너무 치기어려워서 넣었습니다. +import { getToken } from "@/utils/localStorageToken"; + const axiosConfig: AxiosRequestConfig = { baseURL: "https://panda-market-api.vercel.app/", headers: { @@ -10,4 +11,27 @@ const axiosConfig: AxiosRequestConfig = { const axiosInstance = axios.create(axiosConfig); +axiosInstance.interceptors.request.use( + async (config) => { + const accessToken = await getToken(); + if (accessToken) { + config.headers.Authorization = `Bearer ${accessToken}`; + } + return config; + }, + (error) => { + return Promise.reject(error); + } +); + +axiosInstance.interceptors.response.use( + (response) => { + return response; + }, + (error) => { + alert(`ERROR: ${error.response.data.message}`); + return Promise.reject(error); + } +); + export default axiosInstance; diff --git a/src/pages/addboard/index.tsx b/src/pages/addboard/index.tsx index b63ac17d6..959f5885e 100644 --- a/src/pages/addboard/index.tsx +++ b/src/pages/addboard/index.tsx @@ -4,7 +4,7 @@ import Form from "@/components/addBoardComponents/Form"; import FormTitle from "@/components/addBoardComponents/FormTitle"; import Header from "@/components/shared/Header/Header"; import { css } from "@/styled-system/css"; -import { AccessTokenToLocalStorage } from "@/utils/localStorageToken"; +import { getToken } from "@/utils/localStorageToken"; import { useRouter } from "next/router"; import React, { useState } from "react"; @@ -46,7 +46,7 @@ function AddBoard() { const handleSubmit = async () => { if (!isValid) return; - const token = await AccessTokenToLocalStorage(); + const token = await getToken(); await postArticles(postData, token); router.push("/boards"); }; From b65432bf8fe44cd737b440ab0cba3743de89e4ed Mon Sep 17 00:00:00 2001 From: Darkthos Date: Tue, 11 Jun 2024 19:42:38 +0900 Subject: [PATCH 4/8] =?UTF-8?q?refactor:=20=EB=AA=A8=EB=93=A0=20=ED=94=BC?= =?UTF-8?q?=EB=93=9C=EB=B0=B1=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 1 + next.config.mjs | 3 ++ panda.config.ts | 1 + src/apis/article/postArticles.ts | 12 ++------ src/apis/axiosInstance.ts | 2 +- src/apis/comment/getArticlesIdComment.ts | 5 ++-- src/apis/postImage.ts | 5 ++-- .../{Form.tsx => ArticleForm.tsx} | 9 ++++-- .../{FormTitle.tsx => ArticleFormTitle.tsx} | 4 +-- .../boardsComponents/NormalPost.tsx | 4 +-- src/pages/addboard/index.tsx | 28 +++++++++++-------- src/pages/boards/[id].tsx | 1 - 12 files changed, 41 insertions(+), 34 deletions(-) create mode 100644 .env rename src/components/addBoardComponents/{Form.tsx => ArticleForm.tsx} (95%) rename src/components/addBoardComponents/{FormTitle.tsx => ArticleFormTitle.tsx} (86%) diff --git a/.env b/.env new file mode 100644 index 000000000..e5a5d097b --- /dev/null +++ b/.env @@ -0,0 +1 @@ +BASE_URL = https://panda-market-api.vercel.app \ No newline at end of file diff --git a/next.config.mjs b/next.config.mjs index d19b6b74c..74e965473 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -7,6 +7,9 @@ const nextConfig = { "example.com", ], }, + env: { + BASE_URL: process.env.BASE_URL, + }, }; export default nextConfig; diff --git a/panda.config.ts b/panda.config.ts index 88318ad0f..4659c6229 100644 --- a/panda.config.ts +++ b/panda.config.ts @@ -19,6 +19,7 @@ export default defineConfig({ blueBanner: { value: "#CFE5FF" }, textBasic: { value: "#374151" }, disabledBasic: { value: "#9CA3AF" }, + errorRed: { value: "#F74747" }, }, fonts: { ROKAF: { value: "ROKAF Sans" }, diff --git a/src/apis/article/postArticles.ts b/src/apis/article/postArticles.ts index edc63dc00..d73e22e18 100644 --- a/src/apis/article/postArticles.ts +++ b/src/apis/article/postArticles.ts @@ -1,25 +1,19 @@ import { Token } from "@/types/api"; import axiosInstance from "../axiosInstance"; -import { PostData } from "@/components/addBoardComponents/Form"; +import { PostData } from "@/components/addBoardComponents/ArticleForm"; const postArticles = async ( option: PostData = { content: "", title: "", image: null, - }, - token?: string | null + } ) => { const { image, ...restOption } = option; const payload = image ? option : restOption; try { - const { data } = await axiosInstance.post("/articles", payload, { - headers: { - Authorization: `Bearer ${token}`, - }, - }); - return data; + await axiosInstance.post("/articles", payload); } catch (error) { console.error(`Failed to fetch data: ${error}`); throw error; diff --git a/src/apis/axiosInstance.ts b/src/apis/axiosInstance.ts index 1572bb338..7f292906d 100644 --- a/src/apis/axiosInstance.ts +++ b/src/apis/axiosInstance.ts @@ -2,7 +2,7 @@ import axios, { AxiosRequestConfig } from "axios"; import { getToken } from "@/utils/localStorageToken"; const axiosConfig: AxiosRequestConfig = { - baseURL: "https://panda-market-api.vercel.app/", + baseURL: `${process.env.BASE_URL}`, headers: { "Content-Type": "application/json", Accept: "application/json", diff --git a/src/apis/comment/getArticlesIdComment.ts b/src/apis/comment/getArticlesIdComment.ts index a71851729..23f109e87 100644 --- a/src/apis/comment/getArticlesIdComment.ts +++ b/src/apis/comment/getArticlesIdComment.ts @@ -1,12 +1,13 @@ +import { ArticleId } from "@/types/articles"; import axiosInstance from "../axiosInstance"; interface GetArticlesIdCommentResponse { - list: []; + list: ArticleId[]; nextCursor: null | string; } const getArticlesIdComment = async ( - articleId: string | string[] | undefined + articleId?: string | string[] ): Promise => { try { const { data } = await axiosInstance.get( diff --git a/src/apis/postImage.ts b/src/apis/postImage.ts index 5572948e0..a220656c1 100644 --- a/src/apis/postImage.ts +++ b/src/apis/postImage.ts @@ -1,10 +1,10 @@ import axiosInstance from "@/apis/axiosInstance"; interface PostImageResponse { - url?: null | Blob | MediaSource; + image?: null | Blob | MediaSource; } -const postImage = async (token: string | null, image?: any) => { +const postImage = async (image?: any) => { try { const formData = new FormData(); if (image) { @@ -15,7 +15,6 @@ const postImage = async (token: string | null, image?: any) => { formData, { headers: { - Authorization: `Bearer ${token}`, "Content-Type": "multipart/form-data", }, } diff --git a/src/components/addBoardComponents/Form.tsx b/src/components/addBoardComponents/ArticleForm.tsx similarity index 95% rename from src/components/addBoardComponents/Form.tsx rename to src/components/addBoardComponents/ArticleForm.tsx index ebc5093da..8fd6a41c7 100644 --- a/src/components/addBoardComponents/Form.tsx +++ b/src/components/addBoardComponents/ArticleForm.tsx @@ -21,7 +21,12 @@ interface FormProps { onChangeImage: (e: React.ChangeEvent) => void; } -function Form({ postData, file, onChangeInput, onChangeImage }: FormProps) { +function ArticleForm({ + postData, + file, + onChangeInput, + onChangeImage, +}: FormProps) { const [imageUrl, setImageUrl] = useState(imageAdd); useEffect(() => { @@ -83,4 +88,4 @@ function Form({ postData, file, onChangeInput, onChangeImage }: FormProps) { ); } -export default Form; +export default ArticleForm; diff --git a/src/components/addBoardComponents/FormTitle.tsx b/src/components/addBoardComponents/ArticleFormTitle.tsx similarity index 86% rename from src/components/addBoardComponents/FormTitle.tsx rename to src/components/addBoardComponents/ArticleFormTitle.tsx index e88d4a6ae..6c0a5a8ae 100644 --- a/src/components/addBoardComponents/FormTitle.tsx +++ b/src/components/addBoardComponents/ArticleFormTitle.tsx @@ -8,7 +8,7 @@ interface FormTitleProps { handleSubmit: MouseEventHandler; } -function FormTitle({ isValid, handleSubmit }: FormTitleProps) { +function ArticleFormTitle({ isValid, handleSubmit }: FormTitleProps) { return (

게시글 쓰기

@@ -24,4 +24,4 @@ function FormTitle({ isValid, handleSubmit }: FormTitleProps) { ); } -export default FormTitle; +export default ArticleFormTitle; diff --git a/src/components/boardsComponents/NormalPost.tsx b/src/components/boardsComponents/NormalPost.tsx index e90a2529c..5cbfff71a 100644 --- a/src/components/boardsComponents/NormalPost.tsx +++ b/src/components/boardsComponents/NormalPost.tsx @@ -38,8 +38,8 @@ function NormalPost() { useEffect(() => { const loadArticles = async () => { const receive = await getArticles({ - orderBy: `${orderBy}`, - keyword: `${searchValue}`, + orderBy: orderBy, + keyword: searchValue, }); setArticles(receive.list); }; diff --git a/src/pages/addboard/index.tsx b/src/pages/addboard/index.tsx index 959f5885e..df1948dc1 100644 --- a/src/pages/addboard/index.tsx +++ b/src/pages/addboard/index.tsx @@ -1,7 +1,7 @@ import postArticles from "@/apis/article/postArticles"; import postImage from "@/apis/postImage"; -import Form from "@/components/addBoardComponents/Form"; -import FormTitle from "@/components/addBoardComponents/FormTitle"; +import ArticleForm from "@/components/addBoardComponents/ArticleForm"; +import ArticleFormTitle from "@/components/addBoardComponents/ArticleFormTitle"; import Header from "@/components/shared/Header/Header"; import { css } from "@/styled-system/css"; import { getToken } from "@/utils/localStorageToken"; @@ -15,7 +15,7 @@ interface PostData { } function AddBoard() { - const [postData, setUserData] = useState({ + const [postData, setPostData] = useState({ content: "", title: "", image: null, @@ -27,27 +27,31 @@ function AddBoard() { e: React.ChangeEvent ) => { const { name, value } = e.target; - setUserData({ + setPostData({ ...postData, [name]: value, }); }; - const onChangeImage = async (e: any) => { + const onChangeImage = async (e: React.ChangeEvent) => { + if (!e.target.files) { + console.error("파일골라라"); + return; + } const file = e.target.files[0]; setAddImage(file); const token = localStorage.getItem("accessToken"); - const response = await postImage(token, file); - setUserData({ + const response = await postImage(file); + setPostData({ ...postData, - image: response.url, + image: response.image, }); }; const handleSubmit = async () => { if (!isValid) return; - const token = await getToken(); - await postArticles(postData, token); + + await postArticles(postData); router.push("/boards"); }; const isValid: boolean = !!(postData.content && postData.title); @@ -62,8 +66,8 @@ function AddBoard() { p: { base: "16px", md: "16px 24px", xl: "24px" }, })} > - -
+ Date: Fri, 14 Jun 2024 17:42:34 +0900 Subject: [PATCH 5/8] refactor(gitignore) --- .gitignore | 2 + .../addBoardComponents/ArticleForm.tsx | 58 +++++++------- src/pages/boards/[id].tsx | 4 +- src/pages/signin/index.tsx | 36 +++++---- src/pages/signup/index.tsx | 76 ++++++++++--------- 5 files changed, 98 insertions(+), 78 deletions(-) diff --git a/.gitignore b/.gitignore index 3d3b1b297..c44f6d7d1 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,8 @@ /.next/ /out/ +/.env + # production /build diff --git a/src/components/addBoardComponents/ArticleForm.tsx b/src/components/addBoardComponents/ArticleForm.tsx index 8fd6a41c7..d7d0d4a3d 100644 --- a/src/components/addBoardComponents/ArticleForm.tsx +++ b/src/components/addBoardComponents/ArticleForm.tsx @@ -40,36 +40,42 @@ function ArticleForm({ return (
- - +
- -