2026-01-09 21:56:32 +09:00
|
|
|
/**
|
|
|
|
|
* 공통 API 유틸리티
|
|
|
|
|
* 모든 API 호출에서 사용되는 기본 fetch 래퍼
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// 기본 fetch 래퍼
|
|
|
|
|
export async function fetchApi(url, options = {}) {
|
2026-01-19 12:49:29 +09:00
|
|
|
const headers = { ...options.headers };
|
|
|
|
|
|
|
|
|
|
// body가 있을 때만 Content-Type 설정 (DELETE 등 body 없는 요청 대응)
|
|
|
|
|
if (options.body) {
|
|
|
|
|
headers["Content-Type"] = "application/json";
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-09 21:56:32 +09:00
|
|
|
const response = await fetch(url, {
|
|
|
|
|
...options,
|
2026-01-19 12:49:29 +09:00
|
|
|
headers,
|
2026-01-09 21:56:32 +09:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
const error = await response.json().catch(() => ({ error: "요청 실패" }));
|
|
|
|
|
throw new Error(error.error || `HTTP ${response.status}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response.json();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 어드민 토큰 가져오기
|
|
|
|
|
export function getAdminToken() {
|
|
|
|
|
return localStorage.getItem("adminToken");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 어드민 API용 fetch 래퍼 (토큰 자동 추가)
|
|
|
|
|
export async function fetchAdminApi(url, options = {}) {
|
|
|
|
|
const token = getAdminToken();
|
|
|
|
|
|
|
|
|
|
return fetchApi(url, {
|
|
|
|
|
...options,
|
|
|
|
|
headers: {
|
|
|
|
|
...options.headers,
|
|
|
|
|
Authorization: `Bearer ${token}`,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FormData 전송용 (이미지 업로드 등)
|
|
|
|
|
export async function fetchAdminFormData(url, formData, method = "POST") {
|
|
|
|
|
const token = getAdminToken();
|
|
|
|
|
|
|
|
|
|
const response = await fetch(url, {
|
|
|
|
|
method,
|
|
|
|
|
headers: {
|
|
|
|
|
Authorization: `Bearer ${token}`,
|
|
|
|
|
},
|
|
|
|
|
body: formData,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
const error = await response.json().catch(() => ({ error: "요청 실패" }));
|
|
|
|
|
throw new Error(error.error || `HTTP ${response.status}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response.json();
|
|
|
|
|
}
|