diff --git a/index.html b/index.html index 0005b871..54106799 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,12 @@ - - - - - - 항해플러스 SNS - - - + + + + + 항해플러스 + + +
- - - + + + \ No newline at end of file diff --git a/index_sample.html b/index_sample.html new file mode 100644 index 00000000..5a898542 --- /dev/null +++ b/index_sample.html @@ -0,0 +1,13 @@ + + + + + + 항해플러스 SNS + + + +
+ + + diff --git a/src/components/Footer.js b/src/components/Footer.js new file mode 100644 index 00000000..91af07c2 --- /dev/null +++ b/src/components/Footer.js @@ -0,0 +1,7 @@ +export const Footer = () => { + return ` + + `; +}; diff --git a/src/components/Header.js b/src/components/Header.js new file mode 100644 index 00000000..9b21bc42 --- /dev/null +++ b/src/components/Header.js @@ -0,0 +1,24 @@ +export const Header = (currentPath) => { + const isLoggedIn = localStorage.getItem("user"); + + return ` +
+

항해플러스

+
+ + `; +}; diff --git a/src/main.js b/src/main.js index 036c2a38..0428c8ca 100644 --- a/src/main.js +++ b/src/main.js @@ -1,241 +1,74 @@ -const MainPage = () => ` -
-
-
-

항해플러스

-
- - - -
-
- - -
- -
- -
-
- 프로필 -
-

홍길동

-

5분 전

-
-
-

오늘 날씨가 정말 좋네요. 다들 좋은 하루 보내세요!

-
- - - -
-
- -
-
- 프로필 -
-

김철수

-

15분 전

-
-
-

새로운 프로젝트를 시작했어요. 열심히 코딩 중입니다!

-
- - - -
-
- -
-
- 프로필 -
-

이영희

-

30분 전

-
-
-

오늘 점심 메뉴 추천 받습니다. 뭐가 좋을까요?

-
- - - -
-
- -
-
- 프로필 -
-

박민수

-

1시간 전

-
-
-

주말에 등산 가실 분 계신가요? 함께 가요!

-
- - - -
-
- -
-
- 프로필 -
-

정수연

-

2시간 전

-
-
-

새로 나온 영화 재미있대요. 같이 보러 갈 사람?

-
- - - -
-
-
-
- - -
-
-`; - -const ErrorPage = () => ` -
-
-

항해플러스

-

404

-

페이지를 찾을 수 없습니다

-

- 요청하신 페이지가 존재하지 않거나 이동되었을 수 있습니다. -

- - 홈으로 돌아가기 - -
-
-`; - -const LoginPage = () => ` -
-
-

항해플러스

-
-
- -
-
- -
- -
- -
-
- -
-
-
-`; - -const ProfilePage = () => ` -
-
-
-
-

항해플러스

-
- - - -
-
-

- 내 프로필 -

-
-
- - -
-
- - -
-
- - -
- -
-
-
- - -
-
-
-`; - -document.body.innerHTML = ` - ${MainPage()} - ${ProfilePage()} - ${LoginPage()} - ${ErrorPage()} -`; +import { Router } from "./router/router"; +import { MainPage } from "./pages/MainPage"; +import { LoginPage } from "./pages/LoginPage"; +import { ProfilePage } from "./pages/ProfilePage"; +import { ErrorPage } from "./pages/ErrorPage"; + +window.addEventListener("DOMContentLoaded", () => { + const rootElement = document.getElementById("root"); + if (!rootElement) { + console.error("Root element not found"); + return; + } + + const checkAuth = () => { + const user = localStorage.getItem("user"); + if (!user) { + window.history.pushState({}, "", "/login"); + render("/login"); + return false; + } + return true; + }; + + const routes = { + "/": MainPage, + "/login": () => { + if (localStorage.getItem("user")) { + window.history.pushState({}, "", "/"); + render("/"); + return; + } + return LoginPage(); + }, + "/profile": () => { + if (checkAuth()) { + return ProfilePage(); + } + }, + 404: ErrorPage, + }; + + const render = (path) => { + const component = routes[path] || routes[404]; + rootElement.innerHTML = component(); + }; + + const handleNavigation = (path) => { + window.history.pushState({}, "", path); + render(path); + }; + + // 페이지 초기 렌더링 + render(window.location.pathname); + + // popstate 이벤트 처리 (뒤로가기/앞으로가기) + window.addEventListener("popstate", () => { + render(window.location.pathname); + }); + + // 모든 링크 클릭 이벤트 처리 + document.addEventListener("click", (e) => { + const anchor = e.target.closest("a"); + if (anchor && anchor.getAttribute("href")) { + e.preventDefault(); + const href = anchor.getAttribute("href"); + if (href !== "#") { + handleNavigation(href); + } + } + }); + + const router = new Router(routes); + router.addEventListeners(); +}); diff --git a/src/main_sample.js b/src/main_sample.js new file mode 100644 index 00000000..036c2a38 --- /dev/null +++ b/src/main_sample.js @@ -0,0 +1,241 @@ +const MainPage = () => ` +
+
+
+

항해플러스

+
+ + + +
+
+ + +
+ +
+ +
+
+ 프로필 +
+

홍길동

+

5분 전

+
+
+

오늘 날씨가 정말 좋네요. 다들 좋은 하루 보내세요!

+
+ + + +
+
+ +
+
+ 프로필 +
+

김철수

+

15분 전

+
+
+

새로운 프로젝트를 시작했어요. 열심히 코딩 중입니다!

+
+ + + +
+
+ +
+
+ 프로필 +
+

이영희

+

30분 전

+
+
+

오늘 점심 메뉴 추천 받습니다. 뭐가 좋을까요?

+
+ + + +
+
+ +
+
+ 프로필 +
+

박민수

+

1시간 전

+
+
+

주말에 등산 가실 분 계신가요? 함께 가요!

+
+ + + +
+
+ +
+
+ 프로필 +
+

정수연

+

2시간 전

+
+
+

새로 나온 영화 재미있대요. 같이 보러 갈 사람?

+
+ + + +
+
+
+
+ + +
+
+`; + +const ErrorPage = () => ` +
+
+

항해플러스

+

404

+

페이지를 찾을 수 없습니다

+

+ 요청하신 페이지가 존재하지 않거나 이동되었을 수 있습니다. +

+ + 홈으로 돌아가기 + +
+
+`; + +const LoginPage = () => ` +
+
+

항해플러스

+
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+
+`; + +const ProfilePage = () => ` +
+
+
+
+

항해플러스

+
+ + + +
+
+

+ 내 프로필 +

+
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+ + +
+
+
+`; + +document.body.innerHTML = ` + ${MainPage()} + ${ProfilePage()} + ${LoginPage()} + ${ErrorPage()} +`; diff --git a/src/pages/ErrorPage.js b/src/pages/ErrorPage.js new file mode 100644 index 00000000..c373f9eb --- /dev/null +++ b/src/pages/ErrorPage.js @@ -0,0 +1,17 @@ +export const ErrorPage = () => { + return ` +
+
+

항해플러스

+

404

+

페이지를 찾을 수 없습니다

+

+ 요청하신 페이지가 존재하지 않거나 이동되었을 수 있습니다. +

+ + 홈으로 돌아가기 + +
+
+ `; +}; diff --git a/src/pages/LoginPage.js b/src/pages/LoginPage.js new file mode 100644 index 00000000..3bcb8531 --- /dev/null +++ b/src/pages/LoginPage.js @@ -0,0 +1,25 @@ +export const LoginPage = () => { + return ` +
+
+

항해플러스

+
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+
+ `; +}; diff --git a/src/pages/MainPage.js b/src/pages/MainPage.js new file mode 100644 index 00000000..601941b0 --- /dev/null +++ b/src/pages/MainPage.js @@ -0,0 +1,109 @@ +import { Header } from "../components/Header.js"; +import { Footer } from "../components/Footer.js"; + +export const MainPage = () => { + const isLoggedIn = localStorage.getItem("user"); + + return ` +
+
+ ${Header(window.location.pathname)} +
+ ${ + isLoggedIn + ? ` +
+ + +
+ ` + : "" + } +
+ +
+
+ 프로필 +
+

홍길동

+

5분 전

+
+
+

오늘 날씨가 정말 좋네요. 다들 좋은 하루 보내세요!

+
+ + + +
+
+ +
+
+ 프로필 +
+

김철수

+

15분 전

+
+
+

새로운 프로젝트를 시작했어요. 열심히 코딩 중입니다!

+
+ + + +
+
+ +
+
+ 프로필 +
+

이영희

+

30분 전

+
+
+

오늘 점심 메뉴 추천 받습니다. 뭐가 좋을까요?

+
+ + + +
+
+ +
+
+ 프로필 +
+

박민수

+

1시간 전

+
+
+

주말에 등산 가실 분 계신가요? 함께 가요!

+
+ + + +
+
+ +
+
+ 프로필 +
+

정수연

+

2시간 전

+
+
+

새로 나온 영화 재미있대요. 같이 보러 갈 사람?

+
+ + + +
+
+
+
+ ${Footer()} +
+
+ `; +}; diff --git a/src/pages/ProfilePage.js b/src/pages/ProfilePage.js new file mode 100644 index 00000000..14894dcf --- /dev/null +++ b/src/pages/ProfilePage.js @@ -0,0 +1,154 @@ +/* import { Header } from "../components/Header.js"; +import { Footer } from "../components/Footer.js"; + +// 프로필 페이지 컴포넌트 +export const ProfilePage = () => { + const user = JSON.parse(localStorage.getItem("user")); + const username = user.username; + + return ` +
+
+
+ ${Header(window.location.pathname)} + +
+
+

+ 내 프로필 +

+
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+ ${Footer()} +
+
+
+ `; +}; + */ + +import { Header } from "../components/Header.js"; +import { Footer } from "../components/Footer.js"; + +// 프로필 페이지 컴포넌트 +export const ProfilePage = () => { + const user = JSON.parse(localStorage.getItem("user")); + const username = user ? user.username : ""; // username이 없을 경우 빈 문자열 + + const email = JSON.parse(localStorage.getItem("email")); + const userEmail = email ? email.userEmail : ""; + + const text = JSON.parse(localStorage.getItem("text")); + const userText = text ? text.userIntroTxt : ""; + + return ` +
+
+
+ ${Header(window.location.pathname)} + +
+
+

+ 내 프로필 +

+
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+ + ${Footer()} +
+
+
+ `; +}; diff --git a/src/router/router.js b/src/router/router.js new file mode 100644 index 00000000..a8e4692f --- /dev/null +++ b/src/router/router.js @@ -0,0 +1,100 @@ +export class Router { + constructor(routes) { + this.routes = routes; + this.rootElement = document.getElementById("root"); + + if (!this.rootElement) { + throw new Error("Root element not found"); + } + + // 페이지 초기 렌더링 + this.render(window.location.pathname); + + // popstate 이벤트 처리 (뒤로가기/앞으로가기) + window.addEventListener("popstate", () => { + this.render(window.location.pathname); + }); + + // 모든 링크 클릭 이벤트 처리 + document.addEventListener("click", (e) => { + const anchor = e.target.closest("a"); + if (anchor && anchor.getAttribute("href")) { + e.preventDefault(); + const href = anchor.getAttribute("href"); + if (href !== "#") { + this.navigate(href); + } + } + }); + } + + // 경로 이동 + navigate(path) { + window.history.pushState({}, "", path); + this.render(path); + } + + // 현재 경로에 맞는 컴포넌트 렌더링 + render(path) { + const component = this.routes[path] || this.routes[404]; + if (typeof component === "function") { + this.rootElement.innerHTML = component(); + this.addEventListeners(); // 렌더링 후 이벤트 리스너 추가 + } else { + console.error("Invalid route component"); + } + } + + // 이벤트 리스너 추가 + addEventListeners() { + // 로그아웃 기능 + const logoutBtn = document.getElementById("logout-btn"); + if (logoutBtn) { + logoutBtn.addEventListener("click", () => { + localStorage.removeItem("user"); // 사용자 아이디 제거 + localStorage.removeItem("email"); // 사용자 이메일 제거 + localStorage.removeItem("text"); // 사용자 자기소개 제거 + this.navigate("/login"); // 로그인 페이지로 리다이렉트 + }); + } + + // 로그인 기능 + const loginForm = document.querySelector(".login-btn"); + if (loginForm) { + loginForm.addEventListener("click", (e) => { + e.preventDefault(); + const username = document + .querySelector('input[type="text"]') + .value.trim(); + if (username) { + localStorage.setItem("user", JSON.stringify({ username })); + this.navigate("/profile"); + } + }); + } + + //프로필 업데이트 + const profileUpdate = document.querySelector(".profile-btn"); + if (profileUpdate) { + profileUpdate.addEventListener("click", (e) => { + e.preventDefault(); + const username = document + .querySelector('input[type="text"]') + .value.trim(); + const userEmail = document + .querySelector('input[type="email"]') + .value.trim(); + const userIntroTxt = document.querySelector(".intro-text").value.trim(); + if (userEmail && userIntroTxt) { + localStorage.setItem("user", JSON.stringify({ username })); + localStorage.setItem("email", JSON.stringify({ userEmail })); + localStorage.setItem("text", JSON.stringify({ userIntroTxt })); + + alert("프로필이 업데이트되었습니다."); + } else { + alert("모든 필드를 입력해주세요."); + } + }); + } + } +} diff --git a/src/store/state.js b/src/store/state.js new file mode 100644 index 00000000..9dd538ea --- /dev/null +++ b/src/store/state.js @@ -0,0 +1,9 @@ +/* export const state = { + user: null, + isLoggedIn: false +}; + +export function updateState(newState) { + Object.assign(state, newState); + render(); +} */