diff --git a/data/db.json b/data/db.json index 7fcbe2a9..592084fc 100644 --- a/data/db.json +++ b/data/db.json @@ -3,7 +3,7 @@ { "userId": 1, "id": 1, - "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", + "title": "HOLA ALBERTO", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" }, { @@ -138,12 +138,6 @@ "title": "maxime id vitae nihil numquam", "body": "veritatis unde neque eligendi\nquae quod architecto quo neque vitae\nest illo sit tempora doloremque fugit quod\net et vel beatae sequi ullam sed tenetur perspiciatis" }, - { - "userId": 3, - "id": 24, - "title": "autem hic labore sunt dolores incidunt", - "body": "enim et ex nulla\nomnis voluptas quia qui\nvoluptatem consequatur numquam aliquam sunt\ntotam recusandae id dignissimos aut sed asperiores deserunt" - }, { "userId": 3, "id": 25, @@ -156,12 +150,6 @@ "title": "est et quae odit qui non", "body": "similique esse doloribus nihil accusamus\nomnis dolorem fuga consequuntur reprehenderit fugit recusandae temporibus\nperspiciatis cum ut laudantium\nomnis aut molestiae vel vero" }, - { - "userId": 3, - "id": 27, - "title": "quasi id et eos tenetur aut quo autem", - "body": "eum sed dolores ipsam sint possimus debitis occaecati\ndebitis qui qui et\nut placeat enim earum aut odit facilis\nconsequatur suscipit necessitatibus rerum sed inventore temporibus consequatur" - }, { "userId": 3, "id": 28, @@ -1639,41 +1627,6 @@ "email": "Tyrell@abdullah.ca", "body": "laudantium tempore aut\nmaiores laborum fugit qui suscipit hic sint officiis corrupti\nofficiis eum optio cumque fuga sed voluptatibus similique\nsit consequuntur rerum commodi" }, - { - "postId": 24, - "id": 116, - "name": "veritatis sit tempora quasi fuga aut dolorum", - "email": "Reyes@hailey.name", - "body": "quia voluptas qui assumenda nesciunt harum iusto\nest corrupti aperiam\nut aut unde maxime consequatur eligendi\nveniam modi id sint rem labore saepe minus" - }, - { - "postId": 24, - "id": 117, - "name": "incidunt quae optio quam corporis iste deleniti accusantium vero", - "email": "Danika.Dicki@mekhi.biz", - "body": "doloribus esse necessitatibus qui eos et ut est saepe\nsed rerum tempore est ut\nquisquam et eligendi accusantium\ncommodi non doloribus" - }, - { - "postId": 24, - "id": 118, - "name": "quisquam laborum reiciendis aut", - "email": "Alessandra.Nitzsche@stephania.us", - "body": "repudiandae aliquam maxime cupiditate consequatur id\nquas error repellendus\ntotam officia dolorem beatae natus cum exercitationem\nasperiores dolor ea" - }, - { - "postId": 24, - "id": 119, - "name": "minus pariatur odit", - "email": "Matteo@marquis.net", - "body": "et omnis consequatur ut\nin suscipit et voluptatem\nanimi at ut\ndolores quos aut numquam esse praesentium aut placeat nam" - }, - { - "postId": 24, - "id": 120, - "name": "harum error sit", - "email": "Joshua.Spinka@toby.io", - "body": "iusto sint recusandae placeat atque perferendis sit corporis molestiae\nrem dolor eius id delectus et qui\nsed dolorem reiciendis error ullam corporis delectus\nexplicabo mollitia odit laborum sed itaque deserunt rem dolorem" - }, { "postId": 25, "id": 121, @@ -1744,41 +1697,6 @@ "email": "Trevion_Kuphal@bernice.name", "body": "dicta sit culpa molestiae quasi at voluptate eos\ndolorem perferendis accusamus rerum expedita ipsum quis qui\nquos est deserunt\nrerum fuga qui aliquam in consequatur aspernatur" }, - { - "postId": 27, - "id": 131, - "name": "voluptas quasi sunt laboriosam", - "email": "Emmet@guy.biz", - "body": "rem magnam at voluptatem\naspernatur et et nostrum rerum\ndignissimos eum quibusdam\noptio quod dolores et" - }, - { - "postId": 27, - "id": 132, - "name": "unde tenetur vero eum iusto", - "email": "Megane.Fritsch@claude.name", - "body": "ullam harum consequatur est rerum est\nmagni tenetur aperiam et\nrepudiandae et reprehenderit dolorum enim voluptas impedit\neligendi quis necessitatibus in exercitationem voluptatem qui" - }, - { - "postId": 27, - "id": 133, - "name": "est adipisci laudantium amet rem asperiores", - "email": "Amya@durward.ca", - "body": "sunt quis iure molestias qui ipsa commodi dolore a\nodio qui debitis earum\nunde ut omnis\ndoloremque corrupti at repellendus earum eum" - }, - { - "postId": 27, - "id": 134, - "name": "reiciendis quo est vitae dignissimos libero ut officiis fugiat", - "email": "Jasen_Rempel@willis.org", - "body": "corrupti perspiciatis eligendi\net omnis tempora nobis dolores hic\ndolorum vitae odit\nreiciendis sunt odit qui" - }, - { - "postId": 27, - "id": 135, - "name": "inventore fugiat dignissimos", - "email": "Harmony@reggie.com", - "body": "sapiente nostrum dolorem odit a\nsed animi non architecto doloremque unde\nnam aut aut ut facilis\net ut autem fugit minima culpa inventore non" - }, { "postId": 28, "id": 136, @@ -4335,4 +4253,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/documentation/Blog With API - Marcel y Gonzalo.pdf b/documentation/Blog With API - Marcel y Gonzalo.pdf new file mode 100644 index 00000000..24596bc2 Binary files /dev/null and b/documentation/Blog With API - Marcel y Gonzalo.pdf differ diff --git a/favicon.svg b/favicon.svg new file mode 100644 index 00000000..fa76384e --- /dev/null +++ b/favicon.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/img/eraser.svg b/img/eraser.svg new file mode 100644 index 00000000..a194a141 --- /dev/null +++ b/img/eraser.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/world.svg b/img/world.svg new file mode 100644 index 00000000..fa76384e --- /dev/null +++ b/img/world.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/img/writing.svg b/img/writing.svg new file mode 100644 index 00000000..d53f1cb1 --- /dev/null +++ b/img/writing.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/loadMore.js b/loadMore.js new file mode 100644 index 00000000..0fe726eb --- /dev/null +++ b/loadMore.js @@ -0,0 +1,9 @@ +let rowPost = document.querySelector(".row"); + +btnMore.addEventListener("click", loadMorePosts); + +function loadMorePosts() { + let cloneRow = rowPost.cloneNode(true); + divCont.appendChild(cloneRow); + ids(); +} diff --git a/main.html b/main.html new file mode 100644 index 00000000..d323c4a3 --- /dev/null +++ b/main.html @@ -0,0 +1,244 @@ + + + + + + + + Blog with API + +
+ + + +
+
+
+ ... +
+
+

+ + + +
+
+
+ ... +
+
+

+ + + +
+
+
+ ... +
+
+

+ +
+
+
+ +
+
+ ... +
+
+

+ + +
+
+
+ ... +
+
+

+ +
+
+
+ ... +
+
+

+ +
+
+
+
+
+ + + + + + + + diff --git a/main.js b/main.js new file mode 100644 index 00000000..90270162 --- /dev/null +++ b/main.js @@ -0,0 +1,240 @@ +let btnMore = document.getElementById("button--more"); +let divCont = document.getElementById("container--grid"); + +//---------------------------------------------------CARUSEL PICTURES + +document.getElementById("carousel-1").src = + "https://picsum.photos/id/30/1000/400"; +document.getElementById("carousel-2").src = + "https://picsum.photos/id/45/1000/400"; +document.getElementById("carousel-3").src = + "https://picsum.photos/id/55/1000/400"; + +//---------------------------------------------------ADDING IDS TO CARDS AND MORE + +function ids() { + let cards = document.querySelectorAll(".card"); + for (let index = 0; index < cards.length; index++) { + //We are adding ids to the cards and buttons + + cards[index].id = `id-${index}`; + let btnModal = cards[index].querySelector("a"); + btnModal.id = `btn-${index}`; + + //Now we set the data-bs-toggle and data-bs-target which Bootstrap requires + + btnModal.dataset.bsToggle = "modal"; + btnModal.dataset.bsTarget = "#modal--main"; + + //We get the information of each post and fill the cards with it + + fetch(`http://localhost:3000/posts/${index + 1}`) + .then((response) => { + return response.json(); + }) + .then((response) => { + cards[index].querySelector(".card-title").textContent = response.title; + cards[index].querySelector(".card-text").textContent = + response.body.substring(0, 30) + "..."; + }); + + //We get a new picture for each card + + cards[index].querySelector("img").src = `https://picsum.photos/id/${ + index + 10 + index + }/300`; + + //We add the event listener to each button + + btnModal.addEventListener("click", fillingModal); + } +} + +ids(); + +//---------------------------------------------------FILLING THE MODAL'S CONTENT + +function fillingModal(e) { + //We are getting the button's id ("btn-x") and slicing only the number. It comes as string so we parse it + let btnID = parseInt(e.target.id.slice(4, e.target.id.length)); + let modal = document.querySelector("#modal-content"); + let modalTitle = document.getElementById("modal_title"); + let userInfo = document.createElement("section"); + let listComments = document.createElement("section"); + let btnComments = document.querySelector("#btn-comments"); + let btnEdit = document.querySelector("#btn-edit"); + let btnDelete = document.querySelector("#btn-delete"); + let modalBody = document.getElementById("modal_body"); + + //We search inside the API for the post with the btnID + 1 id + + fetch(`http://localhost:3000/posts/${btnID + 1}`) + .then((response) => { + return response.json(); + }) + .then((response) => { + modalTitle.innerHTML = `${response.id} - ${response.title}`; + modalBody.textContent = response.body; + + //Whenever you call a function with a local parameter like userID (myFunct(parameter)), you pass the value of the parameter to the second function + let userID = response.userId; + userData(userID); + }); + + //We need the user's information to fill the modal + + function userData(userID) { + fetch(`http://localhost:3000/users/${userID}`) + .then((response) => { + return response.json(); + }) + .then((response) => { + //First of all, we erase any other possible user's info and comments + let list_comments = document.getElementById("list-comments"); + let user_info = document.getElementById("user-info"); + + if (user_info || list_comments) { + user_info.remove(); + list_comments.remove(); + } + let footer = document.querySelector(".modal-footer"); + if (footer.classList.contains("d-none")) + footer.classList.remove("d-none"); + + //if (!modalFooter) modal.appendChild(cloneFooter); + //Then we create a new section with the user's info and insert it dynamically in the modal-content div + + userInfo.id = "user-info"; + userInfo.className = "modal-body"; + userInfo.style.borderTop = "1px solid lightgrey"; + let username = document.createElement("p"); + username.innerHTML = `${response.name}`; + let mail = document.createElement("p"); + mail.innerHTML = response.email; + userInfo.appendChild(username); + userInfo.appendChild(mail); + modal.insertBefore(userInfo, modal.children[2]); //As we do not want it appended as the last child, we use the insertBefore method to add it after the third element of the div + }); + } + + btnComments.addEventListener("click", function myComments() { + fetch(`http://localhost:3000/comments?postId=${btnID + 1}&_limit=2`) + .then((response) => { + return response.json(); + }) + .then((response) => { + document.querySelector(".modal-footer").classList.add("d-none"); + listComments.id = "list-comments"; + for (let comment of response) { + listComments.innerHTML += ` + + `; + modal.insertBefore(listComments, modal.children[3]); + } + }); + //! Very important: if we do not delete the event listener, the user may click again and there are bugs + //! It also gets duplicated the next time we load other comments if we do not remove it here! + btnComments.removeEventListener("click", myComments); + }); + + btnEdit.addEventListener("click", editPost); + btnDelete.addEventListener("click", deletePost); +} + +//---------------------------------------------------EDIT POST + +function editPost() { + let title = document.getElementById("title-post"); + let body = document.getElementById("modal_body"); + + //We erase here the buttons to give more space inside the modal + document.querySelector(".modal-footer").classList.add("d-none"); + + //Now the title and the body of the post must appear as editable textareas + body.innerHTML = ` + `; + + title.innerHTML = ` + `; + + //We reset the user-info div so that it has the new button "Edit" + document.getElementById("user-info").innerHTML = ` + + `; + //We need to remove the event listener of the button to avoid conflicts and duplications + document.querySelector("#btn-edit").removeEventListener("click", editPost); + + //And now we set the new confirm "Edit" button to patch the changes + document + .querySelector("#btn-confirm") + .addEventListener("click", function confirmEdit() { + let idAgain = eval( + document.querySelector("#modal_title").textContent.substring(0, 2) + ); + let titleArea = document.querySelector("#textarea-title").value; + let bodyArea = document.querySelector("#textarea-body").value; + + fetch(`http://localhost:3000/posts/${idAgain}`, { + method: "PATCH", + body: JSON.stringify({ title: titleArea, body: bodyArea }), + headers: { "Content-type": "application/json; charset:UTF-8" }, + }) + .then((response) => { + response.json(); + }) + .then((json) => { + console.log(json); + }); + document + .querySelector("#btn-confirm") + .removeEventListener("click", confirmEdit); + }); +} + +//---------------------------------------------------DELETE POST + +function deletePost() { + let idAgain2 = eval( + document.querySelector("#modal_title").textContent.substring(0, 2) + ); + fetch( + `http://localhost:3000/posts/${idAgain2}`, + { + method: "DELETE", + headers: { "Content-type": "application/JSON; charset:UTF-8" }, + }, + null + ).then((response) => { + response.json(); + }); + document + .querySelector("#btn-delete") + .removeEventListener("click", deletePost); +}