Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2팀 노정우] [Chapter 1-1] 프레임워크 없이 SPA 만들기 #36

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
모듈 분리
  • Loading branch information
melroh629 committed Dec 20, 2024
commit 8ebf1dbbb8d0ed39d212168288c4861f05d32eb5
7 changes: 7 additions & 0 deletions src/components/Footer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const Footer = () => {
return `
<footer class="bg-gray-200 p-4 text-center">
<p>&copy; 2024 항해플러스. All rights reserved.</p>
</footer>
`;
};
7 changes: 7 additions & 0 deletions src/components/Header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const Header = () => {
return `
<header class="bg-blue-600 text-white p-4 sticky top-0">
<h1 class="text-2xl font-bold">항해플러스</h1>
</header>
`;
};
2 changes: 2 additions & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./Header";
export * from "./Footer";
53 changes: 43 additions & 10 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,68 @@
import { router } from "./router";

// 네비게이션 상태 업데이트 함수
const updateNavigation = () => {
const userId = localStorage.getItem("userId");
const profileMenu = document.querySelector('a[href="/profile"]');
const loginLogoutButton = document.querySelector("#logout");

if (userId) {
// 로그인 상태
if (profileMenu) profileMenu.style.display = "block";
if (loginLogoutButton) {
loginLogoutButton.setAttribute("href", "#logout");
loginLogoutButton.textContent = "로그아웃";
}
} else {
// 비로그인 상태

if (loginLogoutButton) {
loginLogoutButton.setAttribute("href", "/login");
loginLogoutButton.textContent = "로그인";
}
}
};

document.addEventListener("DOMContentLoaded", () => {
// 초기 경로 렌더링
router.handleRoute(window.location.pathname);
updateNavigation();

// 네비게이션 클릭 이벤트 처리
document.body.addEventListener("click", (e) => {
if (e.target.tagName === "A") {
e.preventDefault();
const path = e.target.pathname;
router.navigateTo(path);
const path = e.target.getAttribute("href");

if (path === "#logout") {
localStorage.removeItem("userId");
router.navigateTo("/");
updateNavigation();
} else {
router.navigateTo(path);
updateNavigation();
}
}

// 로그인 로직
if (e.target.id === "logIn") {
e.preventDefault();
const userId = document.getElementById("userId").value;
const userId = document.getElementById("username").value;
const password = document.getElementById("password").value;

if (userId && password) {
localStorage.setItem("userId", JSON.stringify({ userId }));
localStorage.setItem("userId", userId);
router.navigateTo("/profile");
updateNavigation();
} else {
alert("아이디 또는 비밀번호를 입력해주세요");
alert("아이디 또는 비밀번호를 입력해주세요.");
}
}

// 로그아웃 로직
if (e.target.id === "logOut") {
//로그아웃 로직
if (e.target.id === "logout") {
e.preventDefault();
localStorage.removeItem("userId");
router.navigateTo("/login");
router.navigateTo("/");
updateNavigation();
}
});
});
4 changes: 2 additions & 2 deletions src/pages/LoginPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ export const LoginPage = () => `
<main class="bg-gray-100 flex items-center justify-center min-h-screen">
<div class="bg-white p-8 rounded-lg shadow-md w-full max-w-md">
<h1 class="text-2xl font-bold text-center text-blue-600 mb-8">항해플러스</h1>
<form>
<form id="login-form">
<div class="mb-4">
<input type="text" id="userId" placeholder="이메일 또는 전화번호" class="w-full p-2 border rounded" required>
<input type="text" id="username" placeholder="이메일 또는 전화번호" class="w-full p-2 border rounded" required>
</div>
<div class="mb-6">
<input type="password" id="password" placeholder="비밀번호" class="w-full p-2 border rounded" required>
Expand Down
17 changes: 7 additions & 10 deletions src/pages/MainPage.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { Header, Footer } from "../components";

export const MainPage = () => `
<div class="bg-gray-100 min-h-screen flex justify-center">
<div class="max-w-md w-full">
<header class="bg-blue-600 text-white p-4 sticky top-0">
<h1 class="text-2xl font-bold">항해플러스</h1>
</header>

${Header()}
<nav class="bg-white shadow-md p-2 sticky top-14">
<ul class="flex justify-around">
<li><a href="/" class="text-blue-600">홈</a></li>
<li><a href="/profile" class="text-gray-600">프로필</a></li>
<li><a href="/logIn" id="logOut" class="text-gray-600">로그아웃</a></li>
<li><a href="/" class="text-gray-600">홈</a></li>
<li><a href="/profile" class="text-gray-600">프로필</a></li>
<li><a href="/login" class="text-gray-600" id="logout">로그아웃</a></li>
</ul>
</nav>

Expand Down Expand Up @@ -103,9 +102,7 @@ export const MainPage = () => `
</div>
</main>

<footer class="bg-gray-200 p-4 text-center">
<p>&copy; 2024 항해플러스. All rights reserved.</p>
</footer>
${Footer()}
</div>
</div>
`;
40 changes: 23 additions & 17 deletions src/pages/ProfilePage.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Header, Footer } from "../components";
import { router } from "../router";

class Profile {
Expand Down Expand Up @@ -29,16 +30,13 @@ export const ProfilePage = () => {
<div id="root">
<div class="bg-gray-100 min-h-screen flex justify-center">
<div class="max-w-md w-full">
<header class="bg-blue-600 text-white p-4 sticky top-0">
<h1 class="text-2xl font-bold">항해플러스</h1>
</header>

${Header()}
<nav class="bg-white shadow-md p-2 sticky top-14">
<ul class="flex justify-around">
<li><a href="/" class="text-gray-600">홈</a></li>
<li><a href="/profile" class="text-blue-600">프로필</a></li>
<li><a href="/login" class="text-gray-600">로그아웃</a></li>
</ul>
<li><a href="/" class="text-gray-600">홈</a></li>
<li><a href="/profile" class="text-gray-600">프로필</a></li>
<li><a href="/login" class="text-gray-600" id="logout">로그아웃</a></li>
</ul>
</nav>

<main class="p-4">
Expand Down Expand Up @@ -98,9 +96,7 @@ export const ProfilePage = () => {
</div>
</main>

<footer class="bg-gray-200 p-4 text-center">
<p>&copy; 2024 항해플러스. All rights reserved.</p>
</footer>
${Footer()}
</div>
</div>
</div>
Expand All @@ -115,16 +111,26 @@ export const attachProfileFormListeners = () => {
return;
}

// 추가: username, email, bio 필드가 존재하는지 확인
const usernameField = form.username;
const emailField = form.email;
const bioField = form.bio;

if (!usernameField || !emailField || !bioField) {
console.error("One or more input fields are missing!");
return;
}

const { userName, email, bio } = profile.getProfile();
form.username.value = userName;
form.email.value = email;
form.bio.value = bio;
usernameField.value = userName;
emailField.value = email;
bioField.value = bio;

form.addEventListener("submit", (e) => {
e.preventDefault();
const userName = form.username.value.trim();
const email = form.email.value.trim();
const bio = form.bio.value.trim();
const userName = usernameField.value.trim();
const email = emailField.value.trim();
const bio = bioField.value.trim();

if (!userName || !email || !bio) {
alert("모든 필드를 채워주세요.");
Expand Down
23 changes: 10 additions & 13 deletions src/router/Router.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { MainPage, ProfilePage, LoginPage, ErrorPage } from "../pages";
import { attachProfileFormListeners } from "../pages/ProfilePage";

export class Router {
constructor() {
Expand All @@ -11,10 +12,8 @@ export class Router {
}

navigateTo(path) {
if (this.beforeNavigate(path)) {
history.pushState(null, "", path);
this.handleRoute(path);
}
history.pushState(null, "", path);
this.handleRoute(path);
}

handlePopState() {
Expand All @@ -28,23 +27,21 @@ export class Router {
if (handler && appRoot) {
appRoot.innerHTML = handler();

// 경로별로 이벤트 등록 처리
// 각 페이지 렌더링 후 필요한 작업 수행
if (path === "/profile") {
import("../pages/ProfilePage.js").then((module) => {
module.attachProfileFormListeners();
});
attachProfileFormListeners(); // 프로필 페이지에 이벤트 리스너 추가
}
} else {
appRoot.innerHTML = ErrorPage();
} else if (appRoot) {
appRoot.innerHTML = ErrorPage(); // 404 페이지 처리
}
}

beforeNavigate(path) {
const userId = localStorage.getItem("userId");

// 비로그인 상태에서 /profile 접근 시 로그인 페이지로 리다이렉트
if (path === "/profile" && !userId) {
alert("로그인이 필요합니다.");
this.navigateTo("/login");
return false;
return false; // 현재 경로를 중단
}
return true;
}
Expand Down
Loading