Initial dashboard organization setup

This commit is contained in:
hyunho
2026-03-25 10:26:33 +09:00
commit d9023abed6
22 changed files with 5340 additions and 0 deletions

85
frontend/public/app.js Executable file
View File

@@ -0,0 +1,85 @@
const sessionKey = "mh-dashboard-session";
const loginPanel = document.getElementById("login-panel");
const dashboardPanel = document.getElementById("dashboard-panel");
const loginForm = document.getElementById("login-form");
const loginMessage = document.getElementById("login-message");
const logoutBtn = document.getElementById("logout-btn");
const userBadge = document.getElementById("user-badge");
const healthStatus = document.getElementById("health-status");
const refreshHealthBtn = document.getElementById("refresh-health-btn");
function getSession() {
try {
return JSON.parse(sessionStorage.getItem(sessionKey) || "null");
} catch {
return null;
}
}
function setSession(session) {
sessionStorage.setItem(sessionKey, JSON.stringify(session));
}
function clearSession() {
sessionStorage.removeItem(sessionKey);
}
function renderAuth() {
const session = getSession();
const authenticated = Boolean(session?.user?.display_name);
loginPanel.classList.toggle("hidden", authenticated);
dashboardPanel.classList.toggle("hidden", !authenticated);
if (authenticated) {
userBadge.textContent = `${session.user.display_name} / ${session.user.role}`;
refreshHealth();
}
}
async function refreshHealth() {
if (!healthStatus) return;
healthStatus.textContent = "서버 상태를 확인하는 중입니다.";
try {
const response = await fetch("/api/health");
if (!response.ok) throw new Error("unhealthy");
const payload = await response.json();
healthStatus.textContent = `API 상태: ${payload.status}`;
} catch (error) {
healthStatus.textContent = "API에 연결할 수 없습니다. backend 컨테이너를 확인해주세요.";
}
}
if (loginForm) {
loginForm.addEventListener("submit", async (event) => {
event.preventDefault();
loginMessage.textContent = "로그인 처리 중입니다.";
const formData = new FormData(loginForm);
try {
const response = await fetch("/api/mock-login", {
method: "POST",
body: formData,
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.detail || "login failed");
setSession(payload);
loginForm.reset();
renderAuth();
} catch (error) {
loginMessage.textContent = "로그인에 실패했습니다. backend 연결 상태를 확인해주세요.";
}
});
}
if (logoutBtn) {
logoutBtn.addEventListener("click", () => {
clearSession();
renderAuth();
});
}
if (refreshHealthBtn) {
refreshHealthBtn.addEventListener("click", refreshHealth);
}
renderAuth();