219 lines
5.2 KiB
JavaScript
219 lines
5.2 KiB
JavaScript
|
|
/**
|
||
|
|
* 관리자 API 관련 커스텀 훅
|
||
|
|
* 통계, 사용자 관리, SES 설정
|
||
|
|
*/
|
||
|
|
import { useCallback } from "react";
|
||
|
|
import { getAuthHeaders } from "./useAuth";
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 관리자 기능을 제공하는 훅
|
||
|
|
*/
|
||
|
|
export const useAdmin = () => {
|
||
|
|
/**
|
||
|
|
* 관리자 API 403 오류 처리
|
||
|
|
* 권한 박탈 시 강제 리다이렉트
|
||
|
|
*/
|
||
|
|
const handleAdminError = useCallback(async (res) => {
|
||
|
|
if (res.status === 403) {
|
||
|
|
// 권한 없음 - 로컬 스토리지 업데이트
|
||
|
|
const currentUser = JSON.parse(
|
||
|
|
localStorage.getItem("email_user") || "{}"
|
||
|
|
);
|
||
|
|
currentUser.isAdmin = false;
|
||
|
|
localStorage.setItem("email_user", JSON.stringify(currentUser));
|
||
|
|
|
||
|
|
// sessionStorage에 메시지 저장 (리다이렉트 후 표시)
|
||
|
|
sessionStorage.setItem(
|
||
|
|
"admin_denied_message",
|
||
|
|
"권한이 없습니다. 메인 화면으로 이동합니다."
|
||
|
|
);
|
||
|
|
|
||
|
|
// 강제 리다이렉트
|
||
|
|
window.location.href = "/mail/inbox";
|
||
|
|
|
||
|
|
// 페이지 이동이 완료될 때까지 영원히 대기 (후속 코드 실행 방지)
|
||
|
|
return new Promise(() => {});
|
||
|
|
}
|
||
|
|
return res;
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 대시보드 통계 조회
|
||
|
|
*/
|
||
|
|
const fetchStats = useCallback(
|
||
|
|
async (period = "all") => {
|
||
|
|
const res = await fetch(`/api/admin/stats?period=${period}`, {
|
||
|
|
headers: getAuthHeaders(),
|
||
|
|
});
|
||
|
|
await handleAdminError(res);
|
||
|
|
return res.json();
|
||
|
|
},
|
||
|
|
[handleAdminError]
|
||
|
|
);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 사용자 목록 조회
|
||
|
|
*/
|
||
|
|
const fetchUsers = useCallback(async () => {
|
||
|
|
const res = await fetch("/api/admin/users", { headers: getAuthHeaders() });
|
||
|
|
await handleAdminError(res);
|
||
|
|
return res.json();
|
||
|
|
}, [handleAdminError]);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 사용자 추가
|
||
|
|
*/
|
||
|
|
const addUser = useCallback(
|
||
|
|
async (userData) => {
|
||
|
|
const res = await fetch("/api/admin/users", {
|
||
|
|
method: "POST",
|
||
|
|
headers: getAuthHeaders(),
|
||
|
|
body: JSON.stringify(userData),
|
||
|
|
});
|
||
|
|
await handleAdminError(res);
|
||
|
|
if (!res.ok) {
|
||
|
|
const d = await res.json();
|
||
|
|
throw new Error(d.error || "사용자 생성 실패");
|
||
|
|
}
|
||
|
|
return res.json();
|
||
|
|
},
|
||
|
|
[handleAdminError]
|
||
|
|
);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 사용자 수정
|
||
|
|
*/
|
||
|
|
const updateUser = useCallback(
|
||
|
|
async (id, userData) => {
|
||
|
|
const res = await fetch(`/api/admin/users/${id}`, {
|
||
|
|
method: "PUT",
|
||
|
|
headers: getAuthHeaders(),
|
||
|
|
body: JSON.stringify(userData),
|
||
|
|
});
|
||
|
|
await handleAdminError(res);
|
||
|
|
if (!res.ok) {
|
||
|
|
const d = await res.json();
|
||
|
|
throw new Error(d.error || "사용자 수정 실패");
|
||
|
|
}
|
||
|
|
return res.json();
|
||
|
|
},
|
||
|
|
[handleAdminError]
|
||
|
|
);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 사용자 삭제
|
||
|
|
*/
|
||
|
|
const deleteUser = useCallback(
|
||
|
|
async (id) => {
|
||
|
|
const res = await fetch(`/api/admin/users/${id}`, {
|
||
|
|
method: "DELETE",
|
||
|
|
headers: getAuthHeaders(),
|
||
|
|
});
|
||
|
|
await handleAdminError(res);
|
||
|
|
if (!res.ok) {
|
||
|
|
const d = await res.json();
|
||
|
|
throw new Error(d.error || "사용자 삭제 실패");
|
||
|
|
}
|
||
|
|
return res.json();
|
||
|
|
},
|
||
|
|
[handleAdminError]
|
||
|
|
);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 이메일 설정 조회
|
||
|
|
*/
|
||
|
|
const fetchEmailConfig = useCallback(async () => {
|
||
|
|
const res = await fetch("/api/admin/config/email", {
|
||
|
|
headers: getAuthHeaders(),
|
||
|
|
});
|
||
|
|
await handleAdminError(res);
|
||
|
|
return res.json();
|
||
|
|
}, [handleAdminError]);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 이메일 설정 저장
|
||
|
|
*/
|
||
|
|
const updateEmailConfig = useCallback(
|
||
|
|
async (config) => {
|
||
|
|
const res = await fetch("/api/admin/config/email", {
|
||
|
|
method: "POST",
|
||
|
|
headers: getAuthHeaders(),
|
||
|
|
body: JSON.stringify(config),
|
||
|
|
});
|
||
|
|
await handleAdminError(res);
|
||
|
|
if (!res.ok) throw new Error("설정 업데이트 실패");
|
||
|
|
return res.json();
|
||
|
|
},
|
||
|
|
[handleAdminError]
|
||
|
|
);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 이메일 연결 테스트
|
||
|
|
*/
|
||
|
|
const testEmailConnection = useCallback(
|
||
|
|
async (emailConfig) => {
|
||
|
|
const res = await fetch("/api/admin/config/email/test", {
|
||
|
|
method: "POST",
|
||
|
|
headers: getAuthHeaders(),
|
||
|
|
body: JSON.stringify(emailConfig),
|
||
|
|
});
|
||
|
|
await handleAdminError(res);
|
||
|
|
if (!res.ok) {
|
||
|
|
const d = await res.json();
|
||
|
|
throw new Error(d.error || "연결 실패");
|
||
|
|
}
|
||
|
|
return res.json();
|
||
|
|
},
|
||
|
|
[handleAdminError]
|
||
|
|
);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 접속 IP 목록 조회
|
||
|
|
*/
|
||
|
|
const fetchRemoteIps = useCallback(
|
||
|
|
async (page = 1, limit = 10, period = "all") => {
|
||
|
|
const res = await fetch(
|
||
|
|
`/api/admin/remote-ips?page=${page}&limit=${limit}&period=${period}`,
|
||
|
|
{
|
||
|
|
headers: getAuthHeaders(),
|
||
|
|
}
|
||
|
|
);
|
||
|
|
await handleAdminError(res);
|
||
|
|
return res.json();
|
||
|
|
},
|
||
|
|
[handleAdminError]
|
||
|
|
);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 최근 활동 로그 조회
|
||
|
|
*/
|
||
|
|
const fetchRecentLogs = useCallback(
|
||
|
|
async (page = 1, limit = 10) => {
|
||
|
|
const res = await fetch(
|
||
|
|
`/api/admin/recent-logs?page=${page}&limit=${limit}`,
|
||
|
|
{
|
||
|
|
headers: getAuthHeaders(),
|
||
|
|
}
|
||
|
|
);
|
||
|
|
await handleAdminError(res);
|
||
|
|
return res.json();
|
||
|
|
},
|
||
|
|
[handleAdminError]
|
||
|
|
);
|
||
|
|
|
||
|
|
return {
|
||
|
|
fetchStats,
|
||
|
|
fetchUsers,
|
||
|
|
addUser,
|
||
|
|
updateUser,
|
||
|
|
deleteUser,
|
||
|
|
fetchEmailConfig,
|
||
|
|
updateEmailConfig,
|
||
|
|
testEmailConnection,
|
||
|
|
fetchRemoteIps,
|
||
|
|
fetchRecentLogs,
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
export default useAdmin;
|