From 67775ff16ccf82800e09ad8afb08b28dcfe73937 Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Thu, 6 Jul 2023 15:27:32 +0900 Subject: [PATCH 01/25] =?UTF-8?q?[FEAT]=20=EA=B3=BC=EC=A0=9C=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85=20=EC=99=84=EB=A3=8C=20=EB=B0=8F=20API=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 9 ++++ src/App.js | 35 +++++++++++++ src/Editor.js | 50 ++++++++++++++++++ src/LinkButton.js | 17 ++++++ src/PostEditPage.js | 124 ++++++++++++++++++++++++++++++++++++++++++++ src/PostList.js | 32 ++++++++++++ src/PostPage.js | 30 +++++++++++ src/api.js | 22 ++++++++ src/main.js | 5 ++ src/router.js | 22 ++++++++ src/storage.js | 17 ++++++ 11 files changed, 363 insertions(+) create mode 100644 index.html create mode 100644 src/App.js create mode 100644 src/Editor.js create mode 100644 src/LinkButton.js create mode 100644 src/PostEditPage.js create mode 100644 src/PostList.js create mode 100644 src/PostPage.js create mode 100644 src/api.js create mode 100644 src/main.js create mode 100644 src/router.js create mode 100644 src/storage.js diff --git a/index.html b/index.html new file mode 100644 index 00000000..2214f5e8 --- /dev/null +++ b/index.html @@ -0,0 +1,9 @@ + + + Notion Project + + +
+ + + diff --git a/src/App.js b/src/App.js new file mode 100644 index 00000000..e46b6bf2 --- /dev/null +++ b/src/App.js @@ -0,0 +1,35 @@ +import PostEditPage from "./PostEditPage.js"; +import PostPage from "./PostPage.js"; +import { initRouter } from "./router.js"; + +export default function App({ $target }) { + const postPage = new PostPage({ + $target, + }); + const postEditPage = new PostEditPage({ + $target, + initialState: { + postId: "new", + post: { + title: "", + content: "", + }, + }, + }); + + this.route = () => { + $target.innerHTML = ""; + const { pathname } = window.location; + + if (pathname === "/") { + postPage.setState(); + } else if (pathname.indexOf("/post/") === 0) { + const [, , postId] = pathname.split("/"); + postEditPage.setState({ postId }); + } + }; + + this.route(); + + initRouter(() => this.route()) +} diff --git a/src/Editor.js b/src/Editor.js new file mode 100644 index 00000000..f7756f73 --- /dev/null +++ b/src/Editor.js @@ -0,0 +1,50 @@ +export default function Editor({ + $target, + initialState = { + title: "", + content: "", + }, + onEditing, +}) { + const $editor = document.createElement("div"); + + let isinitialize = false; + + this.state = initialState; + + $target.appendChild($editor); + + this.setState = (nextState) => { + this.state = nextState; + $editor.querySelector("[name=title]").value = this.state.title; + $editor.querySelector("[name=content]").value = this.state.content; + this.render(); + }; + + this.render = () => { + if (!isinitialize) { + $editor.innerHTML = ` + + + `; + isinitialize = true; + } + }; + this.render(); + + $editor.addEventListener("keyup", (e) => { + const { target } = e; + + const name = target.getAttribute("name"); + + if (this.state[name] !== undefined) { + const nextState = { + ...this.state, + [name]: target.value, + }; + + this.setState(nextState); + onEditing(this.state); + } + }); +} diff --git a/src/LinkButton.js b/src/LinkButton.js new file mode 100644 index 00000000..d102e552 --- /dev/null +++ b/src/LinkButton.js @@ -0,0 +1,17 @@ +import { push } from "./router.js"; + +export default function LinkButton({ $target, initialState }) { + this.state = initialState; + const $linkButton = document.createElement("button"); + $target.appendChild($linkButton); + + this.render = () => { + $linkButton.textContent = this.state.text; + }; + + this.render(); + + $linkButton.addEventListener("click", () => { + push(this.state.link); + }); +} diff --git a/src/PostEditPage.js b/src/PostEditPage.js new file mode 100644 index 00000000..27dd6201 --- /dev/null +++ b/src/PostEditPage.js @@ -0,0 +1,124 @@ +import { request } from "./api.js"; +import Editor from "./Editor.js"; +import LinkButton from "./LinkButton.js"; +import { getItem, removeItem, setItem } from "./storage.js"; + +export default function PostEditPage({ $target, initialState }) { + const $page = document.createElement("div"); + + this.state = initialState; + + let postLocalSaveKey = `temp-post-${this.state.postId}`; + + const post = getItem(postLocalSaveKey, { + title: "", + content: "", + }); + + let timer = null; + + const editor = new Editor({ + $target: $page, + initialState: post, + onEditing: (post) => { + if (timer !== null) { + clearTimeout(timer); + } + timer = setTimeout(async () => { + setItem(postLocalSaveKey, { + ...post, + tempSaveDate: new Date(), + }); + + const isNew = this.state.postId === "new"; + if (isNew) { + const createdPost = await request("/post", { + method: "POST", + body: JSON.stringify(post), + }); + history.replaceState(null, null, `/post/${createdPost.id}`); + removeItem(postLocalSaveKey); + + this.setState({ + postId: createdPost.id, + }); + } else { + await request(`/post/${post.id}`, { + method: "PUT", + body: JSON.stringify(post), + }); + removeItem(postLocalSaveKey); + } + }, 2000); + }, + }); + + this.setState = async (nextState) => { + if (this.state.postId !== nextState.postId) { + postLocalSaveKey = `temp-post-${nextState.postId}`; + this.state = nextState; + + if (this.state.postId === "new") { + const post = getItem(postLocalSaveKey, { + title: "", + content: "", + }); + this.render(); + editor.setState(post); + } else { + await fetchPost(); + } + return; + } + + this.state = nextState; + this.render(); + + editor.setState( + this.state.post || { + title: "", + content: "", + } + ); + }; + + this.render = () => { + $target.appendChild($page); + }; + + const fetchPost = async () => { + const { postId } = this.state; + + if (postId !== "new") { + const post = await request(`/posts/${postId}`); + + const tempPost = getItem(postLocalSaveKey, { + title: "", + content: "", + }); + + if (tempPost.tempSaveDate && tempPost.tempSaveDate > post.updated_at) { + if (confirm("저장되지 않은 임시 데이터가 있습니다. 불러올까요?")) { + this.setState({ + ...this.state, + post: tempPost, + }); + return; + } + } + + this.setState({ + ...this.state, + post, + }); + } + }; + + new LinkButton({ + $target: $page, + initialState: { + text: "목록으로 이동", + link: "/", + }, + }); +} diff --git a/src/PostList.js b/src/PostList.js new file mode 100644 index 00000000..1a7b1d10 --- /dev/null +++ b/src/PostList.js @@ -0,0 +1,32 @@ +import { push } from "./router.js"; + +export default function PostList({ $target, initialState }) { + const $postList = document.createElement("div"); + $target.appendChild($postList); + + this.state = initialState; + + this.setState = (nextState) => { + this.state = nextState; + this.render(); + }; + + this.render = () => { + $postList.innerHTML = ` + + `; + }; + + this.render(); + + $postList.addEventListener("click", (e) => { + const $li = e.target.closest("li"); + + if ($li) { + const { id } = $li.dataset; + push(`/post/${id}`); + } + }); +} diff --git a/src/PostPage.js b/src/PostPage.js new file mode 100644 index 00000000..0e294503 --- /dev/null +++ b/src/PostPage.js @@ -0,0 +1,30 @@ +import { request } from "./api.js"; +import LinkButton from "./LinkButton.js"; +import PostList from "./PostList.js"; + +export default function PostPage({ $target }) { + const $page = document.createElement("div"); + + const postList = new PostList({ + $target: $page, + initialState: [], + }); + + new LinkButton({ + $target: $page, + initialState: { + text: "New Post", + link: "/post/new", + }, + }); + + this.setState = async () => { + const post = await request("post"); + postList.setState(post); + this.render(); + }; + + this.render = async () => { + $target.appendChild($page); + }; +} diff --git a/src/api.js b/src/api.js new file mode 100644 index 00000000..e08eab77 --- /dev/null +++ b/src/api.js @@ -0,0 +1,22 @@ +export const API_END_POINT = "https://kdt-frontend.programmers.co.kr/documents"; + +export const request = async (documentsId, options = {}) => { + try { + const res = await fetch(`${API_END_POINT}${documentsId}`, { + ...options, + headers: { + "Content-Type": "application/json", + "x-username": "hyun", + }, + }); + + if (res.ok) { + return await res.json(); + } + + throw new Error("API 처리중 에러가 발생했습니다."); + } catch (e) { + alert(e.message); + console.error(); + } +}; diff --git a/src/main.js b/src/main.js new file mode 100644 index 00000000..3876e42a --- /dev/null +++ b/src/main.js @@ -0,0 +1,5 @@ +import App from "./App.js"; + +const $target = document.querySelector("#app"); + +new App({ $target }); diff --git a/src/router.js b/src/router.js new file mode 100644 index 00000000..2c83421c --- /dev/null +++ b/src/router.js @@ -0,0 +1,22 @@ +const ROUTE_CHANGE_EVENT_NAME = "route-change"; + +export const initRouter = (onRoute) => { + window.addEventListener(ROUTE_CHANGE_EVENT_NAME, (e) => { + const { nextUrl } = e.detail; + + if (nextUrl) { + history.pushState(null, null, nextUrl); + onRoute() + } + }); +}; + +export const push = (nextUrl) => { + window.dispatchEvent( + new CustomEvent("route-change", { + detail: { + nextUrl, + }, + }) + ); +}; diff --git a/src/storage.js b/src/storage.js new file mode 100644 index 00000000..dcf55d22 --- /dev/null +++ b/src/storage.js @@ -0,0 +1,17 @@ +const storage = window.localStorage; + +export const getItem = (key, defaultValue) => { + try { + const storageValue = storage.getItem(key); + return storageValue ? JSON.parse(storageValue) : defaultValue; + } catch (e) { + return defaultValue; + } +}; +export const setItem = (key, value) => { + storage.setItem(key, JSON.stringify(value)); +}; + +export const removeItem = (key) => { + storage.removeItem(key); +}; From 53e14ec8b47803e15c173ca205d45e5d6383e154 Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Thu, 6 Jul 2023 15:34:28 +0900 Subject: [PATCH 02/25] =?UTF-8?q?[FIX]=20Router=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/LinkButton.js | 4 ++-- src/PostEditPage.js | 4 ++-- src/PostList.js | 4 ++-- src/router.js | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/LinkButton.js b/src/LinkButton.js index d102e552..9812c6e2 100644 --- a/src/LinkButton.js +++ b/src/LinkButton.js @@ -1,4 +1,4 @@ -import { push } from "./router.js"; +import { pushRouter, pushRouter } from "./router.js"; export default function LinkButton({ $target, initialState }) { this.state = initialState; @@ -12,6 +12,6 @@ export default function LinkButton({ $target, initialState }) { this.render(); $linkButton.addEventListener("click", () => { - push(this.state.link); + pushRouter(this.state.link); }); } diff --git a/src/PostEditPage.js b/src/PostEditPage.js index 27dd6201..406e2057 100644 --- a/src/PostEditPage.js +++ b/src/PostEditPage.js @@ -32,7 +32,7 @@ export default function PostEditPage({ $target, initialState }) { const isNew = this.state.postId === "new"; if (isNew) { - const createdPost = await request("/post", { + const createdPost = await request("", { method: "POST", body: JSON.stringify(post), }); @@ -43,7 +43,7 @@ export default function PostEditPage({ $target, initialState }) { postId: createdPost.id, }); } else { - await request(`/post/${post.id}`, { + await request(`/${post.id}`, { method: "PUT", body: JSON.stringify(post), }); diff --git a/src/PostList.js b/src/PostList.js index 1a7b1d10..ccdda4bb 100644 --- a/src/PostList.js +++ b/src/PostList.js @@ -1,4 +1,4 @@ -import { push } from "./router.js"; +import { pushRouter } from "./router.js"; export default function PostList({ $target, initialState }) { const $postList = document.createElement("div"); @@ -26,7 +26,7 @@ export default function PostList({ $target, initialState }) { if ($li) { const { id } = $li.dataset; - push(`/post/${id}`); + pushRouter(`/post/${id}`); } }); } diff --git a/src/router.js b/src/router.js index 2c83421c..4a728e8d 100644 --- a/src/router.js +++ b/src/router.js @@ -11,7 +11,7 @@ export const initRouter = (onRoute) => { }); }; -export const push = (nextUrl) => { +export const pushRouter = (nextUrl) => { window.dispatchEvent( new CustomEvent("route-change", { detail: { From e741067c5b72f9acdd07ec26621573d930a01fca Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Thu, 6 Jul 2023 16:05:10 +0900 Subject: [PATCH 03/25] =?UTF-8?q?[FIX]=20API=20=ED=86=B5=EC=8B=A0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/LinkButton.js | 2 +- src/PostEditPage.js | 11 +++++++---- src/PostList.js | 3 ++- src/PostPage.js | 2 +- src/api.js | 4 ++-- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/LinkButton.js b/src/LinkButton.js index 9812c6e2..42cac950 100644 --- a/src/LinkButton.js +++ b/src/LinkButton.js @@ -1,4 +1,4 @@ -import { pushRouter, pushRouter } from "./router.js"; +import { pushRouter } from "./router.js"; export default function LinkButton({ $target, initialState }) { this.state = initialState; diff --git a/src/PostEditPage.js b/src/PostEditPage.js index 406e2057..0f7f173d 100644 --- a/src/PostEditPage.js +++ b/src/PostEditPage.js @@ -32,11 +32,14 @@ export default function PostEditPage({ $target, initialState }) { const isNew = this.state.postId === "new"; if (isNew) { - const createdPost = await request("", { + const createdPost = await request('', { method: "POST", - body: JSON.stringify(post), + body: { + title: post.title, + parent: null, + }, }); - history.replaceState(null, null, `/post/${createdPost.id}`); + history.replaceState(null, null, `/${createdPost.id}`); removeItem(postLocalSaveKey); this.setState({ @@ -90,7 +93,7 @@ export default function PostEditPage({ $target, initialState }) { const { postId } = this.state; if (postId !== "new") { - const post = await request(`/posts/${postId}`); + const post = await request(`/${postId}`); const tempPost = getItem(postLocalSaveKey, { title: "", diff --git a/src/PostList.js b/src/PostList.js index ccdda4bb..551d5781 100644 --- a/src/PostList.js +++ b/src/PostList.js @@ -24,9 +24,10 @@ export default function PostList({ $target, initialState }) { $postList.addEventListener("click", (e) => { const $li = e.target.closest("li"); + console.log($li) if ($li) { const { id } = $li.dataset; - pushRouter(`/post/${id}`); + pushRouter(`/${id}`); } }); } diff --git a/src/PostPage.js b/src/PostPage.js index 0e294503..ff36c8c6 100644 --- a/src/PostPage.js +++ b/src/PostPage.js @@ -19,7 +19,7 @@ export default function PostPage({ $target }) { }); this.setState = async () => { - const post = await request("post"); + const post = await request(); postList.setState(post); this.render(); }; diff --git a/src/api.js b/src/api.js index e08eab77..016c2929 100644 --- a/src/api.js +++ b/src/api.js @@ -1,11 +1,11 @@ export const API_END_POINT = "https://kdt-frontend.programmers.co.kr/documents"; -export const request = async (documentsId, options = {}) => { +export const request = async (documentsId = '', options = {}) => { try { const res = await fetch(`${API_END_POINT}${documentsId}`, { ...options, headers: { - "Content-Type": "application/json", + //"Content-Type": "application/json", "x-username": "hyun", }, }); From 03f954ad9976dd185fbfa577d3ef6b225e948a7b Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Thu, 6 Jul 2023 18:10:25 +0900 Subject: [PATCH 04/25] =?UTF-8?q?[FIX]=20API=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 6 ++++-- src/PostEditPage.js | 2 +- src/PostList.js | 1 - src/PostPage.js | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/App.js b/src/App.js index e46b6bf2..a3fac931 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,5 @@ import PostEditPage from "./PostEditPage.js"; +import PostList from "./PostList.js"; import PostPage from "./PostPage.js"; import { initRouter } from "./router.js"; @@ -6,6 +7,7 @@ export default function App({ $target }) { const postPage = new PostPage({ $target, }); + const postEditPage = new PostEditPage({ $target, initialState: { @@ -23,8 +25,8 @@ export default function App({ $target }) { if (pathname === "/") { postPage.setState(); - } else if (pathname.indexOf("/post/") === 0) { - const [, , postId] = pathname.split("/"); + } else if (pathname.indexOf("/") === 0) { + const [, postId] = pathname.split("/"); postEditPage.setState({ postId }); } }; diff --git a/src/PostEditPage.js b/src/PostEditPage.js index 0f7f173d..df535f65 100644 --- a/src/PostEditPage.js +++ b/src/PostEditPage.js @@ -46,7 +46,7 @@ export default function PostEditPage({ $target, initialState }) { postId: createdPost.id, }); } else { - await request(`/${post.id}`, { + await request(`/${this.state.postId}`, { method: "PUT", body: JSON.stringify(post), }); diff --git a/src/PostList.js b/src/PostList.js index 551d5781..105a163e 100644 --- a/src/PostList.js +++ b/src/PostList.js @@ -24,7 +24,6 @@ export default function PostList({ $target, initialState }) { $postList.addEventListener("click", (e) => { const $li = e.target.closest("li"); - console.log($li) if ($li) { const { id } = $li.dataset; pushRouter(`/${id}`); diff --git a/src/PostPage.js b/src/PostPage.js index ff36c8c6..db6811f6 100644 --- a/src/PostPage.js +++ b/src/PostPage.js @@ -14,7 +14,7 @@ export default function PostPage({ $target }) { $target: $page, initialState: { text: "New Post", - link: "/post/new", + link: "/new", }, }); From 21ab7c45867ec8867f84492605112061dc064d96 Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Thu, 6 Jul 2023 23:58:10 +0900 Subject: [PATCH 05/25] =?UTF-8?q?[FIX]=20=EC=83=81=ED=83=9C=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=20=EC=98=A4=EB=A5=98=20=ED=95=B4=EA=B2=B0=20&=20?= =?UTF-8?q?=ED=95=98=EC=9C=84=20=EB=AC=B8=EC=84=9C=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 3 ++ src/PostEditPage.js | 8 ++++-- src/PostList.js | 68 +++++++++++++++++++++++++++++++++++++++++---- src/api.js | 5 ++-- 4 files changed, 73 insertions(+), 11 deletions(-) diff --git a/src/App.js b/src/App.js index a3fac931..31cf7c9e 100644 --- a/src/App.js +++ b/src/App.js @@ -1,3 +1,4 @@ +import { request } from "./api.js"; import PostEditPage from "./PostEditPage.js"; import PostList from "./PostList.js"; import PostPage from "./PostPage.js"; @@ -34,4 +35,6 @@ export default function App({ $target }) { this.route(); initRouter(() => this.route()) + + console.log(request()) } diff --git a/src/PostEditPage.js b/src/PostEditPage.js index df535f65..176eafcc 100644 --- a/src/PostEditPage.js +++ b/src/PostEditPage.js @@ -31,18 +31,20 @@ export default function PostEditPage({ $target, initialState }) { }); const isNew = this.state.postId === "new"; + //const pathname = window.location.href.split('/') if (isNew) { const createdPost = await request('', { method: "POST", - body: { + body: JSON.stringify({ title: post.title, parent: null, - }, + }), }); history.replaceState(null, null, `/${createdPost.id}`); removeItem(postLocalSaveKey); this.setState({ + ...post, postId: createdPost.id, }); } else { @@ -52,7 +54,7 @@ export default function PostEditPage({ $target, initialState }) { }); removeItem(postLocalSaveKey); } - }, 2000); + }, 1000); }, }); diff --git a/src/PostList.js b/src/PostList.js index 105a163e..8bcc0e18 100644 --- a/src/PostList.js +++ b/src/PostList.js @@ -1,3 +1,4 @@ +import { request } from "./api.js"; import { pushRouter } from "./router.js"; export default function PostList({ $target, initialState }) { @@ -14,19 +15,74 @@ export default function PostList({ $target, initialState }) { this.render = () => { $postList.innerHTML = `
    - ${this.state.map((post) => `
  • ${post.title}
  • `).join("")} + ${this.state + .map( + (post) => + ` +
  • + ${post.title} + + +
  • +
      + ${post.documents + .map( + (subPost) => + ` +
    • + ${subPost.title} + + +
    • + ` + ) + .join("")} +
    + ` + ) + .join("")}
`; }; this.render(); - $postList.addEventListener("click", (e) => { - const $li = e.target.closest("li"); + $postList.addEventListener("click", async (e) => { + const clickTag = e.target.localName; - if ($li) { - const { id } = $li.dataset; - pushRouter(`/${id}`); + if (clickTag === "span") { + const $span = e.target.closest("span"); + + if ($span) { + pushRouter(`/${$span.id}`); + request(`/${$span.id}`); + } + } else if (clickTag === "button") { + const $button = e.target.closest("button"); + const [commend, id] = $button.id.split("_"); + + if (commend === "createButton") { + pushRouter(`/${id}/new`); + const createdPost = await request("", { + method: "POST", + body: JSON.stringify({ + title: "제목 없음", + parent: id, + }), + }); + history.replaceState(null, null, `/${createdPost.id}`); + } else { + pushRouter(`/`); + request(`/${id}`, { + method: "DELETE", + }); + } + getDocuments(); } }); + + const getDocuments = async () => { + const documents = await request(); + this.setState(documents); + }; } diff --git a/src/api.js b/src/api.js index 016c2929..d298c808 100644 --- a/src/api.js +++ b/src/api.js @@ -1,11 +1,12 @@ export const API_END_POINT = "https://kdt-frontend.programmers.co.kr/documents"; -export const request = async (documentsId = '', options = {}) => { +export const request = async (documentsId = "", options = {}) => { + console.log('options = ', options) try { const res = await fetch(`${API_END_POINT}${documentsId}`, { ...options, headers: { - //"Content-Type": "application/json", + "Content-Type": "application/json", "x-username": "hyun", }, }); From 32d75bc4d399c60d97c4823eb35bce905c62dbb1 Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 00:00:17 +0900 Subject: [PATCH 06/25] =?UTF-8?q?[FEAT]=20=ED=95=98=EC=9C=84=20=EB=AC=B8?= =?UTF-8?q?=EC=84=9C=20=EC=88=98=EC=A0=95=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/PostList.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/PostList.js b/src/PostList.js index 8bcc0e18..ce5f1c26 100644 --- a/src/PostList.js +++ b/src/PostList.js @@ -62,7 +62,7 @@ export default function PostList({ $target, initialState }) { const [commend, id] = $button.id.split("_"); if (commend === "createButton") { - pushRouter(`/${id}/new`); + pushRouter(`/`); const createdPost = await request("", { method: "POST", body: JSON.stringify({ @@ -70,7 +70,6 @@ export default function PostList({ $target, initialState }) { parent: id, }), }); - history.replaceState(null, null, `/${createdPost.id}`); } else { pushRouter(`/`); request(`/${id}`, { From 7668c8535ab5dd294f7e699c09634dfadbb38802 Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 00:31:14 +0900 Subject: [PATCH 07/25] =?UTF-8?q?[FIX]=20console.log=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/api.js b/src/api.js index d298c808..dc4e2cda 100644 --- a/src/api.js +++ b/src/api.js @@ -1,7 +1,6 @@ export const API_END_POINT = "https://kdt-frontend.programmers.co.kr/documents"; export const request = async (documentsId = "", options = {}) => { - console.log('options = ', options) try { const res = await fetch(`${API_END_POINT}${documentsId}`, { ...options, From a4ff1d775fbeb2b79a86ee9251fb2ca3e167e382 Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 08:24:51 +0900 Subject: [PATCH 08/25] =?UTF-8?q?[FEAT]=20=ED=95=98=EC=9C=84=20=EB=AC=B8?= =?UTF-8?q?=EC=84=9C=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EB=B0=94=EB=A1=9C?= =?UTF-8?q?=EA=B0=80=EA=B8=B0=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 1 - src/PostEditPage.js | 24 ++++++++++++------------ src/PostList.js | 3 ++- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/App.js b/src/App.js index 31cf7c9e..dc0a33ff 100644 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,5 @@ import { request } from "./api.js"; import PostEditPage from "./PostEditPage.js"; -import PostList from "./PostList.js"; import PostPage from "./PostPage.js"; import { initRouter } from "./router.js"; diff --git a/src/PostEditPage.js b/src/PostEditPage.js index 176eafcc..1beafeb7 100644 --- a/src/PostEditPage.js +++ b/src/PostEditPage.js @@ -8,12 +8,12 @@ export default function PostEditPage({ $target, initialState }) { this.state = initialState; - let postLocalSaveKey = `temp-post-${this.state.postId}`; + //let postLocalSaveKey = `temp-post-${this.state.postId}`; - const post = getItem(postLocalSaveKey, { + const post = {//getItem(postLocalSaveKey, { title: "", content: "", - }); + };//); let timer = null; @@ -25,10 +25,10 @@ export default function PostEditPage({ $target, initialState }) { clearTimeout(timer); } timer = setTimeout(async () => { - setItem(postLocalSaveKey, { + /*setItem(postLocalSaveKey, { ...post, tempSaveDate: new Date(), - }); + });*/ const isNew = this.state.postId === "new"; //const pathname = window.location.href.split('/') @@ -41,7 +41,7 @@ export default function PostEditPage({ $target, initialState }) { }), }); history.replaceState(null, null, `/${createdPost.id}`); - removeItem(postLocalSaveKey); + //removeItem(postLocalSaveKey); this.setState({ ...post, @@ -52,7 +52,7 @@ export default function PostEditPage({ $target, initialState }) { method: "PUT", body: JSON.stringify(post), }); - removeItem(postLocalSaveKey); + //removeItem(postLocalSaveKey); } }, 1000); }, @@ -60,14 +60,14 @@ export default function PostEditPage({ $target, initialState }) { this.setState = async (nextState) => { if (this.state.postId !== nextState.postId) { - postLocalSaveKey = `temp-post-${nextState.postId}`; + //postLocalSaveKey = `temp-post-${nextState.postId}`; this.state = nextState; if (this.state.postId === "new") { - const post = getItem(postLocalSaveKey, { + const post = {//getItem(postLocalSaveKey, { title: "", content: "", - }); + };//); this.render(); editor.setState(post); } else { @@ -97,10 +97,10 @@ export default function PostEditPage({ $target, initialState }) { if (postId !== "new") { const post = await request(`/${postId}`); - const tempPost = getItem(postLocalSaveKey, { + const tempPost = {//getItem(postLocalSaveKey, { title: "", content: "", - }); + }; if (tempPost.tempSaveDate && tempPost.tempSaveDate > post.updated_at) { if (confirm("저장되지 않은 임시 데이터가 있습니다. 불러올까요?")) { diff --git a/src/PostList.js b/src/PostList.js index ce5f1c26..0df033ed 100644 --- a/src/PostList.js +++ b/src/PostList.js @@ -62,7 +62,6 @@ export default function PostList({ $target, initialState }) { const [commend, id] = $button.id.split("_"); if (commend === "createButton") { - pushRouter(`/`); const createdPost = await request("", { method: "POST", body: JSON.stringify({ @@ -70,6 +69,7 @@ export default function PostList({ $target, initialState }) { parent: id, }), }); + pushRouter(`/${createdPost.id}`); } else { pushRouter(`/`); request(`/${id}`, { @@ -82,6 +82,7 @@ export default function PostList({ $target, initialState }) { const getDocuments = async () => { const documents = await request(); + console.log(documents) this.setState(documents); }; } From b14c73e743ecfdf6d4f33e5388c39f2112a5f0bc Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 08:34:16 +0900 Subject: [PATCH 09/25] =?UTF-8?q?[FEAT]=20storage=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 4 ++-- src/PostEditPage.js | 47 +++++++++------------------------------------ src/PostList.js | 2 +- src/router.js | 2 +- src/storage.js | 17 ---------------- 5 files changed, 13 insertions(+), 59 deletions(-) delete mode 100644 src/storage.js diff --git a/src/App.js b/src/App.js index dc0a33ff..8d24ee43 100644 --- a/src/App.js +++ b/src/App.js @@ -33,7 +33,7 @@ export default function App({ $target }) { this.route(); - initRouter(() => this.route()) + initRouter(() => this.route()); - console.log(request()) + console.log(request()); } diff --git a/src/PostEditPage.js b/src/PostEditPage.js index 1beafeb7..e755e539 100644 --- a/src/PostEditPage.js +++ b/src/PostEditPage.js @@ -1,39 +1,29 @@ import { request } from "./api.js"; import Editor from "./Editor.js"; import LinkButton from "./LinkButton.js"; -import { getItem, removeItem, setItem } from "./storage.js"; export default function PostEditPage({ $target, initialState }) { const $page = document.createElement("div"); this.state = initialState; - //let postLocalSaveKey = `temp-post-${this.state.postId}`; - - const post = {//getItem(postLocalSaveKey, { - title: "", - content: "", - };//); - let timer = null; const editor = new Editor({ $target: $page, - initialState: post, + initialState: { + title: "", + content: "", + }, onEditing: (post) => { if (timer !== null) { clearTimeout(timer); } timer = setTimeout(async () => { - /*setItem(postLocalSaveKey, { - ...post, - tempSaveDate: new Date(), - });*/ - const isNew = this.state.postId === "new"; - //const pathname = window.location.href.split('/') + if (isNew) { - const createdPost = await request('', { + const createdPost = await request("", { method: "POST", body: JSON.stringify({ title: post.title, @@ -41,7 +31,6 @@ export default function PostEditPage({ $target, initialState }) { }), }); history.replaceState(null, null, `/${createdPost.id}`); - //removeItem(postLocalSaveKey); this.setState({ ...post, @@ -52,7 +41,6 @@ export default function PostEditPage({ $target, initialState }) { method: "PUT", body: JSON.stringify(post), }); - //removeItem(postLocalSaveKey); } }, 1000); }, @@ -60,16 +48,14 @@ export default function PostEditPage({ $target, initialState }) { this.setState = async (nextState) => { if (this.state.postId !== nextState.postId) { - //postLocalSaveKey = `temp-post-${nextState.postId}`; this.state = nextState; if (this.state.postId === "new") { - const post = {//getItem(postLocalSaveKey, { + this.render(); + editor.setState({ title: "", content: "", - };//); - this.render(); - editor.setState(post); + }); } else { await fetchPost(); } @@ -97,21 +83,6 @@ export default function PostEditPage({ $target, initialState }) { if (postId !== "new") { const post = await request(`/${postId}`); - const tempPost = {//getItem(postLocalSaveKey, { - title: "", - content: "", - }; - - if (tempPost.tempSaveDate && tempPost.tempSaveDate > post.updated_at) { - if (confirm("저장되지 않은 임시 데이터가 있습니다. 불러올까요?")) { - this.setState({ - ...this.state, - post: tempPost, - }); - return; - } - } - this.setState({ ...this.state, post, diff --git a/src/PostList.js b/src/PostList.js index 0df033ed..adaf2998 100644 --- a/src/PostList.js +++ b/src/PostList.js @@ -82,7 +82,7 @@ export default function PostList({ $target, initialState }) { const getDocuments = async () => { const documents = await request(); - console.log(documents) + console.log(documents); this.setState(documents); }; } diff --git a/src/router.js b/src/router.js index 4a728e8d..c12d4b46 100644 --- a/src/router.js +++ b/src/router.js @@ -6,7 +6,7 @@ export const initRouter = (onRoute) => { if (nextUrl) { history.pushState(null, null, nextUrl); - onRoute() + onRoute(); } }); }; diff --git a/src/storage.js b/src/storage.js deleted file mode 100644 index dcf55d22..00000000 --- a/src/storage.js +++ /dev/null @@ -1,17 +0,0 @@ -const storage = window.localStorage; - -export const getItem = (key, defaultValue) => { - try { - const storageValue = storage.getItem(key); - return storageValue ? JSON.parse(storageValue) : defaultValue; - } catch (e) { - return defaultValue; - } -}; -export const setItem = (key, value) => { - storage.setItem(key, JSON.stringify(value)); -}; - -export const removeItem = (key) => { - storage.removeItem(key); -}; From d3f3b9e5b191d48928804d42679a2f9517016337 Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 08:45:42 +0900 Subject: [PATCH 10/25] =?UTF-8?q?[FEAT]=20=ED=95=9C=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=EC=97=90=20=EB=AA=A9=EB=A1=9D=EA=B3=BC=20=ED=8E=B8=EC=A7=91?= =?UTF-8?q?=EA=B8=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/App.js b/src/App.js index 8d24ee43..6c0c2df0 100644 --- a/src/App.js +++ b/src/App.js @@ -6,6 +6,13 @@ import { initRouter } from "./router.js"; export default function App({ $target }) { const postPage = new PostPage({ $target, + initialState: { + postId: "new", + post: { + title: "", + content: "", + }, + }, }); const postEditPage = new PostEditPage({ @@ -23,17 +30,14 @@ export default function App({ $target }) { $target.innerHTML = ""; const { pathname } = window.location; - if (pathname === "/") { - postPage.setState(); - } else if (pathname.indexOf("/") === 0) { + if (pathname !== '/' && pathname.indexOf("/") === 0) { const [, postId] = pathname.split("/"); postEditPage.setState({ postId }); } + postPage.setState() }; this.route(); initRouter(() => this.route()); - - console.log(request()); } From 037630aa4926363922181959f49037f3495a2356 Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 08:51:16 +0900 Subject: [PATCH 11/25] [FIX] file rename --- src/App.js | 15 ++++----------- src/{PostPage.js => PostNavBar.js} | 2 +- 2 files changed, 5 insertions(+), 12 deletions(-) rename src/{PostPage.js => PostNavBar.js} (91%) diff --git a/src/App.js b/src/App.js index 6c0c2df0..ddb97cd2 100644 --- a/src/App.js +++ b/src/App.js @@ -1,18 +1,11 @@ import { request } from "./api.js"; import PostEditPage from "./PostEditPage.js"; -import PostPage from "./PostPage.js"; +import PostNavBar from "./PostNavBar.js"; import { initRouter } from "./router.js"; export default function App({ $target }) { - const postPage = new PostPage({ - $target, - initialState: { - postId: "new", - post: { - title: "", - content: "", - }, - }, + const postNavBar = new PostNavBar({ + $target }); const postEditPage = new PostEditPage({ @@ -34,7 +27,7 @@ export default function App({ $target }) { const [, postId] = pathname.split("/"); postEditPage.setState({ postId }); } - postPage.setState() + postNavBar.setState() }; this.route(); diff --git a/src/PostPage.js b/src/PostNavBar.js similarity index 91% rename from src/PostPage.js rename to src/PostNavBar.js index db6811f6..c52cdb67 100644 --- a/src/PostPage.js +++ b/src/PostNavBar.js @@ -2,7 +2,7 @@ import { request } from "./api.js"; import LinkButton from "./LinkButton.js"; import PostList from "./PostList.js"; -export default function PostPage({ $target }) { +export default function PostNavBar({ $target }) { const $page = document.createElement("div"); const postList = new PostList({ From 612fa32822943a615c801d56bc95b7bb68348d3b Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 08:58:51 +0900 Subject: [PATCH 12/25] =?UTF-8?q?[FIX]=20LinkButton=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C=20=EB=B0=8F=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 7 +++---- src/LinkButton.js | 17 ----------------- src/PostEditPage.js | 9 --------- src/PostNavBar.js | 17 ++++++++--------- 4 files changed, 11 insertions(+), 39 deletions(-) delete mode 100644 src/LinkButton.js diff --git a/src/App.js b/src/App.js index ddb97cd2..1e485d4e 100644 --- a/src/App.js +++ b/src/App.js @@ -1,11 +1,10 @@ -import { request } from "./api.js"; import PostEditPage from "./PostEditPage.js"; import PostNavBar from "./PostNavBar.js"; import { initRouter } from "./router.js"; export default function App({ $target }) { const postNavBar = new PostNavBar({ - $target + $target, }); const postEditPage = new PostEditPage({ @@ -23,11 +22,11 @@ export default function App({ $target }) { $target.innerHTML = ""; const { pathname } = window.location; - if (pathname !== '/' && pathname.indexOf("/") === 0) { + if (pathname !== "/" && pathname.indexOf("/") === 0) { const [, postId] = pathname.split("/"); postEditPage.setState({ postId }); } - postNavBar.setState() + postNavBar.setState(); }; this.route(); diff --git a/src/LinkButton.js b/src/LinkButton.js deleted file mode 100644 index 42cac950..00000000 --- a/src/LinkButton.js +++ /dev/null @@ -1,17 +0,0 @@ -import { pushRouter } from "./router.js"; - -export default function LinkButton({ $target, initialState }) { - this.state = initialState; - const $linkButton = document.createElement("button"); - $target.appendChild($linkButton); - - this.render = () => { - $linkButton.textContent = this.state.text; - }; - - this.render(); - - $linkButton.addEventListener("click", () => { - pushRouter(this.state.link); - }); -} diff --git a/src/PostEditPage.js b/src/PostEditPage.js index e755e539..4aab1af2 100644 --- a/src/PostEditPage.js +++ b/src/PostEditPage.js @@ -1,6 +1,5 @@ import { request } from "./api.js"; import Editor from "./Editor.js"; -import LinkButton from "./LinkButton.js"; export default function PostEditPage({ $target, initialState }) { const $page = document.createElement("div"); @@ -89,12 +88,4 @@ export default function PostEditPage({ $target, initialState }) { }); } }; - - new LinkButton({ - $target: $page, - initialState: { - text: "목록으로 이동", - link: "/", - }, - }); } diff --git a/src/PostNavBar.js b/src/PostNavBar.js index c52cdb67..f19f4fda 100644 --- a/src/PostNavBar.js +++ b/src/PostNavBar.js @@ -1,23 +1,16 @@ import { request } from "./api.js"; -import LinkButton from "./LinkButton.js"; import PostList from "./PostList.js"; +import { pushRouter } from "./router.js"; export default function PostNavBar({ $target }) { const $page = document.createElement("div"); + const $createButton = document.createElement("button"); const postList = new PostList({ $target: $page, initialState: [], }); - new LinkButton({ - $target: $page, - initialState: { - text: "New Post", - link: "/new", - }, - }); - this.setState = async () => { const post = await request(); postList.setState(post); @@ -25,6 +18,12 @@ export default function PostNavBar({ $target }) { }; this.render = async () => { + $createButton.textContent = "+"; + $page.appendChild($createButton); $target.appendChild($page); }; + + $createButton.addEventListener("click", (e) => { + pushRouter("/new"); + }); } From 722e43a5fcb6e346e9f92c200dbf15edb24a5b14 Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 09:04:08 +0900 Subject: [PATCH 13/25] =?UTF-8?q?[FIX]=20API=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/PostEditPage.js | 6 +++--- src/PostList.js | 8 ++++---- src/PostNavBar.js | 2 +- src/api.js | 13 +++++++------ 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/PostEditPage.js b/src/PostEditPage.js index 4aab1af2..b7d3b483 100644 --- a/src/PostEditPage.js +++ b/src/PostEditPage.js @@ -22,7 +22,7 @@ export default function PostEditPage({ $target, initialState }) { const isNew = this.state.postId === "new"; if (isNew) { - const createdPost = await request("", { + const createdPost = await request("/documents", { method: "POST", body: JSON.stringify({ title: post.title, @@ -36,7 +36,7 @@ export default function PostEditPage({ $target, initialState }) { postId: createdPost.id, }); } else { - await request(`/${this.state.postId}`, { + await request(`/documents/${this.state.postId}`, { method: "PUT", body: JSON.stringify(post), }); @@ -80,7 +80,7 @@ export default function PostEditPage({ $target, initialState }) { const { postId } = this.state; if (postId !== "new") { - const post = await request(`/${postId}`); + const post = await request(`/documents/${postId}`); this.setState({ ...this.state, diff --git a/src/PostList.js b/src/PostList.js index adaf2998..59f4de51 100644 --- a/src/PostList.js +++ b/src/PostList.js @@ -55,14 +55,14 @@ export default function PostList({ $target, initialState }) { if ($span) { pushRouter(`/${$span.id}`); - request(`/${$span.id}`); + request(`/documents/${$span.id}`); } } else if (clickTag === "button") { const $button = e.target.closest("button"); const [commend, id] = $button.id.split("_"); if (commend === "createButton") { - const createdPost = await request("", { + const createdPost = await request("/documents", { method: "POST", body: JSON.stringify({ title: "제목 없음", @@ -72,7 +72,7 @@ export default function PostList({ $target, initialState }) { pushRouter(`/${createdPost.id}`); } else { pushRouter(`/`); - request(`/${id}`, { + request(`/documents/${id}`, { method: "DELETE", }); } @@ -81,7 +81,7 @@ export default function PostList({ $target, initialState }) { }); const getDocuments = async () => { - const documents = await request(); + const documents = await request("/documents"); console.log(documents); this.setState(documents); }; diff --git a/src/PostNavBar.js b/src/PostNavBar.js index f19f4fda..29169a19 100644 --- a/src/PostNavBar.js +++ b/src/PostNavBar.js @@ -12,7 +12,7 @@ export default function PostNavBar({ $target }) { }); this.setState = async () => { - const post = await request(); + const post = await request("/documents"); postList.setState(post); this.render(); }; diff --git a/src/api.js b/src/api.js index dc4e2cda..9dad0eb0 100644 --- a/src/api.js +++ b/src/api.js @@ -1,17 +1,18 @@ -export const API_END_POINT = "https://kdt-frontend.programmers.co.kr/documents"; +export const API_END_POINT = "https://kdt-frontend.programmers.co.kr"; +export const API_X_USERNAME = "API_X_USERNAME_LIMJISEON"; -export const request = async (documentsId = "", options = {}) => { +export const request = async (url, options = {}) => { try { - const res = await fetch(`${API_END_POINT}${documentsId}`, { + const response = await fetch(`${API_END_POINT}${url}`, { ...options, headers: { "Content-Type": "application/json", - "x-username": "hyun", + "x-username": API_X_USERNAME, }, }); - if (res.ok) { - return await res.json(); + if (response.ok) { + return await response.json(); } throw new Error("API 처리중 에러가 발생했습니다."); From 80933e53f66bff6f7f929bb5232455fc34420b4b Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 09:20:00 +0900 Subject: [PATCH 14/25] =?UTF-8?q?[FIX]=20editor=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Editor.js | 6 +++--- src/PostNavBar.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Editor.js b/src/Editor.js index f7756f73..38d5b439 100644 --- a/src/Editor.js +++ b/src/Editor.js @@ -24,9 +24,9 @@ export default function Editor({ this.render = () => { if (!isinitialize) { $editor.innerHTML = ` - - - `; + + + `; isinitialize = true; } }; diff --git a/src/PostNavBar.js b/src/PostNavBar.js index 29169a19..12cd9bb5 100644 --- a/src/PostNavBar.js +++ b/src/PostNavBar.js @@ -12,8 +12,8 @@ export default function PostNavBar({ $target }) { }); this.setState = async () => { - const post = await request("/documents"); - postList.setState(post); + const documents = await request("/documents"); + postList.setState(documents); this.render(); }; From 631e92f7da956f82dc5b041042a51b1afa58f87a Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 09:24:38 +0900 Subject: [PATCH 15/25] =?UTF-8?q?[FEAT]=20=EB=A3=A8=ED=8A=B8=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=83=9D=EC=84=B1=20=EC=BD=94=EB=93=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/PostNavBar.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/PostNavBar.js b/src/PostNavBar.js index 12cd9bb5..03f22d28 100644 --- a/src/PostNavBar.js +++ b/src/PostNavBar.js @@ -23,7 +23,14 @@ export default function PostNavBar({ $target }) { $target.appendChild($page); }; - $createButton.addEventListener("click", (e) => { - pushRouter("/new"); + $createButton.addEventListener("click", async () => { + const createdPost = await request("/documents", { + method: "POST", + body: JSON.stringify({ + title: "제목 없음", + parent: null, + }), + }); + pushRouter(`/${createdPost.id}`); }); } From 59b36a6a44852da33abf5396cdfdbf5090849ff2 Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 10:51:51 +0900 Subject: [PATCH 16/25] =?UTF-8?q?[FIX]=20postEdit=20=EC=83=88=EB=A1=9C?= =?UTF-8?q?=EC=9A=B4=20=EB=AC=B8=EC=84=9C=20=EC=83=9D=EC=84=B1=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Editor.js | 1 - src/PostEditPage.js | 38 +++++++------------------------------- src/PostList.js | 1 - 3 files changed, 7 insertions(+), 33 deletions(-) diff --git a/src/Editor.js b/src/Editor.js index 38d5b439..df2e7941 100644 --- a/src/Editor.js +++ b/src/Editor.js @@ -42,7 +42,6 @@ export default function Editor({ ...this.state, [name]: target.value, }; - this.setState(nextState); onEditing(this.state); } diff --git a/src/PostEditPage.js b/src/PostEditPage.js index b7d3b483..0a864e3d 100644 --- a/src/PostEditPage.js +++ b/src/PostEditPage.js @@ -18,24 +18,9 @@ export default function PostEditPage({ $target, initialState }) { if (timer !== null) { clearTimeout(timer); } - timer = setTimeout(async () => { - const isNew = this.state.postId === "new"; - - if (isNew) { - const createdPost = await request("/documents", { - method: "POST", - body: JSON.stringify({ - title: post.title, - parent: null, - }), - }); - history.replaceState(null, null, `/${createdPost.id}`); - this.setState({ - ...post, - postId: createdPost.id, - }); - } else { + timer = setTimeout(async () => { + if (this.state.postId) { await request(`/documents/${this.state.postId}`, { method: "PUT", body: JSON.stringify(post), @@ -48,22 +33,13 @@ export default function PostEditPage({ $target, initialState }) { this.setState = async (nextState) => { if (this.state.postId !== nextState.postId) { this.state = nextState; - - if (this.state.postId === "new") { - this.render(); - editor.setState({ - title: "", - content: "", - }); - } else { - await fetchPost(); - } + await fetchPost(); return; + } else { + this.state = nextState; + this.render(); } - this.state = nextState; - this.render(); - editor.setState( this.state.post || { title: "", @@ -79,7 +55,7 @@ export default function PostEditPage({ $target, initialState }) { const fetchPost = async () => { const { postId } = this.state; - if (postId !== "new") { + if (postId) { const post = await request(`/documents/${postId}`); this.setState({ diff --git a/src/PostList.js b/src/PostList.js index 59f4de51..faa624ce 100644 --- a/src/PostList.js +++ b/src/PostList.js @@ -82,7 +82,6 @@ export default function PostList({ $target, initialState }) { const getDocuments = async () => { const documents = await request("/documents"); - console.log(documents); this.setState(documents); }; } From 35b68fd76dfce28ab5f637de2636227dfd958f8f Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 10:58:00 +0900 Subject: [PATCH 17/25] =?UTF-8?q?[FEAT]=20=EA=B8=80=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=EC=8B=9C=20=EB=84=A4=EB=B9=84=EB=B0=94=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/PostEditPage.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/PostEditPage.js b/src/PostEditPage.js index 0a864e3d..484eef05 100644 --- a/src/PostEditPage.js +++ b/src/PostEditPage.js @@ -1,5 +1,6 @@ import { request } from "./api.js"; import Editor from "./Editor.js"; +import { pushRouter } from "./router.js"; export default function PostEditPage({ $target, initialState }) { const $page = document.createElement("div"); @@ -25,6 +26,8 @@ export default function PostEditPage({ $target, initialState }) { method: "PUT", body: JSON.stringify(post), }); + pushRouter(`/${this.state.postId}`); + await fetchPost(); } }, 1000); }, From 6853d665d76d5cb28ebc5c985dfcc876ccb24887 Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 11:00:01 +0900 Subject: [PATCH 18/25] =?UTF-8?q?[FIX]=20=ED=95=A8=EC=88=98=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/PostEditPage.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/PostEditPage.js b/src/PostEditPage.js index 484eef05..54150984 100644 --- a/src/PostEditPage.js +++ b/src/PostEditPage.js @@ -27,7 +27,7 @@ export default function PostEditPage({ $target, initialState }) { body: JSON.stringify(post), }); pushRouter(`/${this.state.postId}`); - await fetchPost(); + await getDocument(); } }, 1000); }, @@ -36,7 +36,7 @@ export default function PostEditPage({ $target, initialState }) { this.setState = async (nextState) => { if (this.state.postId !== nextState.postId) { this.state = nextState; - await fetchPost(); + await getDocument(); return; } else { this.state = nextState; @@ -55,7 +55,7 @@ export default function PostEditPage({ $target, initialState }) { $target.appendChild($page); }; - const fetchPost = async () => { + const getDocument = async () => { const { postId } = this.state; if (postId) { From 09e395630b52757c060f1c4cc1d5db68a457d00e Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 12:27:18 +0900 Subject: [PATCH 19/25] =?UTF-8?q?[FIX]=20=EB=AC=B8=EC=84=9C=20=ED=8A=B8?= =?UTF-8?q?=EB=A6=AC=20=EA=B5=AC=EC=A1=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/PostItem.js | 57 +++++++++++++++++++++++++++++++++ src/PostList.js | 83 +++++++++---------------------------------------- 2 files changed, 72 insertions(+), 68 deletions(-) create mode 100644 src/PostItem.js diff --git a/src/PostItem.js b/src/PostItem.js new file mode 100644 index 00000000..1f7865e8 --- /dev/null +++ b/src/PostItem.js @@ -0,0 +1,57 @@ +import { request } from "./api.js"; +import { pushRouter } from "./router.js"; + +export default function PostItem(title, id) { + const $postItemBox = document.createElement("div"); + $postItemBox.id = `box_${id}`; + + const $li = document.createElement("li"); + $li.id = `li_${id}`; + + const $title = document.createElement("span"); + $title.id = id; + $title.textContent = title; + $li.appendChild($title); + + const $addButton = document.createElement("button"); + $addButton.textContent = "+"; + $addButton.id = `createButton_${id}`; + $li.appendChild($addButton); + + const $removeButton = document.createElement("button"); + $removeButton.textContent = "-"; + $removeButton.id = `deleteButton_${id}`; + $li.appendChild($removeButton); + + const $postSubItemBox = document.createElement("ul"); + + $postItemBox.appendChild($li); + $postItemBox.append($postSubItemBox); + + $title.addEventListener("click", async () => { + request(`/documents/${$title.id}`); + pushRouter(`/${$title.id}`); + }); + + $addButton.addEventListener("click", async () => { + const [, id] = $addButton.id.split("_"); + const createdPost = await request("/documents", { + method: "POST", + body: JSON.stringify({ + title: "제목 없음", + parent: id, + }), + }); + pushRouter(`/${createdPost.id}`); + }); + + $removeButton.addEventListener("click", async () => { + const [, id] = $removeButton.id.split("_"); + await request(`/documents/${id}`, { + method: "DELETE", + }); + pushRouter(`/`); + }); + + return { $postItemBox, $postSubItemBox }; +} diff --git a/src/PostList.js b/src/PostList.js index faa624ce..203864e1 100644 --- a/src/PostList.js +++ b/src/PostList.js @@ -1,8 +1,9 @@ import { request } from "./api.js"; +import PostItem from "./PostItem.js"; import { pushRouter } from "./router.js"; export default function PostList({ $target, initialState }) { - const $postList = document.createElement("div"); + const $postList = document.createElement("ul"); $target.appendChild($postList); this.state = initialState; @@ -12,76 +13,22 @@ export default function PostList({ $target, initialState }) { this.render(); }; - this.render = () => { - $postList.innerHTML = ` -
    - ${this.state - .map( - (post) => - ` -
  • - ${post.title} - - -
  • -
      - ${post.documents - .map( - (subPost) => - ` -
    • - ${subPost.title} - - -
    • - ` - ) - .join("")} -
    - ` - ) - .join("")} -
- `; - }; - - this.render(); - - $postList.addEventListener("click", async (e) => { - const clickTag = e.target.localName; + this.makeList = ($wrap, data) => { + data.forEach(({ title, documents, id }) => { + const { $postItemBox, $postSubItemBox } = PostItem(title, id); - if (clickTag === "span") { - const $span = e.target.closest("span"); + $wrap.appendChild($postItemBox); - if ($span) { - pushRouter(`/${$span.id}`); - request(`/documents/${$span.id}`); + if (documents.length > 0) { + this.makeList($postSubItemBox, documents); } - } else if (clickTag === "button") { - const $button = e.target.closest("button"); - const [commend, id] = $button.id.split("_"); - - if (commend === "createButton") { - const createdPost = await request("/documents", { - method: "POST", - body: JSON.stringify({ - title: "제목 없음", - parent: id, - }), - }); - pushRouter(`/${createdPost.id}`); - } else { - pushRouter(`/`); - request(`/documents/${id}`, { - method: "DELETE", - }); - } - getDocuments(); - } - }); + }); + }; - const getDocuments = async () => { - const documents = await request("/documents"); - this.setState(documents); + this.render = () => { + $postList.innerHTML = ""; + this.makeList($postList, this.state); }; + + this.render(); } From e7b3dff35c37dbd6b51d749e2ac8beb8ada78ff0 Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 12:31:03 +0900 Subject: [PATCH 20/25] =?UTF-8?q?[FIX]=20id=20->=20classname=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/PostItem.js | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/PostItem.js b/src/PostItem.js index 1f7865e8..07360f72 100644 --- a/src/PostItem.js +++ b/src/PostItem.js @@ -3,24 +3,24 @@ import { pushRouter } from "./router.js"; export default function PostItem(title, id) { const $postItemBox = document.createElement("div"); - $postItemBox.id = `box_${id}`; + $postItemBox.className = id; const $li = document.createElement("li"); - $li.id = `li_${id}`; + $li.className = id; const $title = document.createElement("span"); - $title.id = id; + $title.className = id; $title.textContent = title; $li.appendChild($title); const $addButton = document.createElement("button"); $addButton.textContent = "+"; - $addButton.id = `createButton_${id}`; + $addButton.className = id; $li.appendChild($addButton); const $removeButton = document.createElement("button"); $removeButton.textContent = "-"; - $removeButton.id = `deleteButton_${id}`; + $removeButton.className = id; $li.appendChild($removeButton); const $postSubItemBox = document.createElement("ul"); @@ -29,25 +29,23 @@ export default function PostItem(title, id) { $postItemBox.append($postSubItemBox); $title.addEventListener("click", async () => { - request(`/documents/${$title.id}`); - pushRouter(`/${$title.id}`); + request(`/documents/${$title.className}`); + pushRouter(`/${$title.className}`); }); $addButton.addEventListener("click", async () => { - const [, id] = $addButton.id.split("_"); const createdPost = await request("/documents", { method: "POST", body: JSON.stringify({ title: "제목 없음", - parent: id, + parent: $addButton.className, }), }); pushRouter(`/${createdPost.id}`); }); $removeButton.addEventListener("click", async () => { - const [, id] = $removeButton.id.split("_"); - await request(`/documents/${id}`, { + await request(`/documents/${$removeButton.className}`, { method: "DELETE", }); pushRouter(`/`); From bded9fee9d4d45bb46a89cd4a25179b28d05bd62 Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 12:32:17 +0900 Subject: [PATCH 21/25] =?UTF-8?q?[FIX]=20=EC=BD=94=EB=93=9C=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/PostList.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/PostList.js b/src/PostList.js index 203864e1..425d6226 100644 --- a/src/PostList.js +++ b/src/PostList.js @@ -1,6 +1,4 @@ -import { request } from "./api.js"; import PostItem from "./PostItem.js"; -import { pushRouter } from "./router.js"; export default function PostList({ $target, initialState }) { const $postList = document.createElement("ul"); From 9c3557f2dc6015b092ab93462b627b212f3ab0fc Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 14:52:34 +0900 Subject: [PATCH 22/25] =?UTF-8?q?[STYLE]=20=EB=94=94=EC=9E=90=EC=9D=B8=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 1 + src/Editor.js | 1 + src/PostEditPage.js | 1 + src/PostNavBar.js | 16 ++++++--- src/main.js | 1 + style.css | 83 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 style.css diff --git a/index.html b/index.html index 2214f5e8..a6194b9f 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,7 @@
+ diff --git a/src/Editor.js b/src/Editor.js index df2e7941..9da6f7af 100644 --- a/src/Editor.js +++ b/src/Editor.js @@ -7,6 +7,7 @@ export default function Editor({ onEditing, }) { const $editor = document.createElement("div"); + $editor.id = "editor"; let isinitialize = false; diff --git a/src/PostEditPage.js b/src/PostEditPage.js index 54150984..8a4b6135 100644 --- a/src/PostEditPage.js +++ b/src/PostEditPage.js @@ -4,6 +4,7 @@ import { pushRouter } from "./router.js"; export default function PostEditPage({ $target, initialState }) { const $page = document.createElement("div"); + $page.id = "editPage"; this.state = initialState; diff --git a/src/PostNavBar.js b/src/PostNavBar.js index 03f22d28..91524553 100644 --- a/src/PostNavBar.js +++ b/src/PostNavBar.js @@ -3,11 +3,15 @@ import PostList from "./PostList.js"; import { pushRouter } from "./router.js"; export default function PostNavBar({ $target }) { - const $page = document.createElement("div"); + const $nav = document.createElement("div"); const $createButton = document.createElement("button"); + const $title = document.createElement("h1"); + $nav.id = "nav"; + $createButton.id = "createButton"; + $title.id = "title"; const postList = new PostList({ - $target: $page, + $target: $nav, initialState: [], }); @@ -18,9 +22,11 @@ export default function PostNavBar({ $target }) { }; this.render = async () => { - $createButton.textContent = "+"; - $page.appendChild($createButton); - $target.appendChild($page); + $createButton.textContent = "문서 생성하기"; + $title.textContent = "Notion Project"; + $nav.appendChild($title); + $nav.appendChild($createButton); + $target.appendChild($nav); }; $createButton.addEventListener("click", async () => { diff --git a/src/main.js b/src/main.js index 3876e42a..32a175ca 100644 --- a/src/main.js +++ b/src/main.js @@ -1,5 +1,6 @@ import App from "./App.js"; const $target = document.querySelector("#app"); +$target.id = "contentWrap"; new App({ $target }); diff --git a/style.css b/style.css new file mode 100644 index 00000000..2612d2ba --- /dev/null +++ b/style.css @@ -0,0 +1,83 @@ +body { + margin: 0; + padding: 0; + background-color: rgb(229, 229, 229); +} + +button { + border: none; + background-color: transparent; + font-size: 16px; + margin: 0 5 0 5; +} + +button:hover { + background-color: white; + border-radius: 5px; + font-weight: bolder; +} + +li { + padding: 10 5 10 5; +} + +li:hover { + background-color: white; + border-radius: 5px; + font-weight: bold; +} + +input { + width: 50vw; + height: 5vh; + border-radius: 5px; + font-size: 16px; + border: none; + outline: none; +} + +textarea { + width: 50vw; + height: 50vh; + border-radius: 5px; + font-size: 16px; + border: none; + outline: none; + margin-top: 10px; +} + +#contentWrap { + width: 100%; + height: 100%; + display: flex; + justify-content: space-between; +} + +#nav { + width: 70vw; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +#editPage { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +#createButton { + border-radius: 5px; + padding: 10px; + background-color: white; +} + +#editor { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 0 50 0 50; +} \ No newline at end of file From 0e0fec1de6aff51792a817ddac961394c885d115 Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Fri, 7 Jul 2023 15:31:29 +0900 Subject: [PATCH 23/25] =?UTF-8?q?[FIX]=20element=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=EC=A4=91(=EB=AF=B8=ED=95=B4=EA=B2=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/PostEditPage.js | 4 +++- src/PostNavBar.js | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/PostEditPage.js b/src/PostEditPage.js index 8a4b6135..40945056 100644 --- a/src/PostEditPage.js +++ b/src/PostEditPage.js @@ -5,6 +5,7 @@ import { pushRouter } from "./router.js"; export default function PostEditPage({ $target, initialState }) { const $page = document.createElement("div"); $page.id = "editPage"; + $page.className = "2"; this.state = initialState; @@ -30,7 +31,7 @@ export default function PostEditPage({ $target, initialState }) { pushRouter(`/${this.state.postId}`); await getDocument(); } - }, 1000); + }, 2000); }, }); @@ -54,6 +55,7 @@ export default function PostEditPage({ $target, initialState }) { this.render = () => { $target.appendChild($page); + console.log($target) }; const getDocument = async () => { diff --git a/src/PostNavBar.js b/src/PostNavBar.js index 91524553..04b113e8 100644 --- a/src/PostNavBar.js +++ b/src/PostNavBar.js @@ -7,6 +7,7 @@ export default function PostNavBar({ $target }) { const $createButton = document.createElement("button"); const $title = document.createElement("h1"); $nav.id = "nav"; + $nav.className = "1"; $createButton.id = "createButton"; $title.id = "title"; From b6a613a487eba3fdb4fd1d6ddbfb59d6e778b6a3 Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Wed, 19 Jul 2023 17:45:55 +0900 Subject: [PATCH 24/25] =?UTF-8?q?[FIX]=20=EB=9E=9C=EB=8D=94=EB=A7=81=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EB=B0=8F=20=ED=94=BC=EB=93=9C=EB=B0=B1=20?= =?UTF-8?q?=EB=B0=98=EC=98=81(1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 19 ++++-- src/Editor.js | 13 ++-- src/PostEditPage.js | 14 +---- src/PostList.js | 4 +- src/{PostNavBar.js => PostSidebar.js} | 14 ++--- src/api.js | 3 +- src/main.js | 2 +- src/router.js | 2 +- style.css | 91 +++++++++++++-------------- 9 files changed, 75 insertions(+), 87 deletions(-) rename src/{PostNavBar.js => PostSidebar.js} (74%) diff --git a/src/App.js b/src/App.js index 1e485d4e..bcc325d2 100644 --- a/src/App.js +++ b/src/App.js @@ -1,14 +1,21 @@ import PostEditPage from "./PostEditPage.js"; -import PostNavBar from "./PostNavBar.js"; +import PostSidebar from "./PostSidebar.js"; import { initRouter } from "./router.js"; export default function App({ $target }) { - const postNavBar = new PostNavBar({ - $target, + const $postSideBarContainer = document.createElement("div"); + const $postEditContainer = document.createElement("div"); + $target.appendChild($postSideBarContainer); + $target.appendChild($postEditContainer); + $postSideBarContainer.className = "post-side-bar-container"; + $postEditContainer.className = "post-edit-container"; + + const postSideBar = new PostSidebar({ + $target: $postSideBarContainer, }); const postEditPage = new PostEditPage({ - $target, + $target: $postEditContainer, initialState: { postId: "new", post: { @@ -19,14 +26,14 @@ export default function App({ $target }) { }); this.route = () => { - $target.innerHTML = ""; const { pathname } = window.location; + postSideBar.setState(); + if (pathname !== "/" && pathname.indexOf("/") === 0) { const [, postId] = pathname.split("/"); postEditPage.setState({ postId }); } - postNavBar.setState(); }; this.route(); diff --git a/src/Editor.js b/src/Editor.js index 9da6f7af..4f69282f 100644 --- a/src/Editor.js +++ b/src/Editor.js @@ -7,9 +7,9 @@ export default function Editor({ onEditing, }) { const $editor = document.createElement("div"); - $editor.id = "editor"; + $editor.className = "editor"; - let isinitialize = false; + let isInitialized = false; this.state = initialState; @@ -17,18 +17,19 @@ export default function Editor({ this.setState = (nextState) => { this.state = nextState; - $editor.querySelector("[name=title]").value = this.state.title; - $editor.querySelector("[name=content]").value = this.state.content; + const { title, content } = this.state; + $editor.querySelector("[name=title]").value = title; + $editor.querySelector("[name=content]").value = content; this.render(); }; this.render = () => { - if (!isinitialize) { + if (!isInitialized) { $editor.innerHTML = ` `; - isinitialize = true; + isInitialized = true; } }; this.render(); diff --git a/src/PostEditPage.js b/src/PostEditPage.js index 40945056..7f511462 100644 --- a/src/PostEditPage.js +++ b/src/PostEditPage.js @@ -3,16 +3,14 @@ import Editor from "./Editor.js"; import { pushRouter } from "./router.js"; export default function PostEditPage({ $target, initialState }) { - const $page = document.createElement("div"); - $page.id = "editPage"; - $page.className = "2"; + const INTERVAL_SAVE_TIME = 2000; this.state = initialState; let timer = null; const editor = new Editor({ - $target: $page, + $target, initialState: { title: "", content: "", @@ -31,7 +29,7 @@ export default function PostEditPage({ $target, initialState }) { pushRouter(`/${this.state.postId}`); await getDocument(); } - }, 2000); + }, INTERVAL_SAVE_TIME); }, }); @@ -42,7 +40,6 @@ export default function PostEditPage({ $target, initialState }) { return; } else { this.state = nextState; - this.render(); } editor.setState( @@ -53,11 +50,6 @@ export default function PostEditPage({ $target, initialState }) { ); }; - this.render = () => { - $target.appendChild($page); - console.log($target) - }; - const getDocument = async () => { const { postId } = this.state; diff --git a/src/PostList.js b/src/PostList.js index 425d6226..78343256 100644 --- a/src/PostList.js +++ b/src/PostList.js @@ -11,11 +11,11 @@ export default function PostList({ $target, initialState }) { this.render(); }; - this.makeList = ($wrap, data) => { + this.makeList = ($itemContainer, data) => { data.forEach(({ title, documents, id }) => { const { $postItemBox, $postSubItemBox } = PostItem(title, id); - $wrap.appendChild($postItemBox); + $itemContainer.appendChild($postItemBox); if (documents.length > 0) { this.makeList($postSubItemBox, documents); diff --git a/src/PostNavBar.js b/src/PostSidebar.js similarity index 74% rename from src/PostNavBar.js rename to src/PostSidebar.js index 04b113e8..41feb324 100644 --- a/src/PostNavBar.js +++ b/src/PostSidebar.js @@ -2,17 +2,14 @@ import { request } from "./api.js"; import PostList from "./PostList.js"; import { pushRouter } from "./router.js"; -export default function PostNavBar({ $target }) { - const $nav = document.createElement("div"); +export default function PostSidebar({ $target }) { const $createButton = document.createElement("button"); const $title = document.createElement("h1"); - $nav.id = "nav"; - $nav.className = "1"; - $createButton.id = "createButton"; + $createButton.className = "createButton"; $title.id = "title"; const postList = new PostList({ - $target: $nav, + $target, initialState: [], }); @@ -25,9 +22,8 @@ export default function PostNavBar({ $target }) { this.render = async () => { $createButton.textContent = "문서 생성하기"; $title.textContent = "Notion Project"; - $nav.appendChild($title); - $nav.appendChild($createButton); - $target.appendChild($nav); + $target.appendChild($title); + $target.appendChild($createButton); }; $createButton.addEventListener("click", async () => { diff --git a/src/api.js b/src/api.js index 9dad0eb0..fbe541a0 100644 --- a/src/api.js +++ b/src/api.js @@ -17,7 +17,6 @@ export const request = async (url, options = {}) => { throw new Error("API 처리중 에러가 발생했습니다."); } catch (e) { - alert(e.message); - console.error(); + console.error(e); } }; diff --git a/src/main.js b/src/main.js index 32a175ca..9d74a7bc 100644 --- a/src/main.js +++ b/src/main.js @@ -1,6 +1,6 @@ import App from "./App.js"; const $target = document.querySelector("#app"); -$target.id = "contentWrap"; +$target.className = "contentWrap"; new App({ $target }); diff --git a/src/router.js b/src/router.js index c12d4b46..6270b318 100644 --- a/src/router.js +++ b/src/router.js @@ -13,7 +13,7 @@ export const initRouter = (onRoute) => { export const pushRouter = (nextUrl) => { window.dispatchEvent( - new CustomEvent("route-change", { + new CustomEvent(ROUTE_CHANGE_EVENT_NAME, { detail: { nextUrl, }, diff --git a/style.css b/style.css index 2612d2ba..303bbae9 100644 --- a/style.css +++ b/style.css @@ -1,14 +1,14 @@ body { - margin: 0; - padding: 0; - background-color: rgb(229, 229, 229); + margin: 0; + padding: 0; + background-color: rgb(229, 229, 229); } button { border: none; background-color: transparent; font-size: 16px; - margin: 0 5 0 5; + margin: 0px 5px 0px 5px; } button:hover { @@ -18,66 +18,59 @@ button:hover { } li { - padding: 10 5 10 5; + padding: 10px 5px 10px 5px; } li:hover { - background-color: white; - border-radius: 5px; - font-weight: bold; + background-color: white; + border-radius: 5px; + font-weight: bold; } input { - width: 50vw; - height: 5vh; - border-radius: 5px; - font-size: 16px; - border: none; - outline: none; + width: 50vw; + height: 5vh; + border-radius: 5px; + font-size: 16px; + border: none; + outline: none; } textarea { - width: 50vw; - height: 50vh; - border-radius: 5px; - font-size: 16px; - border: none; - outline: none; - margin-top: 10px; + width: 50vw; + height: 50vh; + border-radius: 5px; + font-size: 16px; + border: none; + outline: none; + margin-top: 10px; } -#contentWrap { - width: 100%; - height: 100%; - display: flex; - justify-content: space-between; +.contentWrap { + width: 100%; + height: 100%; + display: flex; + justify-content: space-between; } -#nav { - width: 70vw; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; +.post-side-bar-container { + width: 70vw; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; } -#editPage { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; +.createButton { + border-radius: 5px; + padding: 10px; + background-color: white; } -#createButton { - border-radius: 5px; - padding: 10px; - background-color: white; +.editor { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 0px 50px 0px 50px; } - -#editor { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - padding: 0 50 0 50; -} \ No newline at end of file From ae82433c49846d9fd598889447bf0bd887fdf05f Mon Sep 17 00:00:00 2001 From: Lim_JiSeon Date: Mon, 24 Jul 2023 11:36:13 +0900 Subject: [PATCH 25/25] =?UTF-8?q?[FIX]=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/PostItem.js | 55 ---------------------------- src/{ => components}/App.js | 4 +- src/{ => components}/Editor.js | 14 +++---- src/{ => components}/PostEditPage.js | 17 ++++----- src/components/PostItem.js | 54 +++++++++++++++++++++++++++ src/{ => components}/PostList.js | 0 src/{ => components}/PostSidebar.js | 25 ++++++------- src/main.js | 2 +- src/{ => utils}/api.js | 27 ++++++++++++++ src/{ => utils}/router.js | 1 + style.css | 15 +++++++- 11 files changed, 124 insertions(+), 90 deletions(-) delete mode 100644 src/PostItem.js rename src/{ => components}/App.js (91%) rename src/{ => components}/Editor.js (80%) rename src/{ => components}/PostEditPage.js (73%) create mode 100644 src/components/PostItem.js rename src/{ => components}/PostList.js (100%) rename src/{ => components}/PostSidebar.js (55%) rename src/{ => utils}/api.js (52%) rename src/{ => utils}/router.js (88%) diff --git a/src/PostItem.js b/src/PostItem.js deleted file mode 100644 index 07360f72..00000000 --- a/src/PostItem.js +++ /dev/null @@ -1,55 +0,0 @@ -import { request } from "./api.js"; -import { pushRouter } from "./router.js"; - -export default function PostItem(title, id) { - const $postItemBox = document.createElement("div"); - $postItemBox.className = id; - - const $li = document.createElement("li"); - $li.className = id; - - const $title = document.createElement("span"); - $title.className = id; - $title.textContent = title; - $li.appendChild($title); - - const $addButton = document.createElement("button"); - $addButton.textContent = "+"; - $addButton.className = id; - $li.appendChild($addButton); - - const $removeButton = document.createElement("button"); - $removeButton.textContent = "-"; - $removeButton.className = id; - $li.appendChild($removeButton); - - const $postSubItemBox = document.createElement("ul"); - - $postItemBox.appendChild($li); - $postItemBox.append($postSubItemBox); - - $title.addEventListener("click", async () => { - request(`/documents/${$title.className}`); - pushRouter(`/${$title.className}`); - }); - - $addButton.addEventListener("click", async () => { - const createdPost = await request("/documents", { - method: "POST", - body: JSON.stringify({ - title: "제목 없음", - parent: $addButton.className, - }), - }); - pushRouter(`/${createdPost.id}`); - }); - - $removeButton.addEventListener("click", async () => { - await request(`/documents/${$removeButton.className}`, { - method: "DELETE", - }); - pushRouter(`/`); - }); - - return { $postItemBox, $postSubItemBox }; -} diff --git a/src/App.js b/src/components/App.js similarity index 91% rename from src/App.js rename to src/components/App.js index bcc325d2..280329ee 100644 --- a/src/App.js +++ b/src/components/App.js @@ -1,6 +1,6 @@ import PostEditPage from "./PostEditPage.js"; import PostSidebar from "./PostSidebar.js"; -import { initRouter } from "./router.js"; +import { initRouter } from "../utils/router.js"; export default function App({ $target }) { const $postSideBarContainer = document.createElement("div"); @@ -31,7 +31,7 @@ export default function App({ $target }) { postSideBar.setState(); if (pathname !== "/" && pathname.indexOf("/") === 0) { - const [, postId] = pathname.split("/"); + const [, , postId] = pathname.split("/"); postEditPage.setState({ postId }); } }; diff --git a/src/Editor.js b/src/components/Editor.js similarity index 80% rename from src/Editor.js rename to src/components/Editor.js index 4f69282f..c812978c 100644 --- a/src/Editor.js +++ b/src/components/Editor.js @@ -9,10 +9,10 @@ export default function Editor({ const $editor = document.createElement("div"); $editor.className = "editor"; - let isInitialized = false; - this.state = initialState; + let isInitialize = false; + $target.appendChild($editor); this.setState = (nextState) => { @@ -24,12 +24,12 @@ export default function Editor({ }; this.render = () => { - if (!isInitialized) { + if (!isInitialize) { $editor.innerHTML = ` - - - `; - isInitialized = true; + + + `; + isInitialize = true; } }; this.render(); diff --git a/src/PostEditPage.js b/src/components/PostEditPage.js similarity index 73% rename from src/PostEditPage.js rename to src/components/PostEditPage.js index 7f511462..60277afa 100644 --- a/src/PostEditPage.js +++ b/src/components/PostEditPage.js @@ -1,6 +1,6 @@ -import { request } from "./api.js"; +import { getData, putData } from "../utils/api.js"; import Editor from "./Editor.js"; -import { pushRouter } from "./router.js"; +import { pushRouter } from "../utils/router.js"; export default function PostEditPage({ $target, initialState }) { const INTERVAL_SAVE_TIME = 2000; @@ -21,12 +21,10 @@ export default function PostEditPage({ $target, initialState }) { } timer = setTimeout(async () => { - if (this.state.postId) { - await request(`/documents/${this.state.postId}`, { - method: "PUT", - body: JSON.stringify(post), - }); - pushRouter(`/${this.state.postId}`); + const { postId } = this.state; + if (postId && postId !== "new") { + await putData(postId, post); + pushRouter(`/documents/${postId}`); await getDocument(); } }, INTERVAL_SAVE_TIME); @@ -52,9 +50,8 @@ export default function PostEditPage({ $target, initialState }) { const getDocument = async () => { const { postId } = this.state; - if (postId) { - const post = await request(`/documents/${postId}`); + const post = await getData(`/documents/${postId}`); this.setState({ ...this.state, diff --git a/src/components/PostItem.js b/src/components/PostItem.js new file mode 100644 index 00000000..5f9160c1 --- /dev/null +++ b/src/components/PostItem.js @@ -0,0 +1,54 @@ +import { deleteData, getData, postData } from "../utils/api.js"; +import { pushRouter } from "../utils/router.js"; + +export default function PostItem(title, id) { + const $postItemBox = document.createElement("div"); + $postItemBox.className = id; + + const $li = document.createElement("li"); + $li.className = id; + + const $title = document.createElement("span"); + $title.className = id; + $title.textContent = title; + $li.appendChild($title); + + const $addButton = makeButton("+", id); + $li.appendChild($addButton); + + const $removeButton = makeButton("-", id); + $li.appendChild($removeButton); + + const $postSubItemBox = document.createElement("ul"); + + $postItemBox.appendChild($li); + $postItemBox.append($postSubItemBox); + + $li.addEventListener("click", async (e) => { + const target = e.target; + if (target.closest("span") === $title) { + pushRouter(`/documents/${$title.className}`); + } else if (target.closest("button") === $addButton) { + const createdPost = await postData($addButton.className); + pushRouter(`/documents/${createdPost.id}`); + } else if (target.closest("button") === $removeButton) { + alert("문서가 정상적으로 삭제되었습니다."); + await deleteData($removeButton.className).then((res) => { + if (res.parent) pushRouter(`/documents/${res.parent.id}`); + else { + pushRouter(`/`); + location.reload(); + } + }); + } + }); + + return { $postItemBox, $postSubItemBox }; +} + +export const makeButton = (text, className) => { + const $button = document.createElement("button"); + $button.textContent = text; + $button.className = className; + return $button; +}; diff --git a/src/PostList.js b/src/components/PostList.js similarity index 100% rename from src/PostList.js rename to src/components/PostList.js diff --git a/src/PostSidebar.js b/src/components/PostSidebar.js similarity index 55% rename from src/PostSidebar.js rename to src/components/PostSidebar.js index 41feb324..15cd2d04 100644 --- a/src/PostSidebar.js +++ b/src/components/PostSidebar.js @@ -1,20 +1,22 @@ -import { request } from "./api.js"; +import { getData, postData } from "../utils/api.js"; import PostList from "./PostList.js"; -import { pushRouter } from "./router.js"; +import { pushRouter } from "../utils/router.js"; export default function PostSidebar({ $target }) { + const $listContainer = document.createElement("div"); const $createButton = document.createElement("button"); const $title = document.createElement("h1"); - $createButton.className = "createButton"; - $title.id = "title"; + $listContainer.className = "post-list-container"; + $createButton.className = "create-button"; + $title.className = "title"; const postList = new PostList({ - $target, + $target: $listContainer, initialState: [], }); this.setState = async () => { - const documents = await request("/documents"); + const documents = await getData("/documents"); postList.setState(documents); this.render(); }; @@ -24,16 +26,11 @@ export default function PostSidebar({ $target }) { $title.textContent = "Notion Project"; $target.appendChild($title); $target.appendChild($createButton); + $target.appendChild($listContainer); }; $createButton.addEventListener("click", async () => { - const createdPost = await request("/documents", { - method: "POST", - body: JSON.stringify({ - title: "제목 없음", - parent: null, - }), - }); - pushRouter(`/${createdPost.id}`); + const createdPost = await postData(); + pushRouter(`/documents/${createdPost.id}`); }); } diff --git a/src/main.js b/src/main.js index 9d74a7bc..9db98264 100644 --- a/src/main.js +++ b/src/main.js @@ -1,4 +1,4 @@ -import App from "./App.js"; +import App from "./components/App.js"; const $target = document.querySelector("#app"); $target.className = "contentWrap"; diff --git a/src/api.js b/src/utils/api.js similarity index 52% rename from src/api.js rename to src/utils/api.js index fbe541a0..aa20fd3f 100644 --- a/src/api.js +++ b/src/utils/api.js @@ -20,3 +20,30 @@ export const request = async (url, options = {}) => { console.error(e); } }; + +export const getData = async (url) => { + return request(url); +}; + +export const postData = async (id = null) => { + return request("/documents", { + method: "POST", + body: JSON.stringify({ + title: "제목 없음", + parent: id, + }), + }); +}; + +export const deleteData = async (id) => { + return request(`/documents/${id}`, { + method: "DELETE", + }); +}; + +export const putData = async (id, post) => { + return request(`/documents/${id}`, { + method: "PUT", + body: JSON.stringify(post), + }); +}; diff --git a/src/router.js b/src/utils/router.js similarity index 88% rename from src/router.js rename to src/utils/router.js index 6270b318..06650aee 100644 --- a/src/router.js +++ b/src/utils/router.js @@ -5,6 +5,7 @@ export const initRouter = (onRoute) => { const { nextUrl } = e.detail; if (nextUrl) { + window.addEventListener("popstate", () => onRoute()); history.pushState(null, null, nextUrl); onRoute(); } diff --git a/style.css b/style.css index 303bbae9..f062f0b0 100644 --- a/style.css +++ b/style.css @@ -9,6 +9,11 @@ button { background-color: transparent; font-size: 16px; margin: 0px 5px 0px 5px; + cursor: pointer; +} + +span { + cursor: pointer; } button:hover { @@ -53,6 +58,14 @@ textarea { justify-content: space-between; } +.post-edit-container { + width: 70vw; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + .post-side-bar-container { width: 70vw; display: flex; @@ -61,7 +74,7 @@ textarea { align-items: center; } -.createButton { +.create-button { border-radius: 5px; padding: 10px; background-color: white;