From 8e2d7f092f20b19ad1e22db46cddf6d424239ed9 Mon Sep 17 00:00:00 2001 From: KimBoYoung Date: Thu, 19 Dec 2024 22:48:39 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Header.js | 4 +- src/events/loginEvents.js | 31 +++++++++++++++ src/events/mainEvents.js | 41 ++++++++++++++++++++ src/main.hash.js | 12 +----- src/main.js | 12 +----- src/pages/loginPage.js | 31 --------------- src/pages/profilePage.js | 18 +-------- src/preferences/user.js | 24 ------------ src/router.js | 79 --------------------------------------- src/router/router.js | 47 +++++++++++++++++++++++ src/router/routes.js | 33 ++++++++++++++++ src/storage/storage.js | 11 ++++++ 12 files changed, 169 insertions(+), 174 deletions(-) create mode 100644 src/events/loginEvents.js create mode 100644 src/events/mainEvents.js delete mode 100644 src/preferences/user.js delete mode 100644 src/router.js create mode 100644 src/router/router.js create mode 100644 src/router/routes.js create mode 100644 src/storage/storage.js diff --git a/src/components/Header.js b/src/components/Header.js index 0fec5552..85a806ad 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -10,7 +10,7 @@ export const Header = () => ` `; // 로그인 여부에 따른 렌더링 -function renderLoginStatus() { +const renderLoginStatus = () => { const user = JSON.parse(localStorage.getItem("user") || "{}"); const path = window.location.pathname; @@ -26,4 +26,4 @@ function renderLoginStatus() {
  • 로그인
  • `; } -} +}; diff --git a/src/events/loginEvents.js b/src/events/loginEvents.js new file mode 100644 index 00000000..3c051a9c --- /dev/null +++ b/src/events/loginEvents.js @@ -0,0 +1,31 @@ +import { navigateTo } from "../router/router.js"; +import { saveLocalStorage } from "../storage/storage.js"; + +export const loginEvents = () => { + const form = document.getElementById("login-form"); + const emailInput = document.getElementById("username"); + const passwordInput = document.getElementById("passwordInput"); + + // 로그인 + form.addEventListener("submit", (e) => { + e.preventDefault(); + const email = emailInput.value.trim(); + const password = passwordInput.value.trim(); + + if (validateForm(email, password)) { + saveLocalStorage("user", { username: email, email: "", bio: "" }); + console.log(localStorage.getItem("user")); + navigateTo("/profile"); + } + }); + + // 유효성 검사 + const validateForm = (email) => { + if (!email) { + alert("이메일을 입력해주세요."); + emailInput.focus(); + return false; + } + return true; + }; +}; diff --git a/src/events/mainEvents.js b/src/events/mainEvents.js new file mode 100644 index 00000000..ae5f69fb --- /dev/null +++ b/src/events/mainEvents.js @@ -0,0 +1,41 @@ +import { navigateTo } from "../router/router.js"; +import { clearLocalStorage, saveLocalStorage } from "../storage/storage.js"; + +export const mainEvents = () => { + // 헤더 이동 + document.addEventListener("click", (e) => { + const target = e.target.closest("a"); + if (target) { + e.preventDefault(); + e.stopPropagation(); + const href = target.getAttribute("href"); + if (href) { + navigateTo(href); + } + } + }); + + // 프로필 수정 + document.addEventListener("submit", (e) => { + e.preventDefault(); + if (e.target && e.target.id === "profile-form") { + const updatedUser = { + username: document.getElementById("username").value, + email: document.getElementById("email").value, + bio: document.getElementById("bio").value, + }; + + saveLocalStorage("user", updatedUser); + alert("프로필이 업데이트 되었습니다."); + } + }); + + // 로그아웃 + document.addEventListener("click", (e) => { + if (e.target && e.target.id === "logout") { + e.preventDefault(); + clearLocalStorage(); + navigateTo("/login"); + } + }); +}; diff --git a/src/main.hash.js b/src/main.hash.js index 12f91406..48d129b2 100644 --- a/src/main.hash.js +++ b/src/main.hash.js @@ -1,18 +1,8 @@ -import { navigateTo, resolveRoute } from "./router.js"; +import { resolveRoute } from "./router/router.js"; -document.addEventListener("click", (e) => { - if (e.target && e.target.id === "logout") { - e.preventDefault(); - localStorage.clear(); - navigateTo("/login"); - } -}); - -// 이벤트 초기화 const initializeRouter = () => { window.addEventListener("hashchange", () => resolveRoute(true)); window.addEventListener("load", () => resolveRoute(true)); }; -// 라우터 초기화 호출 initializeRouter(); diff --git a/src/main.js b/src/main.js index 52ff5801..12e97938 100644 --- a/src/main.js +++ b/src/main.js @@ -1,18 +1,8 @@ -import { navigateTo, resolveRoute } from "./router.js"; +import { resolveRoute } from "./router/router.js"; -document.addEventListener("click", (e) => { - if (e.target && e.target.id === "logout") { - e.preventDefault(); - localStorage.clear(); - navigateTo("/login"); - } -}); - -// 이벤트 초기화 const initializeRouter = () => { window.addEventListener("popstate", () => resolveRoute(false)); window.addEventListener("load", () => resolveRoute(false)); }; -// 라우터 초기화 호출 initializeRouter(); diff --git a/src/pages/loginPage.js b/src/pages/loginPage.js index e9756513..33f30d3d 100644 --- a/src/pages/loginPage.js +++ b/src/pages/loginPage.js @@ -1,5 +1,3 @@ -import { navigateTo } from "../router.js"; - export const LoginPage = () => { return `
    @@ -25,32 +23,3 @@ export const LoginPage = () => {
    `; }; - -export const loginHandles = () => { - const form = document.getElementById("login-form"); - const emailInput = document.getElementById("username"); - const passwordInput = document.getElementById("passwordInput"); - - form.addEventListener("submit", (e) => { - e.preventDefault(); - const email = emailInput.value.trim(); - const password = passwordInput.value.trim(); - - if (validateForm(email, password)) { - localStorage.setItem( - "user", - JSON.stringify({ username: email, email: "", bio: "" }), - ); - navigateTo("/profile"); - } - }); - - const validateForm = (email) => { - if (!email) { - alert("이메일을 입력해주세요."); - emailInput.focus(); - return false; - } - return true; - }; -}; diff --git a/src/pages/profilePage.js b/src/pages/profilePage.js index 3e905dc3..277c9046 100644 --- a/src/pages/profilePage.js +++ b/src/pages/profilePage.js @@ -1,8 +1,9 @@ import { Header } from "../components/Header.js"; import { Footer } from "../components/Footer.js"; +import { getLocalStorage } from "../storage/storage.js"; export const ProfilePage = () => { - const user = JSON.parse(localStorage.getItem("user")) || { + const user = getLocalStorage("user") || { username: "", email: "", bio: "", @@ -74,18 +75,3 @@ export const ProfilePage = () => { `; }; - -// 프로필 수정 -document.addEventListener("submit", (e) => { - e.preventDefault(); - if (e.target && e.target.id === "profile-form") { - const updatedUser = { - username: document.getElementById("username").value, - email: document.getElementById("email").value, - bio: document.getElementById("bio").value, - }; - - localStorage.setItem("user", JSON.stringify(updatedUser)); - alert("프로필이 업데이트 되었습니다."); - } -}); diff --git a/src/preferences/user.js b/src/preferences/user.js deleted file mode 100644 index 64dcb0a7..00000000 --- a/src/preferences/user.js +++ /dev/null @@ -1,24 +0,0 @@ -// -// export class UserPreferences { -// constructor() { -// this.preferences = JSON.parse(localStorage.getItem('userPreferences')) || {}; -// } -// -// set(key, value) { -// this.preferences[key] = value; -// this.save(); -// } -// -// get(key) { -// return this.preferences[key]; -// } -// -// save() { -// localStorage.setItem('userPreferences', JSON.stringify(this.preferences)); -// } -// -// clear() { -// localStorage.removeItem('userPreferences'); -// this.preferences = {}; -// } -// } diff --git a/src/router.js b/src/router.js deleted file mode 100644 index 3b2f3a08..00000000 --- a/src/router.js +++ /dev/null @@ -1,79 +0,0 @@ -import { MainPage } from "./pages/mainPage.js"; -import { loginHandles, LoginPage } from "./pages/loginPage.js"; -import { ProfilePage } from "./pages/profilePage.js"; -import { ErrorPage } from "./pages/errorPage.js"; - -// 초기 URL 모드 -let isHashMode = false; - -// 링크 이벤트 처리 -document.addEventListener("click", (e) => { - const target = e.target.closest("a"); - if (target) { - e.preventDefault(); - e.stopPropagation(); - const href = target.getAttribute("href"); - if (href) { - navigateTo(href); - } - } -}); - -const Routes = { - "/": () => MainPage(), - "/login": () => LoginPage(), - "/profile": () => ProfilePage(), -}; - -// 현재 경로 계산 -const getCurrentPath = () => { - if (isHashMode) { - const hash = window.location.hash.slice(1); // # 제거 - return hash || "/"; - } else { - return window.location.pathname; - } -}; - -// 공통 라우팅 처리 -export const resolveRoute = (isHash = false) => { - isHashMode = isHash; - const path = getCurrentPath(); - const user = localStorage.getItem("user") - ? JSON.parse(localStorage.getItem("user")) - : null; - const root = document.getElementById("root"); - - // 인증 경로 가드 - if (path === "/profile" && user === null) { - navigateTo("/login"); - return; - } - if (path === "/login" && user !== null) { - navigateTo("/"); - return; - } - - const route = Routes[path]; - - if (route) { - root.innerHTML = route(); - } else { - root.innerHTML = ErrorPage(); - } - - // 로그인 이벤트 핸들러 추가 - if (path === "/login") { - loginHandles(); - } -}; - -// 페이지 이동 함수 -export const navigateTo = (path) => { - if (isHashMode) { - window.location.hash = `#${path}`; - } else { - window.history.pushState(null, null, path); - } - resolveRoute(isHashMode); -}; diff --git a/src/router/router.js b/src/router/router.js new file mode 100644 index 00000000..82bd67d6 --- /dev/null +++ b/src/router/router.js @@ -0,0 +1,47 @@ +import { ErrorPage } from "../pages/errorPage.js"; +import { getLocalStorage } from "../storage/storage.js"; +import { eventRegister, Routes } from "./routes.js"; + +// 초기 URL 모드 +let isHashMode = false; + +const getCurrentPath = () => { + if (isHashMode) { + return window.location.hash.slice(1) || "/"; + } else { + return window.location.pathname; + } +}; + +export const resolveRoute = (isHash = false) => { + isHashMode = isHash; + const path = getCurrentPath(); + const user = getLocalStorage("user"); + const root = document.getElementById("root"); + + if (path === "/profile" && !user) { + navigateTo("/login"); + return; + } + if (path === "/login" && user) { + navigateTo("/"); + return; + } + + const route = Routes[path]; + if (route) { + root.innerHTML = route(); + eventRegister(path); + } else { + root.innerHTML = ErrorPage(); + } +}; + +export const navigateTo = (path) => { + if (isHashMode) { + window.location.hash = `#${path}`; + } else { + window.history.pushState(null, null, path); + } + resolveRoute(isHashMode); +}; diff --git a/src/router/routes.js b/src/router/routes.js new file mode 100644 index 00000000..611e57a2 --- /dev/null +++ b/src/router/routes.js @@ -0,0 +1,33 @@ +import { MainPage } from "../pages/mainPage.js"; +import { LoginPage } from "../pages/loginPage.js"; +import { ProfilePage } from "../pages/profilePage.js"; +import { mainEvents } from "../events/mainEvents.js"; +import { loginEvents } from "../events/loginEvents.js"; + +export const PATHS = { + MAIN: "/", + LOGIN: "/login", + PROFILE: "/profile", +}; + +export const Routes = { + [PATHS.MAIN]: () => MainPage(), + [PATHS.LOGIN]: () => LoginPage(), + [PATHS.PROFILE]: () => ProfilePage(), +}; + +// 경로별 이벤트 등록 +export const eventRegister = (path) => { + switch (path) { + case PATHS.MAIN: + case PATHS.PROFILE: + mainEvents(); + break; + case PATHS.LOGIN: + loginEvents(); + break; + default: + console.warn(`No events to register for path: ${path}`); + break; + } +}; diff --git a/src/storage/storage.js b/src/storage/storage.js new file mode 100644 index 00000000..36907bb4 --- /dev/null +++ b/src/storage/storage.js @@ -0,0 +1,11 @@ +export const saveLocalStorage = (key, value) => { + localStorage.setItem(key, JSON.stringify(value)); +}; + +export const getLocalStorage = (key) => { + return JSON.parse(localStorage.getItem(key)); +}; + +export const clearLocalStorage = () => { + localStorage.clear(); +};