Skip to content

Commit 24a8a2b

Browse files
committed
feat: api 추가
1 parent c7f66fa commit 24a8a2b

File tree

2 files changed

+84
-12
lines changed

2 files changed

+84
-12
lines changed

app/addboard/page.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ export default function AddBoard() {
1515

1616
const handleSubmit = async () => {
1717
try {
18-
const imageUrl = image ? URL.createObjectURL(image) : undefined;
19-
await addArticle(title, content, imageUrl);
20-
18+
await addArticle(title, content, image);
2119
alert("게시물이 성공적으로 등록되었습니다!");
2220
setTitle("");
2321
setContent("");

app/lib/api/api.ts

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -203,27 +203,101 @@ export const signIn = async (email: string, password: string) => {
203203
return response.json();
204204
};
205205

206-
export const addArticle = async (
207-
title: string,
208-
content: string,
209-
image?: string
210-
): Promise<void> => {
206+
export const refreshAccessToken = async (): Promise<string> => {
207+
const refreshToken = localStorage.getItem("refreshToken");
208+
if (!refreshToken) {
209+
throw new Error("리프레시 토큰이 없습니다. 다시 로그인해주세요.");
210+
}
211+
212+
const response = await fetch(`${BASE_URL}auth/refresh-token`, {
213+
method: "POST",
214+
headers: {
215+
"Content-Type": "application/json",
216+
},
217+
body: JSON.stringify({ refreshToken }),
218+
});
219+
220+
if (!response.ok) {
221+
const errorData = await response.json();
222+
throw new Error(errorData.message || "토큰 갱신 실패");
223+
}
224+
225+
const data = await response.json();
226+
localStorage.setItem("accessToken", data.accessToken);
227+
return data.accessToken;
228+
};
229+
230+
export const uploadImage = async (image: File): Promise<string> => {
211231
const token = localStorage.getItem("accessToken");
212232
if (!token) {
213233
throw new Error("로그인이 필요합니다.");
214234
}
215235

216-
const response = await fetch(`${BASE_URL}articles`, {
236+
const formData = new FormData();
237+
formData.append("file", image);
238+
239+
const response = await fetch(`${BASE_URL}images/upload`, {
217240
method: "POST",
218241
headers: {
219-
"Content-Type": "application/json",
220242
Authorization: `Bearer ${token}`,
221243
},
222-
body: JSON.stringify({ title, content, image }),
244+
body: formData,
223245
});
224246

225247
if (!response.ok) {
226248
const errorData = await response.json();
227-
throw new Error(errorData.message || "게시물 등록 실패");
249+
throw new Error(errorData.message || "이미지 업로드 실패");
250+
}
251+
252+
const data = await response.json();
253+
return data.url;
254+
};
255+
256+
export const addArticle = async (
257+
title: string,
258+
content: string,
259+
image?: File | null
260+
): Promise<void> => {
261+
let token = localStorage.getItem("accessToken");
262+
if (!token) {
263+
throw new Error("로그인이 필요합니다.");
264+
}
265+
266+
try {
267+
const body = { title, content };
268+
269+
const response = await fetch(`${BASE_URL}articles`, {
270+
method: "POST",
271+
headers: {
272+
"Content-Type": "application/json",
273+
Authorization: `Bearer ${token}`,
274+
},
275+
body: JSON.stringify(body),
276+
});
277+
278+
if (!response.ok) {
279+
if (response.status === 401) {
280+
const newToken = await refreshAccessToken();
281+
token = newToken;
282+
283+
const retryResponse = await fetch(`${BASE_URL}articles`, {
284+
method: "POST",
285+
headers: {
286+
"Content-Type": "application/json",
287+
Authorization: `Bearer ${token}`,
288+
},
289+
body: JSON.stringify(body),
290+
});
291+
292+
if (!retryResponse.ok) {
293+
throw new Error("게시물 등록 실패");
294+
}
295+
} else {
296+
const errorData = await response.json();
297+
throw new Error(errorData.message || "게시물 등록 실패");
298+
}
299+
}
300+
} catch (error) {
301+
throw new Error(error instanceof Error ? error.message : "오류 발생");
228302
}
229303
};

0 commit comments

Comments
 (0)