260706_2_로그인 인증 검토

This commit is contained in:
2026-07-07 20:40:10 +09:00
parent f8633bb1fe
commit 5da0260be3
29 changed files with 720 additions and 336 deletions
+25 -14
View File
@@ -9,12 +9,7 @@
import { ui_locales, currentLanguageIndex, setLanguage } from "@ui/ui_template_locale";
import { createButton } from "@ui/ui_template_elements";
import {
THEME_STORAGE_KEY,
LANG_STORAGE_KEY,
AUTH_TOKEN_KEY,
ROUTES,
} from "@config/config_frontend";
import { THEME_STORAGE_KEY, LANG_STORAGE_KEY, ROUTES } from "@config/config_frontend";
import { navigateTo, isAuthenticated } from "./router";
/** locale 헬퍼: 현재 언어 인덱스로 문구 반환 */
@@ -51,8 +46,13 @@ function onApp_Lang_Toggle_Click(): void {
window.dispatchEvent(new HashChangeEvent("hashchange"));
}
function onApp_Logout_Click(): void {
localStorage.removeItem(AUTH_TOKEN_KEY);
async function onApp_Logout_Click(): Promise<void> {
const { logout } = await import("../A06_Login/A06_Login_Api_Fetch");
try {
await logout();
} catch {
// 세션이 이미 만료된 경우 등은 무시하고 홈으로 이동
}
navigateTo(ROUTES.A01_HOME);
}
@@ -105,8 +105,22 @@ function buildHeader(): HTMLElement {
});
actions.append(langBtn, themeBtn);
if (isAuthenticated() as any) {
actions.append(
// 인증 버튼은 서버 세션 확인(비동기) 후 채운다.
const authSlot = document.createElement("div");
authSlot.className = "app-actions__auth";
actions.append(authSlot);
void fillAuthActions(authSlot);
header.append(brand, nav, actions);
return header;
}
/** 서버 세션 상태에 따라 로그인/로그아웃 버튼을 채운다. */
async function fillAuthActions(slot: HTMLElement): Promise<void> {
const loggedIn = await isAuthenticated();
slot.innerHTML = "";
if (loggedIn) {
slot.append(
createButton({
label: L("Nav_MyAccount"),
variant: "ghost",
@@ -119,7 +133,7 @@ function buildHeader(): HTMLElement {
}),
);
} else {
actions.append(
slot.append(
createButton({
label: L("Nav_Login"),
variant: "ghost",
@@ -132,9 +146,6 @@ function buildHeader(): HTMLElement {
}),
);
}
header.append(brand, nav, actions);
return header;
}
function buildFooter(): HTMLElement {