결과물
** 반응형 아님 (모니터 권장)
수정 할 것
페이지네이션 (수정 완료)페이지 나누기 (수정 완료)+ 전반적인 코드정리와 리팩토링 (수정 완료)답변 렌더링 (취소)
배치 & 디자인
사용자 경험을 고려하여 컴포넌트 배치를 바꿔보았다. 이제 display: flex는 껌이구나!
clear localStorage
로컬 데이터를 비우는 버튼을 만들어주었다.
페이지네이션
더보기
// index.html을 열어서 agoraStatesDiscussions 배열 요소를 확인하세요.
console.log(agoraStatesDiscussions);
let data;
const dataFromLocalStorage = localStorage.getItem("agoraStatesDiscussions");
if (dataFromLocalStorage) {
data = JSON.parse(dataFromLocalStorage);
} else {
data = agoraStatesDiscussions.slice();
}
// convertToDiscussion은 아고라 스테이츠 데이터를 DOM으로 바꿔줍니다.
const convertToDiscussion = (obj) => {
const li = document.createElement("li"); // li 요소 생성
li.className = "discussion__container"; // 클래스 이름 지정
const avatarWrapper = document.createElement("div");
avatarWrapper.className = "discussion__avatar--wrapper";
const discussionContent = document.createElement("div");
discussionContent.className = "discussion__content";
const discussionAnswered = document.createElement("div");
discussionAnswered.className = "discussion__answered";
// TODO: 객체 하나에 담긴 정보를 DOM에 적절히 넣어주세요.
const avatarImg = document.createElement("img");
avatarImg.src = obj.avatarUrl;
avatarImg.alt = "avatar of " + obj.author;
avatarWrapper.append(avatarImg);
const discussionTitle = document.createElement("h2");
const titleAnchor = document.createElement("a");
titleAnchor.href = obj.url;
titleAnchor.textContent = obj.title;
discussionTitle.append(titleAnchor);
const discussionInformation = document.createElement("div");
discussionInformation.className = "discussion__information";
discussionInformation.textContent = `${obj.author} / ${new Date(
obj.createdAt
).toLocaleTimeString()}`;
discussionContent.append(discussionTitle, discussionInformation);
const checked = document.createElement("p");
checked.textContent = obj.answer ? "☑" : "☒";
discussionAnswered.append(checked);
li.append(avatarWrapper, discussionContent, discussionAnswered);
return li;
};
// data 배열의 모든 데이터를 화면에 렌더링하는 함수입니다.
const render = (element, from, to) => {
console.log(from, to);
if (!from && !to) {
from = 0;
to = data.length - 1;
}
// 다 지우고 배열에 있는 내용 다 보여주기
while (element.firstChild) {
element.removeChild(element.firstChild);
}
for (let i = from; i < to; i += 1) {
element.append(convertToDiscussion(data[i]));
}
return;
};
// 페이지네이션을 위한 변수
let limit = 10,
page = 1;
// ul 요소에 data 배열의 모든 데이터를 화면에 렌더링합니다.
const ul = document.querySelector("ul.discussions__container");
render(ul, 0, limit);
// const getPageStartEnd = (limit, page) => {
// const len = data.length - 1;
// let pageStart = Number(page - 1) * Number(limit);
// let pageEnd = Number(pageStart) + Number(limit);
// if (page <= 0) {
// pageStart = 0;
// }
// if (pageEnd >= len) {
// pageEnd = len;
// }
// return { pageStart, pageEnd };
// };
// const buttons = document.querySelector(".buttons");
// buttons.children[0].addEventListener("click", () => {
// if (page > 1) {
// page = page - 1;
// }
// const { pageStart, pageEnd } = getPageStartEnd(limit, page);
// render(ul, pageStart, pageEnd);
// });
// buttons.children[1].addEventListener("click", () => {
// if (limit * page < data.length - 1) {
// page = page + 1;
// }
// const { pageStart, pageEnd } = getPageStartEnd(limit, page);
// render(ul, pageStart, pageEnd);
// });
// buttons.children[2].addEventListener("click", () => {
// localStorage.removeItem("agoraStatesDiscussions");
// data = agoraStatesDiscussions.slice();
// limit = 10;
// page = 1;
// render(ul, 0, limit);
// });
// 문서의 내용을 확인해야 합니다.
const form = document.querySelector("form.form");
const author = form.querySelector("div.form__input--name > input");
const title = form.querySelector("div.form__input--title > input");
const textbox = form.querySelector("div.form__textbox > textarea");
// 문서를 제출해야 합니다.
form.addEventListener("submit", (event) => {
event.preventDefault();
const obj = {
id: "unique id",
createdAt: new Date().toISOString(),
title: title.value,
url: "https://github.com/codestates-seb/agora-states-fe/discussions",
author: author.value,
answer: null,
bodyHTML: textbox.value,
avatarUrl:
"https://avatars.githubusercontent.com/u/12145019?s=64&u=5c97f25ee02d87898457e23c0e61b884241838e3&v=4",
};
data.unshift(obj);
// 로컬스토리지에 저장
localStorage.setItem("agoraStatesDiscussions", JSON.stringify(data));
// 렌더링
render(ul, 0, limit);
});
답변 렌더링(취소)
질문을 클릭하면 화면에 답변까지 렌더링되는 것까지 고려했기 때문에 어떤 식으로 할지 고민을 해 보았다.
1. 게시물을 클릭하면 질문 내용 + 답변이 화면의 아래에 크게 뜨도록 한다.
-> 보통 문답게시판에 오는 사용자들은 여러 질문들을 여러 개 탭을 키워놓고 자료를 찾을 가능성이 높다.
클릭 한 번에 게시물을 하나만 볼 수 있는 것은 사용자 경험에 고려했을 때 바람직하지 않음
2. 게시물을 클릭하면 질문 내용 + 답변에 팝업처럼 뜨게 한다.
-> 1번의 이유와 마찬가지
최선의 경우는 클릭했을 때 게시글들이 새 탭으로 뜨게하는 방법이다. 그런 결론을 내었기 때문에 이번 미니 프로젝트에서는 딱히 건들지 않았다.
내가 상상하고 원하는 무언가를 디지털 상에 구현할 수 있다는 것 자체가 짜릿하다. 하면 할 수록 빠져든다. 너무 재밌다.. 빨리 나만의 웹앱을 만들 수 있는 날이 오길!
728x90
'📌 TOY-PROJECT > 2303 문답게시판' 카테고리의 다른 글
[연습 프로젝트] 문답 게시판_서버 개발 (0) | 2023.04.09 |
---|---|
[연습 프로젝트] 문답 게시판 _ pagination & local storage 코드 분석 (0) | 2023.03.18 |
[연습 프로젝트] 컴포넌트(component) 만들기 (0) | 2023.03.12 |
[연습 프로젝트] 나만의 아고라 스테이츠 만들기 (0) | 2023.03.12 |