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

[김현서] Week15 #479

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
18 changes: 0 additions & 18 deletions weekly-mission/next-project/lib/api/authService.ts

This file was deleted.

64 changes: 64 additions & 0 deletions weekly-mission/next-project/lib/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,71 @@
import axios from "axios";
import { useRouter } from "next/router";

const instance = axios.create({
baseURL: "https://bootcamp-api.codeit.kr/api",
headers: { "Content-Type": "application/json" },
});

// 요청 인터셉터
// 요청 인터셉터
instance.interceptors.request.use(
function (config) {
// 스토리지에서 토큰을 가져온다.
const accessToken = localStorage.getItem("accessToken");
const refreshToken = localStorage.getItem("refreshToken");

// 토큰이 있으면 요청 헤더에 추가한다.
if (accessToken) {
config.headers["Authorization"] = `Bearer ${accessToken}`;
}
// Refresh 토큰을 보낼 경우 사용하고자 하는 커스텀 인증 헤더를 사용하면 된다.
if (refreshToken) {
config.headers["x-refresh-token"] = refreshToken;
}

return config;
},
function (error) {
// 요청 오류 처리
return Promise.reject(error);
}
);

// 응답 인터셉터
instance.interceptors.response.use(
async function (response) {
return response;
},
async function (error) {
const {
config,
response: { status },
} = error;

if (status === 401 && data.message === "InvalidTokenException") {
// 토큰이 없거나 잘못되었을 경우
logout();
}
if (status === 401 && data.message === "TokenExpired") {
try {
const tokenRefreshResult = await instance.post("/refresh-token");
if (tokenRefreshResult.status === 200) {
const { accessToken, refreshToken } = tokenRefreshResult.data;
// 새로 발급받은 토큰을 스토리지에 저장
localStorage.setItem("accessToken", accessToken);
localStorage.setItem("refreshToken", refreshToken);
// 토큰 갱신 성공. API 재요청
return instance(config);
} else {
logout();
}
} catch (e) {
logout();
}
}

return Promise.reject(error);
}
);

export default instance;
6 changes: 6 additions & 0 deletions weekly-mission/next-project/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ const nextConfig = {
port: "",
pathname: "/badges/**",
},
{
protocol: "https",
hostname: "ca.slack-edge.com",
port: "",
pathname: "/**",
},
],
},
};
Expand Down
7 changes: 6 additions & 1 deletion weekly-mission/next-project/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import "@/styles/globals.css";
import { AppProps } from "next/app";
import React from "react";
import { FolderProvider } from "src/context/FolderContext";

function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
return (
<FolderProvider>
<Component {...pageProps} />
</FolderProvider>
);
}

export default App;
33 changes: 0 additions & 33 deletions weekly-mission/next-project/pages/api/check-email.tsx

This file was deleted.

11 changes: 0 additions & 11 deletions weekly-mission/next-project/pages/api/sign-in.tsx

This file was deleted.

14 changes: 0 additions & 14 deletions weekly-mission/next-project/pages/api/sign-up.tsx

This file was deleted.

20 changes: 20 additions & 0 deletions weekly-mission/next-project/pages/folder/[folderId].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useEffect } from "react";
import { useRouter } from "next/router";
import FolderPageLayout from "@components/Layout/FolderPageLayout";
import { useFolder, useUser } from "src/context/FolderContext";

function FolderIdPage() {
const router = useRouter();
const { folderId } = router.query;
const { user, getUser } = useUser();

useEffect(() => {
if (folderId) {
getUser();
}
}, [folderId]);

return <FolderPageLayout user={user} />;
}

export default FolderIdPage;
15 changes: 15 additions & 0 deletions weekly-mission/next-project/pages/folder/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React, { useEffect } from "react";
import { useUser, useFolder } from "src/context/FolderContext";
import FolderPageLayout from "@components/Layout/FolderPageLayout";

function FolderPage() {
const { user, getUser } = useUser();

useEffect(() => {
getUser();
}, []);

return <FolderPageLayout user={user} />;
}

export default FolderPage;
14 changes: 0 additions & 14 deletions weekly-mission/next-project/pages/index.tsx

This file was deleted.

25 changes: 0 additions & 25 deletions weekly-mission/next-project/pages/service/fetchFolderLinksData.ts

This file was deleted.

42 changes: 42 additions & 0 deletions weekly-mission/next-project/pages/service/useFetchLink.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useEffect, useState } from "react";
import { AxiosResponse } from "axios";
import instance from "lib/api";

export interface LinkData {
data: {
id: number;
title: string;
created_at: string;
url: string;
description?: string;
image_source?: string;
}[];
Comment on lines +6 to +13
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data: {} 로 오는 건 보통 서버에서 오는 응답인 경우가 많은데 이 경우엔 generic 함수를 이용해서 처리하는 경우가 많습니다!
https://velog.io/@ctdlog/Axios-Response-with-generic#%EC%99%9C-%EA%B8%B0%EB%B3%B8-response-%ED%83%80%EC%9E%85%EC%9D%84-%EB%B0%94%EA%BF%94%EC%84%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C%EC%9A%94

}

export async function useFetchLinks(userId: number, folderId: number) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use 로 시작하는 훅의 경우 pages 말고 hooks 폴더에 따로 묶어주심 좋을 거 같아요!

const [links, setLinks] = useState<LinkData>({ data: [] });

useEffect(() => {
async function fetchLinks() {
try {
const response: AxiosResponse<LinkData> = await instance.get(
`/api/users/${userId}/links`,
{
params: {
folderId: folderId,
},
}
);
setLinks(response.data);
} catch (error) {
console.error("Error fetching links:", error);
}
}

if (folderId) {
fetchLinks();
}
}, [userId, folderId]);

return links;
}
42 changes: 42 additions & 0 deletions weekly-mission/next-project/pages/service/useFolderData.ts
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useFetchLink 랑 되게 비슷한 구조라 공통화해봐도 좋을 거 같아요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useState, useEffect } from "react";
import instance from "lib/api";

interface FolderData {
email: string;
id: number;
name: string;
profileImageSource: string;
}

const useFolderData = (
folderId: string
): {
data: FolderData | null;
isLoading: boolean;
} => {
const [data, setData] = useState<FolderData | null>(null);
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
const fetchData = async () => {
try {
const response = await instance.get(
`${process.env.NEXT_PUBLIC_BASE_URL}/folders/${folderId}`
);
const fetchedData: FolderData = await response.data.data;

setData(fetchedData);
} catch (error) {
console.error("Error fetching folder data:", error);
} finally {
setIsLoading(false);
}
};

fetchData();
}, [folderId]);

return { data, isLoading };
};

export default useFolderData;
12 changes: 7 additions & 5 deletions weekly-mission/next-project/pages/service/useFolderList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { useState, useEffect } from "react";
import instance from "lib/api";
import { AxiosResponse } from "axios";

interface Owner {
id: number;
Expand Down Expand Up @@ -30,19 +32,17 @@ interface FolderListState {
isLoading: boolean;
}

const useFolderList = (): FolderListState => {
const useFolderList = (userId: number): FolderListState => {
const [data, setData] = useState<FolderData | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(true);

useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(
const response: AxiosResponse<FolderData> = await instance.get(
`${process.env.NEXT_PUBLIC_BASE_URL}/sample/folder`
);
const fetchedData = await response.json();

setData(fetchedData);
setData(response.data);
} catch (error) {
console.error("Error fetching folders data:", error);
} finally {
Expand All @@ -57,3 +57,5 @@ const useFolderList = (): FolderListState => {
};

export default useFolderList;

//${process.env.NEXT_PUBLIC_BASE_URL}/sample/folder
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const useFoldersByUserId = (userId: number): useFoldersByUserIdResponse => {
const fetchData = async () => {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_BASE_URL}/users/${userId}/folders`
`${process.env.NEXT_PUBLIC_BASE_URL}/users/${userId}`
);
const fetchedData: Folder = await response.json();

Expand All @@ -49,3 +49,5 @@ const useFoldersByUserId = (userId: number): useFoldersByUserIdResponse => {
};

export default useFoldersByUserId;

/*${process.env.NEXT_PUBLIC_BASE_URL}/users/${userId}/folders*/
Loading
Loading