diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..373c5df0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +package-lock.json +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index 95e87fdf..3bada591 100644 --- a/README.md +++ b/README.md @@ -3,58 +3,56 @@ # Blog with API

- Version + Version

-> In this pill you will put into practice the knowledge learned about making HTTP requests to create a blog consuming the information from a third-party API. You will also learn how to use Bootstrap Framework for the layout. +> In this project we put into practice the knowledge acquired on how to make HTTP requests to create a blog that consumes information from a third-party API. You'll also learn how to use the Bootstrap Framework for design. ## Index -- [Requirements](#requirements) -- [Repository](#repository) +- [Install](#install) +- [Getting Started](#starting) - [Technologies used](#technologies-used) -- [Project delivery](#project-delivery) -- [Resources](#resources) +- [Live Demo](#live-demo) +- [Work Log](#work-log) -## Requirements +## Install -- You must use semantic HTML5 elements for all the contents of the application -- You must use JSON server library to create your own local repository -- You must use fecth to do the requests -- You have to use Bootstrap Framework for the Layout and the styles +- Download repository +```javascript + git clone git@github.com:alejandroaperez1994g/blog-with-api.git + cd blog-with-api +``` +- Install json-server +```javascript + npm install +``` -## Repository +- Execute json-server -First of all you must fork this project into your GitHub account. +```javascript + npm run server +``` -To create a fork on GitHub is as easy as clicking the “fork” button on the repository page. +## Starting -Fork on GitHub +This is a project that simulates the display of posts brought from an API, being able to delete them and modify the content. ## Technologies used -\* HTML +- HTML +- CSS +- JS +- Bootstrap +- HTTP Requests +- JSON +- API -\* CSS +## Preview -\* JS +image image -\* Bootstrap +## Work Log -\* HTTP Requests - -\* JSON - -\* API - -## Project delivery - -To deliver this project you must follow the steps indicated in the document: - -- [Submitting a solution](https://www.notion.so/Submitting-a-solution-524dab1a71dd4b96903f26385e24cdb6) - -## Resources - -- [JSON server](https://github.com/typicode/json-server) -- [Official Bootstrap](https://getbootstrap.com/) \ No newline at end of file +image image image diff --git a/data/db.json b/data/db.json index 7fcbe2a9..71842b95 100644 --- a/data/db.json +++ b/data/db.json @@ -1,35 +1,5 @@ { "posts": [ - { - "userId": 1, - "id": 1, - "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", - "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" - }, - { - "userId": 1, - "id": 2, - "title": "qui est esse", - "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla" - }, - { - "userId": 1, - "id": 3, - "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut", - "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut" - }, - { - "userId": 1, - "id": 4, - "title": "eum et est occaecati", - "body": "ullam et saepe reiciendis voluptatem adipisci\nsit amet autem assumenda provident rerum culpa\nquis hic commodi nesciunt rem tenetur doloremque ipsam iure\nquis sunt voluptatem rerum illo velit" - }, - { - "userId": 1, - "id": 5, - "title": "nesciunt quas odio", - "body": "repudiandae veniam quaerat sunt sed\nalias aut fugiat sit autem sed est\nvoluptatem omnis possimus esse voluptatibus quis\nest aut tenetur dolor neque" - }, { "userId": 1, "id": 6, @@ -531,8 +501,8 @@ { "userId": 9, "id": 89, - "title": "sint soluta et vel magnam aut ut sed qui", - "body": "repellat aut aperiam totam temporibus autem et\narchitecto magnam ut\nconsequatur qui cupiditate rerum quia soluta dignissimos nihil iure\ntempore quas est" + "title": "89: sint soluta et vel magnam aut ut sed qui", + "body": "repellat aut aperiam totam temporibus autem et\narchitecto magnam ut\nc nihil iure\ntempore quas est" }, { "userId": 9, @@ -543,7 +513,7 @@ { "userId": 10, "id": 91, - "title": "aut amet sed", + "title": "91: aut amet sed", "body": "libero voluptate eveniet aperiam sed\nsunt placeat suscipit molestias\nsimilique fugit nam natus\nexpedita consequatur consequatur dolores quia eos et placeat" }, { @@ -834,181 +804,6 @@ } ], "comments": [ - { - "postId": 1, - "id": 1, - "name": "id labore ex et quam laborum", - "email": "Eliseo@gardner.biz", - "body": "laudantium enim quasi est quidem magnam voluptate ipsam eos\ntempora quo necessitatibus\ndolor quam autem quasi\nreiciendis et nam sapiente accusantium" - }, - { - "postId": 1, - "id": 2, - "name": "quo vero reiciendis velit similique earum", - "email": "Jayne_Kuhic@sydney.com", - "body": "est natus enim nihil est dolore omnis voluptatem numquam\net omnis occaecati quod ullam at\nvoluptatem error expedita pariatur\nnihil sint nostrum voluptatem reiciendis et" - }, - { - "postId": 1, - "id": 3, - "name": "odio adipisci rerum aut animi", - "email": "Nikita@garfield.biz", - "body": "quia molestiae reprehenderit quasi aspernatur\naut expedita occaecati aliquam eveniet laudantium\nomnis quibusdam delectus saepe quia accusamus maiores nam est\ncum et ducimus et vero voluptates excepturi deleniti ratione" - }, - { - "postId": 1, - "id": 4, - "name": "alias odio sit", - "email": "Lew@alysha.tv", - "body": "non et atque\noccaecati deserunt quas accusantium unde odit nobis qui voluptatem\nquia voluptas consequuntur itaque dolor\net qui rerum deleniti ut occaecati" - }, - { - "postId": 1, - "id": 5, - "name": "vero eaque aliquid doloribus et culpa", - "email": "Hayden@althea.biz", - "body": "harum non quasi et ratione\ntempore iure ex voluptates in ratione\nharum architecto fugit inventore cupiditate\nvoluptates magni quo et" - }, - { - "postId": 2, - "id": 6, - "name": "et fugit eligendi deleniti quidem qui sint nihil autem", - "email": "Presley.Mueller@myrl.com", - "body": "doloribus at sed quis culpa deserunt consectetur qui praesentium\naccusamus fugiat dicta\nvoluptatem rerum ut voluptate autem\nvoluptatem repellendus aspernatur dolorem in" - }, - { - "postId": 2, - "id": 7, - "name": "repellat consequatur praesentium vel minus molestias voluptatum", - "email": "Dallas@ole.me", - "body": "maiores sed dolores similique labore et inventore et\nquasi temporibus esse sunt id et\neos voluptatem aliquam\naliquid ratione corporis molestiae mollitia quia et magnam dolor" - }, - { - "postId": 2, - "id": 8, - "name": "et omnis dolorem", - "email": "Mallory_Kunze@marie.org", - "body": "ut voluptatem corrupti velit\nad voluptatem maiores\net nisi velit vero accusamus maiores\nvoluptates quia aliquid ullam eaque" - }, - { - "postId": 2, - "id": 9, - "name": "provident id voluptas", - "email": "Meghan_Littel@rene.us", - "body": "sapiente assumenda molestiae atque\nadipisci laborum distinctio aperiam et ab ut omnis\net occaecati aspernatur odit sit rem expedita\nquas enim ipsam minus" - }, - { - "postId": 2, - "id": 10, - "name": "eaque et deleniti atque tenetur ut quo ut", - "email": "Carmen_Keeling@caroline.name", - "body": "voluptate iusto quis nobis reprehenderit ipsum amet nulla\nquia quas dolores velit et non\naut quia necessitatibus\nnostrum quaerat nulla et accusamus nisi facilis" - }, - { - "postId": 3, - "id": 11, - "name": "fugit labore quia mollitia quas deserunt nostrum sunt", - "email": "Veronica_Goodwin@timmothy.net", - "body": "ut dolorum nostrum id quia aut est\nfuga est inventore vel eligendi explicabo quis consectetur\naut occaecati repellat id natus quo est\nut blanditiis quia ut vel ut maiores ea" - }, - { - "postId": 3, - "id": 12, - "name": "modi ut eos dolores illum nam dolor", - "email": "Oswald.Vandervort@leanne.org", - "body": "expedita maiores dignissimos facilis\nipsum est rem est fugit velit sequi\neum odio dolores dolor totam\noccaecati ratione eius rem velit" - }, - { - "postId": 3, - "id": 13, - "name": "aut inventore non pariatur sit vitae voluptatem sapiente", - "email": "Kariane@jadyn.tv", - "body": "fuga eos qui dolor rerum\ninventore corporis exercitationem\ncorporis cupiditate et deserunt recusandae est sed quis culpa\neum maiores corporis et" - }, - { - "postId": 3, - "id": 14, - "name": "et officiis id praesentium hic aut ipsa dolorem repudiandae", - "email": "Nathan@solon.io", - "body": "vel quae voluptas qui exercitationem\nvoluptatibus unde sed\nminima et qui ipsam aspernatur\nexpedita magnam laudantium et et quaerat ut qui dolorum" - }, - { - "postId": 3, - "id": 15, - "name": "debitis magnam hic odit aut ullam nostrum tenetur", - "email": "Maynard.Hodkiewicz@roberta.com", - "body": "nihil ut voluptates blanditiis autem odio dicta rerum\nquisquam saepe et est\nsunt quasi nemo laudantium deserunt\nmolestias tempora quo quia" - }, - { - "postId": 4, - "id": 16, - "name": "perferendis temporibus delectus optio ea eum ratione dolorum", - "email": "Christine@ayana.info", - "body": "iste ut laborum aliquid velit facere itaque\nquo ut soluta dicta voluptate\nerror tempore aut et\nsequi reiciendis dignissimos expedita consequuntur libero sed fugiat facilis" - }, - { - "postId": 4, - "id": 17, - "name": "eos est animi quis", - "email": "Preston_Hudson@blaise.tv", - "body": "consequatur necessitatibus totam sed sit dolorum\nrecusandae quae odio excepturi voluptatum harum voluptas\nquisquam sit ad eveniet delectus\ndoloribus odio qui non labore" - }, - { - "postId": 4, - "id": 18, - "name": "aut et tenetur ducimus illum aut nulla ab", - "email": "Vincenza_Klocko@albertha.name", - "body": "veritatis voluptates necessitatibus maiores corrupti\nneque et exercitationem amet sit et\nullam velit sit magnam laborum\nmagni ut molestias" - }, - { - "postId": 4, - "id": 19, - "name": "sed impedit rerum quia et et inventore unde officiis", - "email": "Madelynn.Gorczany@darion.biz", - "body": "doloribus est illo sed minima aperiam\nut dignissimos accusantium tempore atque et aut molestiae\nmagni ut accusamus voluptatem quos ut voluptates\nquisquam porro sed architecto ut" - }, - { - "postId": 4, - "id": 20, - "name": "molestias expedita iste aliquid voluptates", - "email": "Mariana_Orn@preston.org", - "body": "qui harum consequatur fugiat\net eligendi perferendis at molestiae commodi ducimus\ndoloremque asperiores numquam qui\nut sit dignissimos reprehenderit tempore" - }, - { - "postId": 5, - "id": 21, - "name": "aliquid rerum mollitia qui a consectetur eum sed", - "email": "Noemie@marques.me", - "body": "deleniti aut sed molestias explicabo\ncommodi odio ratione nesciunt\nvoluptate doloremque est\nnam autem error delectus" - }, - { - "postId": 5, - "id": 22, - "name": "porro repellendus aut tempore quis hic", - "email": "Khalil@emile.co.uk", - "body": "qui ipsa animi nostrum praesentium voluptatibus odit\nqui non impedit cum qui nostrum aliquid fuga explicabo\nvoluptatem fugit earum voluptas exercitationem temporibus dignissimos distinctio\nesse inventore reprehenderit quidem ut incidunt nihil necessitatibus rerum" - }, - { - "postId": 5, - "id": 23, - "name": "quis tempora quidem nihil iste", - "email": "Sophia@arianna.co.uk", - "body": "voluptates provident repellendus iusto perspiciatis ex fugiat ut\nut dolor nam aliquid et expedita voluptate\nsunt vitae illo rerum in quos\nvel eligendi enim quae fugiat est" - }, - { - "postId": 5, - "id": 24, - "name": "in tempore eos beatae est", - "email": "Jeffery@juwan.us", - "body": "repudiandae repellat quia\nsequi est dolore explicabo nihil et\net sit et\net praesentium iste atque asperiores tenetur" - }, - { - "postId": 5, - "id": 25, - "name": "autem ab ea sit alias hic provident sit", - "email": "Isaias_Kuhic@jarrett.net", - "body": "sunt aut quae laboriosam sit ut impedit\nadipisci harum laborum totam deleniti voluptas odit rem ea\nnon iure distinctio ut velit doloribus\net non ex" - }, { "postId": 6, "id": 26, @@ -4335,4 +4130,4 @@ "body": "perspiciatis quis doloremque\nveniam nisi eos velit sed\nid totam inventore voluptatem laborum et eveniet\naut aut aut maxime quia temporibus ut omnis" } ] -} +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 00000000..cb7d1ef3 --- /dev/null +++ b/index.html @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + Blog + + + + +
+

Feel free to share your opinions

+ + + +
+ + + + + + + \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..2b054e43 --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "blog-with-api", + "version": "1.0.0", + "description": "`#html` `#css` `#js` `#dom` `#JSON` `#HTTP` `#API` `#Bootstrap` `#master-in-software-development`", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "server": "json-server --watch ./data/db.json" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/alejandroaperez1994g/blog-with-api.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/alejandroaperez1994g/blog-with-api/issues" + }, + "homepage": "https://github.com/alejandroaperez1994g/blog-with-api#readme", + "dependencies": { + "json-server": "0.17.0" + } +} diff --git a/src/assets/Aablog.jpg b/src/assets/Aablog.jpg new file mode 100644 index 00000000..047cbe49 Binary files /dev/null and b/src/assets/Aablog.jpg differ diff --git a/src/assets/bloglogo.png b/src/assets/bloglogo.png new file mode 100644 index 00000000..8a116bdd Binary files /dev/null and b/src/assets/bloglogo.png differ diff --git a/src/assets/icon/blog.png b/src/assets/icon/blog.png new file mode 100644 index 00000000..43633c12 Binary files /dev/null and b/src/assets/icon/blog.png differ diff --git a/src/assets/images/demo-mobile.gif b/src/assets/images/demo-mobile.gif new file mode 100644 index 00000000..9695a06e Binary files /dev/null and b/src/assets/images/demo-mobile.gif differ diff --git a/src/assets/images/demo.gif b/src/assets/images/demo.gif new file mode 100644 index 00000000..09809510 Binary files /dev/null and b/src/assets/images/demo.gif differ diff --git a/src/js/api.js b/src/js/api.js new file mode 100644 index 00000000..e6205db5 --- /dev/null +++ b/src/js/api.js @@ -0,0 +1,54 @@ +import { updatePosts } from "./main.js"; + +const fetchPosts = async () => { + return await fetch("http://localhost:3000/posts") + .then((response) => response.json()) + .then((data) => data) + .catch((e) => console.error(e)); +}; + +const fetchUser = async (userId) => { + return await fetch(`http://localhost:3000/users?id=${userId}`) + .then((response) => response.json()) + .then((data) => data) + .catch((e) => console.error(e)); +}; + +const fetchComments = async (postId) => { + return await fetch(`http://localhost:3000/comments?postId=${postId}`) + .then((response) => response.json()) + .then((data) => data) + .catch((e) => console.error(e)); +}; +const modifyPost = async (postId, postTitle, postBody) => { + return await fetch(`http://localhost:3000/posts/${postId}`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ title: postTitle, body: postBody }), + }) + .then((response) => + response.json().then((data) => { + updatePosts(); + }) + ) + .catch((e) => console.error(e)); +}; + +const deletePost = async (postId) => { + fetch(`http://localhost:3000/posts/${postId}`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + }) + .then((response) => + response.json().then((data) => { + updatePosts(); + }) + ) + .catch((e) => console.error(e)); +}; + +export { fetchPosts, fetchUser, fetchComments, modifyPost, deletePost }; diff --git a/src/js/main.js b/src/js/main.js new file mode 100644 index 00000000..1d75aac2 --- /dev/null +++ b/src/js/main.js @@ -0,0 +1,140 @@ +import { + fetchPosts, + fetchUser, + fetchComments, + modifyPost, + deletePost, +} from "./api.js"; +import { + createPost, + addPaginators, + updatePostsDisplay, + updateDisplay, + startNumberPagination, + endNumberPagination, +} from "./utils.js"; + +const postList = document.getElementById("postList"); +const btnComments = document.getElementById("btnComents"); +const commentsUl = document.getElementById("modal__comments"); +const saveBtn = document.getElementById("saveBtn"); +const modifyTitle = document.getElementById("modifyTitle"); +const modifyBody = document.getElementById("modifyBody"); +const deleteBtn = document.getElementById("deleteButton"); + +const getPosts = (startNumber, endNumber) => { + fetchPosts().then((data) => { + data.forEach((post, index) => { + if (index >= startNumber && index < endNumber) { + const liElement = createPost( + post.userId, + post.id, + post.title, + post.body, + index + ); + + postList.append(liElement); + } + }); + addMultiEvents(); + }); +}; + +function addMultiEvents() { + const modalTitle = document.getElementById("modalTitle"); + const modalBody = document.getElementById("modal__post_body"); + const userName = document.getElementById("user_name"); + const userEmail = document.getElementById("user_email"); + + Array.from(postList.children).map((post) => { + const title = post.querySelector("h3"); + const modifyBtn = post.querySelector("[data-modify]"); + const body = title.nextElementSibling; + modifyBtn.addEventListener("click", (e) => { + let id = e.target.getAttribute("data-id"); + modifyTitle.value = title.textContent; + modifyBody.value = body.textContent; + modifyTitle.setAttribute("data-id", id); + }); + + const deleteButton = post.querySelector("[data-delete]"); + deleteButton.addEventListener("click", (e) => { + const dataId = e.target.getAttribute("data-id"); + deleteBtn.setAttribute("data-id", dataId); + }); + + title.addEventListener("click", (e) => { + if (btnComments.classList.value.includes("hide")) { + btnComments.classList.remove("hide"); + commentsUl.classList.add("hide"); + } + + let user = fetchUser(e.target.getAttribute("data-userId")); + user.then((data) => { + userName.textContent = data[0].username; + userEmail.textContent = data[0].email.toLowerCase(); + }); + btnComments.setAttribute( + "data-postId", + `${e.target.getAttribute("data-id")}` + ); + modalTitle.textContent = e.target.textContent; + modalBody.textContent = e.target.nextSibling.textContent; + }); + }); +} + +const updatePosts = () => { + updatePostsDisplay(); + getPosts(startNumberPagination, endNumberPagination); +}; + +saveBtn.addEventListener("click", (e) => { + e.preventDefault(); + + const title = document.getElementById("modifyTitle"); + const body = document.getElementById("modifyBody"); + const id = title.getAttribute("data-id"); + modifyPost(id, title.value, body.value); +}); + +btnComments.addEventListener("click", (e) => { + commentsUl.classList.toggle("hide"); + btnComments.classList.toggle("hide"); + let postId = e.target.getAttribute("data-postId"); + fetchComments(postId).then((data) => { + updateDisplay(); + data.forEach((dataComment) => { + const commentsLi = document.createElement("li"); + const commentsTitle = document.createElement("p"); + const commentsBody = document.createElement("p"); + const commentsUser = document.createElement("p"); + commentsTitle.textContent = `Title: ${dataComment.name}`; + commentsBody.textContent = `Comment: ${dataComment.body}`; + commentsUser.textContent = `e.mail: ${dataComment.email}`; + commentsLi.append(commentsTitle, commentsBody, commentsUser); + commentsUl.appendChild(commentsLi); + commentsUl.classList.add("comments__ul"); + commentsUl.setAttribute("data-bs-spy", "scroll"); + commentsUl.setAttribute("data-target", ".navbar"); + commentsUl.setAttribute("data-offset", "'50'"); + commentsLi.classList.add("comments__li"); + commentsTitle.classList.add("comments__title"); + commentsUser.classList.add("comments_user"); + // commentsTitle, + }); + }); +}); +deleteBtn.addEventListener("click", (e) => { + const dataId = e.target.getAttribute("data-id"); + console.log(dataId); + deletePost(dataId); + updatePostsDisplay(); + getPosts(startNumberPagination, endNumberPagination); +}); + +getPosts(0, 10); +addPaginators(); + +export { getPosts, postList, commentsUl, updatePosts }; diff --git a/src/js/utils.js b/src/js/utils.js new file mode 100644 index 00000000..be1eccf6 --- /dev/null +++ b/src/js/utils.js @@ -0,0 +1,112 @@ +import { getPosts, postList, commentsUl } from "./main.js"; +const paginatorNumbers = document.querySelectorAll("[data-type]"); +const previousPage = document.getElementById("previous-page"); +const nextPage = document.getElementById("next-page"); +let startNumberPagination = 0; +let endNumberPagination = 10; + +previousPage.addEventListener("click", (e) => { + e.preventDefault(); + if (startNumberPagination < 10) return; + startNumberPagination -= 10; + endNumberPagination -= 10; + updatePostsDisplay(); + getPosts(startNumberPagination, endNumberPagination); +}); + +nextPage.addEventListener("click", (e) => { + e.preventDefault(); + if (endNumberPagination > 90) return; + startNumberPagination += 10; + endNumberPagination += 10; + updatePostsDisplay(); + getPosts(startNumberPagination, endNumberPagination); +}); + +const createPost = (userId, id, title, body, index) => { + const liElement = document.createElement("li"); + liElement.classList.add("article__post"); + const avatarImg = document.createElement("img"); + avatarImg.classList.add("img__avatar"); + const postContainer = document.createElement("div"); + postContainer.classList.add("post__container"); + const postTitle = document.createElement("h3"); + postTitle.classList.add("post__title", "openModal"); + const postBody = document.createElement("p"); + postBody.classList.add("post__body"); + const buttonsContainer = document.createElement("div"); + buttonsContainer.classList.add("buttons__container"); + const modifyButton = document.createElement("button"); + modifyButton.classList.add("btn", "btn-secondary", "btn__modify"); + const iconModify = document.createElement("i"); + iconModify.classList.add("bi", "bi-bookmark-check"); + const deleteButton = document.createElement("button"); + deleteButton.classList.add("btn", "btn-warning", "btn__delete"); + const iconDelete = document.createElement("i"); + iconDelete.classList.add("bi", "bi-file-x"); + + postTitle.textContent = `${title}`; + postTitle.setAttribute("data-id", id); + postTitle.setAttribute("data-userId", userId); + + postTitle.setAttribute("data-bs-toggle", "modal"); + postTitle.setAttribute("data-bs-target", "#modalWindow"); + modifyButton.setAttribute("data-bs-toggle", "modal"); + postBody.textContent = body; + deleteButton.setAttribute("data-id", id); + deleteButton.setAttribute("data-bs-toggle", "modal"); + deleteButton.setAttribute("data-bs-target", "#modalDelete"); + + deleteButton.textContent = "Delete"; + modifyButton.setAttribute("data-id", id); + modifyButton.setAttribute("data-bs-target", "#modalModify"); + modifyButton.setAttribute("data-modify", true); + modifyButton.textContent = "Modify"; + deleteButton.setAttribute("data-delete", true); + + avatarImg.src = `https://source.unsplash.com/16${index}x9${index}/?profile picture?orientation=portrait`; + + deleteButton.append(iconDelete); + modifyButton.append(iconModify); + buttonsContainer.append(modifyButton, deleteButton); + postContainer.append(postTitle, postBody, buttonsContainer); + liElement.append(avatarImg, postContainer); + + return liElement; +}; + +const updatePostsDisplay = () => { + while (postList.firstChild) { + postList.removeChild(postList.lastChild); + } +}; + +const updateDisplay = () => { + while (commentsUl.firstChild) { + commentsUl.removeChild(commentsUl.lastChild); + } +}; + +const addPaginators = () => { + Array.from(paginatorNumbers).map((number) => { + number.addEventListener("click", (e) => { + e.preventDefault(); + updatePostsDisplay(); + startNumberPagination = (e.target.getAttribute("value") - 1) * 10; + endNumberPagination = e.target.getAttribute("value") * 10; + getPosts( + (e.target.getAttribute("value") - 1) * 10, + e.target.getAttribute("value") * 10 + ); + }); + }); +}; + +export { + createPost, + addPaginators, + updatePostsDisplay, + updateDisplay, + startNumberPagination, + endNumberPagination, +}; diff --git a/src/styles/reset.css b/src/styles/reset.css new file mode 100644 index 00000000..af944401 --- /dev/null +++ b/src/styles/reset.css @@ -0,0 +1,48 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} \ No newline at end of file diff --git a/src/styles/style.css b/src/styles/style.css new file mode 100644 index 00000000..04612854 --- /dev/null +++ b/src/styles/style.css @@ -0,0 +1,220 @@ +@import url(./reset.css); +@import url("https://fonts.googleapis.com/css2?family=Nunito&display=swap"); + +* { + font-family: "Nunito", sans-serif; +} +body { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background-image: url("../assets/Aablog.jpg"); + background-size: cover; + background-repeat: no-repeat; + background-attachment: fixed; +} +main { + display: flex; + flex-direction: column; + align-items: center; + position: relative; + width: 90vw; +} + +.article__post { + display: flex; + padding: 2%; + margin: 20px 10%; + border-radius: 5px; + box-shadow: 4px 4px 4px 4px rgb(199, 199, 199); +} +.post__container { + width: 100%; +} + +.postList { + background-color: aliceblue; + height: 70vh; + width: 75%; + margin: 0 15%; + padding-top: 2rem; + padding-bottom: 5rem; + overflow: overlay; + background-color: #fff6ea; +} + +.navbar { + position: sticky !important; + padding: 15%; + top: 0; + width: 100%; + z-index: 1; +} +.subTitle { + width: 75%; + padding: 20px; + margin: 0 15%; + font-weight: 700; + border-radius: 10px 10px 0 0; + margin-top: 2rem; + background-color: #fff6ea; + color: black; + text-align: center; +} + +.img__avatar { + height: 4rem; + width: 4rem; + border-radius: 50%; + margin-right: 1rem; +} + +.buttons__container { + display: flex; + flex-wrap: wrap; + justify-content: flex-end; + margin-top: 20px; +} + +.btn__delete { + margin-left: 2rem; +} + +.openModal:hover { + color: rgb(224, 89, 89); + cursor: pointer; +} + +.footer { + width: 75%; + margin-bottom: 0; +} +.pagination { + display: flex; + justify-content: center; + background-color: aliceblue; + border-radius: 0 0 10px 10px; + background-color: #fff6ea; +} +.comments__li { + list-style-type: none; + box-shadow: 2px 2px 2px 2px rgb(199, 199, 199); + padding: 2%; + margin: 20px 0; +} +.comments__li:hover { + background-color: beige; +} +.modify__title{ + width: 100%; + border: 1.5px solid black; + border-radius: 5px; + margin: 10px 0 20px 0; + box-shadow: 2px 2px 2px 2px rgb(199, 199, 199); +} +.modifyBody { + resize: none; + width: 100%; + border: 1.5px solid black; + border-radius: 5px; + margin: 10px 0 20px 0; + box-shadow: 2px 2px 2px 2px rgb(199, 199, 199); +} +.modal-body { + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; +} +.modal__comments { + overflow-y: overlay; + height: 70vh; +} +.hide { + display: none !important; +} + +/* Firefox */ +* { + scrollbar-width: auto; + scrollbar-color: #9f9d9d #ffffff; +} + +/* Chrome, Edge, and Safari */ +*::-webkit-scrollbar { + width: 16px; +} + +*::-webkit-scrollbar-track { + background: #fff6ea; + margin-top: 10px; + margin-bottom: 10px; +} + +*::-webkit-scrollbar-thumb { + background-color: #9f9d9d; + border-radius: 10px; + border: 3px solid #ffffff; +} + +@media (max-width: 700px) { + .navbar img { + margin: 0 auto; + align-items: center; + text-align: center; + justify-content: center; + } + .article__post { + display: flex; + flex-direction: column; + padding: 2%; + margin: 20px 0%; + border-radius: 5px; + box-shadow: 4px 4px 4px 4px rgb(199, 199, 199); + } + .postList { + margin: 0 2%; + padding-top: 2rem; + padding-bottom: 5rem; + } + .btn__modify { + margin-top: 0.7rem; + width: 100%; + } + .btn__delete { + margin-top: 0.7rem; + margin-left: 0; + } + .img__avatar { + margin: 10px auto; + width: 9rem; + height: 9rem; + } + .buttons__container { + display: flex; + flex-direction: column; + justify-content: flex-end; + margin-top: 20px; + } + ul#postList.postList { + padding-left: 0; + } + .postList{ + overflow: initial; + height: 100%; + width: 100%; + margin: 0 0; + } + .subTitle { + width: 100%; + padding: 20px; + margin: 0 15%; + font-weight: 700; + border-radius: 10px 10px 0 0; + margin-top: 2rem; + background-color: #fff6ea; + color: black; + text-align: center; + } +} \ No newline at end of file