├── .gitignore ├── LICENSE ├── README.md ├── data ├── comments.json ├── db.json ├── posts.json └── users.json ├── index.html ├── package.json └── src ├── assets ├── Aablog.jpg ├── bloglogo.png ├── icon │ └── blog.png └── images │ ├── demo-mobile.gif │ └── demo.gif ├── js ├── api.js ├── main.js └── utils.js └── styles ├── reset.css └── style.css /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | .DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Assembler School Of Software Engineering 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | `#html` `#css` `#js` `#dom` `#JSON` `#HTTP` `#API` `#Bootstrap` `#master-in-software-development` 2 | 3 | # Blog with API 4 | 5 |

6 | Version 7 |

8 | 9 | > 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. 10 | 11 | ## Index 12 | 13 | - [Install](#install) 14 | - [Getting Started](#starting) 15 | - [Technologies used](#technologies-used) 16 | - [Live Demo](#live-demo) 17 | - [Work Log](#work-log) 18 | 19 | ## Install 20 | 21 | - Download repository 22 | ```javascript 23 | git clone git@github.com:alejandroaperez1994g/blog-with-api.git 24 | cd blog-with-api 25 | ``` 26 | 27 | - Install json-server 28 | ```javascript 29 | npm install 30 | ``` 31 | 32 | - Execute json-server 33 | 34 | ```javascript 35 | npm run server 36 | ``` 37 | 38 | ## Starting 39 | 40 | This is a project that simulates the display of posts brought from an API, being able to delete them and modify the content. 41 | 42 | ## Technologies used 43 | 44 | - HTML 45 | - CSS 46 | - JS 47 | - Bootstrap 48 | - HTTP Requests 49 | - JSON 50 | - API 51 | 52 | ## Preview 53 | 54 | image image 55 | 56 | ## Work Log 57 | 58 | image image image 59 | -------------------------------------------------------------------------------- /data/posts.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "userId": 1, 4 | "id": 1, 5 | "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", 6 | "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" 7 | }, 8 | { 9 | "userId": 1, 10 | "id": 2, 11 | "title": "qui est esse", 12 | "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" 13 | }, 14 | { 15 | "userId": 1, 16 | "id": 3, 17 | "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut", 18 | "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" 19 | }, 20 | { 21 | "userId": 1, 22 | "id": 4, 23 | "title": "eum et est occaecati", 24 | "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" 25 | }, 26 | { 27 | "userId": 1, 28 | "id": 5, 29 | "title": "nesciunt quas odio", 30 | "body": "repudiandae veniam quaerat sunt sed\nalias aut fugiat sit autem sed est\nvoluptatem omnis possimus esse voluptatibus quis\nest aut tenetur dolor neque" 31 | }, 32 | { 33 | "userId": 1, 34 | "id": 6, 35 | "title": "dolorem eum magni eos aperiam quia", 36 | "body": "ut aspernatur corporis harum nihil quis provident sequi\nmollitia nobis aliquid molestiae\nperspiciatis et ea nemo ab reprehenderit accusantium quas\nvoluptate dolores velit et doloremque molestiae" 37 | }, 38 | { 39 | "userId": 1, 40 | "id": 7, 41 | "title": "magnam facilis autem", 42 | "body": "dolore placeat quibusdam ea quo vitae\nmagni quis enim qui quis quo nemo aut saepe\nquidem repellat excepturi ut quia\nsunt ut sequi eos ea sed quas" 43 | }, 44 | { 45 | "userId": 1, 46 | "id": 8, 47 | "title": "dolorem dolore est ipsam", 48 | "body": "dignissimos aperiam dolorem qui eum\nfacilis quibusdam animi sint suscipit qui sint possimus cum\nquaerat magni maiores excepturi\nipsam ut commodi dolor voluptatum modi aut vitae" 49 | }, 50 | { 51 | "userId": 1, 52 | "id": 9, 53 | "title": "nesciunt iure omnis dolorem tempora et accusantium", 54 | "body": "consectetur animi nesciunt iure dolore\nenim quia ad\nveniam autem ut quam aut nobis\net est aut quod aut provident voluptas autem voluptas" 55 | }, 56 | { 57 | "userId": 1, 58 | "id": 10, 59 | "title": "optio molestias id quia eum", 60 | "body": "quo et expedita modi cum officia vel magni\ndoloribus qui repudiandae\nvero nisi sit\nquos veniam quod sed accusamus veritatis error" 61 | }, 62 | { 63 | "userId": 2, 64 | "id": 11, 65 | "title": "et ea vero quia laudantium autem", 66 | "body": "delectus reiciendis molestiae occaecati non minima eveniet qui voluptatibus\naccusamus in eum beatae sit\nvel qui neque voluptates ut commodi qui incidunt\nut animi commodi" 67 | }, 68 | { 69 | "userId": 2, 70 | "id": 12, 71 | "title": "in quibusdam tempore odit est dolorem", 72 | "body": "itaque id aut magnam\npraesentium quia et ea odit et ea voluptas et\nsapiente quia nihil amet occaecati quia id voluptatem\nincidunt ea est distinctio odio" 73 | }, 74 | { 75 | "userId": 2, 76 | "id": 13, 77 | "title": "dolorum ut in voluptas mollitia et saepe quo animi", 78 | "body": "aut dicta possimus sint mollitia voluptas commodi quo doloremque\niste corrupti reiciendis voluptatem eius rerum\nsit cumque quod eligendi laborum minima\nperferendis recusandae assumenda consectetur porro architecto ipsum ipsam" 79 | }, 80 | { 81 | "userId": 2, 82 | "id": 14, 83 | "title": "voluptatem eligendi optio", 84 | "body": "fuga et accusamus dolorum perferendis illo voluptas\nnon doloremque neque facere\nad qui dolorum molestiae beatae\nsed aut voluptas totam sit illum" 85 | }, 86 | { 87 | "userId": 2, 88 | "id": 15, 89 | "title": "eveniet quod temporibus", 90 | "body": "reprehenderit quos placeat\nvelit minima officia dolores impedit repudiandae molestiae nam\nvoluptas recusandae quis delectus\nofficiis harum fugiat vitae" 91 | }, 92 | { 93 | "userId": 2, 94 | "id": 16, 95 | "title": "sint suscipit perspiciatis velit dolorum rerum ipsa laboriosam odio", 96 | "body": "suscipit nam nisi quo aperiam aut\nasperiores eos fugit maiores voluptatibus quia\nvoluptatem quis ullam qui in alias quia est\nconsequatur magni mollitia accusamus ea nisi voluptate dicta" 97 | }, 98 | { 99 | "userId": 2, 100 | "id": 17, 101 | "title": "fugit voluptas sed molestias voluptatem provident", 102 | "body": "eos voluptas et aut odit natus earum\naspernatur fuga molestiae ullam\ndeserunt ratione qui eos\nqui nihil ratione nemo velit ut aut id quo" 103 | }, 104 | { 105 | "userId": 2, 106 | "id": 18, 107 | "title": "voluptate et itaque vero tempora molestiae", 108 | "body": "eveniet quo quis\nlaborum totam consequatur non dolor\nut et est repudiandae\nest voluptatem vel debitis et magnam" 109 | }, 110 | { 111 | "userId": 2, 112 | "id": 19, 113 | "title": "adipisci placeat illum aut reiciendis qui", 114 | "body": "illum quis cupiditate provident sit magnam\nea sed aut omnis\nveniam maiores ullam consequatur atque\nadipisci quo iste expedita sit quos voluptas" 115 | }, 116 | { 117 | "userId": 2, 118 | "id": 20, 119 | "title": "doloribus ad provident suscipit at", 120 | "body": "qui consequuntur ducimus possimus quisquam amet similique\nsuscipit porro ipsam amet\neos veritatis officiis exercitationem vel fugit aut necessitatibus totam\nomnis rerum consequatur expedita quidem cumque explicabo" 121 | }, 122 | { 123 | "userId": 3, 124 | "id": 21, 125 | "title": "asperiores ea ipsam voluptatibus modi minima quia sint", 126 | "body": "repellat aliquid praesentium dolorem quo\nsed totam minus non itaque\nnihil labore molestiae sunt dolor eveniet hic recusandae veniam\ntempora et tenetur expedita sunt" 127 | }, 128 | { 129 | "userId": 3, 130 | "id": 22, 131 | "title": "dolor sint quo a velit explicabo quia nam", 132 | "body": "eos qui et ipsum ipsam suscipit aut\nsed omnis non odio\nexpedita earum mollitia molestiae aut atque rem suscipit\nnam impedit esse" 133 | }, 134 | { 135 | "userId": 3, 136 | "id": 23, 137 | "title": "maxime id vitae nihil numquam", 138 | "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" 139 | }, 140 | { 141 | "userId": 3, 142 | "id": 24, 143 | "title": "autem hic labore sunt dolores incidunt", 144 | "body": "enim et ex nulla\nomnis voluptas quia qui\nvoluptatem consequatur numquam aliquam sunt\ntotam recusandae id dignissimos aut sed asperiores deserunt" 145 | }, 146 | { 147 | "userId": 3, 148 | "id": 25, 149 | "title": "rem alias distinctio quo quis", 150 | "body": "ullam consequatur ut\nomnis quis sit vel consequuntur\nipsa eligendi ipsum molestiae et omnis error nostrum\nmolestiae illo tempore quia et distinctio" 151 | }, 152 | { 153 | "userId": 3, 154 | "id": 26, 155 | "title": "est et quae odit qui non", 156 | "body": "similique esse doloribus nihil accusamus\nomnis dolorem fuga consequuntur reprehenderit fugit recusandae temporibus\nperspiciatis cum ut laudantium\nomnis aut molestiae vel vero" 157 | }, 158 | { 159 | "userId": 3, 160 | "id": 27, 161 | "title": "quasi id et eos tenetur aut quo autem", 162 | "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" 163 | }, 164 | { 165 | "userId": 3, 166 | "id": 28, 167 | "title": "delectus ullam et corporis nulla voluptas sequi", 168 | "body": "non et quaerat ex quae ad maiores\nmaiores recusandae totam aut blanditiis mollitia quas illo\nut voluptatibus voluptatem\nsimilique nostrum eum" 169 | }, 170 | { 171 | "userId": 3, 172 | "id": 29, 173 | "title": "iusto eius quod necessitatibus culpa ea", 174 | "body": "odit magnam ut saepe sed non qui\ntempora atque nihil\naccusamus illum doloribus illo dolor\neligendi repudiandae odit magni similique sed cum maiores" 175 | }, 176 | { 177 | "userId": 3, 178 | "id": 30, 179 | "title": "a quo magni similique perferendis", 180 | "body": "alias dolor cumque\nimpedit blanditiis non eveniet odio maxime\nblanditiis amet eius quis tempora quia autem rem\na provident perspiciatis quia" 181 | }, 182 | { 183 | "userId": 4, 184 | "id": 31, 185 | "title": "ullam ut quidem id aut vel consequuntur", 186 | "body": "debitis eius sed quibusdam non quis consectetur vitae\nimpedit ut qui consequatur sed aut in\nquidem sit nostrum et maiores adipisci atque\nquaerat voluptatem adipisci repudiandae" 187 | }, 188 | { 189 | "userId": 4, 190 | "id": 32, 191 | "title": "doloremque illum aliquid sunt", 192 | "body": "deserunt eos nobis asperiores et hic\nest debitis repellat molestiae optio\nnihil ratione ut eos beatae quibusdam distinctio maiores\nearum voluptates et aut adipisci ea maiores voluptas maxime" 193 | }, 194 | { 195 | "userId": 4, 196 | "id": 33, 197 | "title": "qui explicabo molestiae dolorem", 198 | "body": "rerum ut et numquam laborum odit est sit\nid qui sint in\nquasi tenetur tempore aperiam et quaerat qui in\nrerum officiis sequi cumque quod" 199 | }, 200 | { 201 | "userId": 4, 202 | "id": 34, 203 | "title": "magnam ut rerum iure", 204 | "body": "ea velit perferendis earum ut voluptatem voluptate itaque iusto\ntotam pariatur in\nnemo voluptatem voluptatem autem magni tempora minima in\nest distinctio qui assumenda accusamus dignissimos officia nesciunt nobis" 205 | }, 206 | { 207 | "userId": 4, 208 | "id": 35, 209 | "title": "id nihil consequatur molestias animi provident", 210 | "body": "nisi error delectus possimus ut eligendi vitae\nplaceat eos harum cupiditate facilis reprehenderit voluptatem beatae\nmodi ducimus quo illum voluptas eligendi\net nobis quia fugit" 211 | }, 212 | { 213 | "userId": 4, 214 | "id": 36, 215 | "title": "fuga nam accusamus voluptas reiciendis itaque", 216 | "body": "ad mollitia et omnis minus architecto odit\nvoluptas doloremque maxime aut non ipsa qui alias veniam\nblanditiis culpa aut quia nihil cumque facere et occaecati\nqui aspernatur quia eaque ut aperiam inventore" 217 | }, 218 | { 219 | "userId": 4, 220 | "id": 37, 221 | "title": "provident vel ut sit ratione est", 222 | "body": "debitis et eaque non officia sed nesciunt pariatur vel\nvoluptatem iste vero et ea\nnumquam aut expedita ipsum nulla in\nvoluptates omnis consequatur aut enim officiis in quam qui" 223 | }, 224 | { 225 | "userId": 4, 226 | "id": 38, 227 | "title": "explicabo et eos deleniti nostrum ab id repellendus", 228 | "body": "animi esse sit aut sit nesciunt assumenda eum voluptas\nquia voluptatibus provident quia necessitatibus ea\nrerum repudiandae quia voluptatem delectus fugit aut id quia\nratione optio eos iusto veniam iure" 229 | }, 230 | { 231 | "userId": 4, 232 | "id": 39, 233 | "title": "eos dolorem iste accusantium est eaque quam", 234 | "body": "corporis rerum ducimus vel eum accusantium\nmaxime aspernatur a porro possimus iste omnis\nest in deleniti asperiores fuga aut\nvoluptas sapiente vel dolore minus voluptatem incidunt ex" 235 | }, 236 | { 237 | "userId": 4, 238 | "id": 40, 239 | "title": "enim quo cumque", 240 | "body": "ut voluptatum aliquid illo tenetur nemo sequi quo facilis\nipsum rem optio mollitia quas\nvoluptatem eum voluptas qui\nunde omnis voluptatem iure quasi maxime voluptas nam" 241 | }, 242 | { 243 | "userId": 5, 244 | "id": 41, 245 | "title": "non est facere", 246 | "body": "molestias id nostrum\nexcepturi molestiae dolore omnis repellendus quaerat saepe\nconsectetur iste quaerat tenetur asperiores accusamus ex ut\nnam quidem est ducimus sunt debitis saepe" 247 | }, 248 | { 249 | "userId": 5, 250 | "id": 42, 251 | "title": "commodi ullam sint et excepturi error explicabo praesentium voluptas", 252 | "body": "odio fugit voluptatum ducimus earum autem est incidunt voluptatem\nodit reiciendis aliquam sunt sequi nulla dolorem\nnon facere repellendus voluptates quia\nratione harum vitae ut" 253 | }, 254 | { 255 | "userId": 5, 256 | "id": 43, 257 | "title": "eligendi iste nostrum consequuntur adipisci praesentium sit beatae perferendis", 258 | "body": "similique fugit est\nillum et dolorum harum et voluptate eaque quidem\nexercitationem quos nam commodi possimus cum odio nihil nulla\ndolorum exercitationem magnam ex et a et distinctio debitis" 259 | }, 260 | { 261 | "userId": 5, 262 | "id": 44, 263 | "title": "optio dolor molestias sit", 264 | "body": "temporibus est consectetur dolore\net libero debitis vel velit laboriosam quia\nipsum quibusdam qui itaque fuga rem aut\nea et iure quam sed maxime ut distinctio quae" 265 | }, 266 | { 267 | "userId": 5, 268 | "id": 45, 269 | "title": "ut numquam possimus omnis eius suscipit laudantium iure", 270 | "body": "est natus reiciendis nihil possimus aut provident\nex et dolor\nrepellat pariatur est\nnobis rerum repellendus dolorem autem" 271 | }, 272 | { 273 | "userId": 5, 274 | "id": 46, 275 | "title": "aut quo modi neque nostrum ducimus", 276 | "body": "voluptatem quisquam iste\nvoluptatibus natus officiis facilis dolorem\nquis quas ipsam\nvel et voluptatum in aliquid" 277 | }, 278 | { 279 | "userId": 5, 280 | "id": 47, 281 | "title": "quibusdam cumque rem aut deserunt", 282 | "body": "voluptatem assumenda ut qui ut cupiditate aut impedit veniam\noccaecati nemo illum voluptatem laudantium\nmolestiae beatae rerum ea iure soluta nostrum\neligendi et voluptate" 283 | }, 284 | { 285 | "userId": 5, 286 | "id": 48, 287 | "title": "ut voluptatem illum ea doloribus itaque eos", 288 | "body": "voluptates quo voluptatem facilis iure occaecati\nvel assumenda rerum officia et\nillum perspiciatis ab deleniti\nlaudantium repellat ad ut et autem reprehenderit" 289 | }, 290 | { 291 | "userId": 5, 292 | "id": 49, 293 | "title": "laborum non sunt aut ut assumenda perspiciatis voluptas", 294 | "body": "inventore ab sint\nnatus fugit id nulla sequi architecto nihil quaerat\neos tenetur in in eum veritatis non\nquibusdam officiis aspernatur cumque aut commodi aut" 295 | }, 296 | { 297 | "userId": 5, 298 | "id": 50, 299 | "title": "repellendus qui recusandae incidunt voluptates tenetur qui omnis exercitationem", 300 | "body": "error suscipit maxime adipisci consequuntur recusandae\nvoluptas eligendi et est et voluptates\nquia distinctio ab amet quaerat molestiae et vitae\nadipisci impedit sequi nesciunt quis consectetur" 301 | }, 302 | { 303 | "userId": 6, 304 | "id": 51, 305 | "title": "soluta aliquam aperiam consequatur illo quis voluptas", 306 | "body": "sunt dolores aut doloribus\ndolore doloribus voluptates tempora et\ndoloremque et quo\ncum asperiores sit consectetur dolorem" 307 | }, 308 | { 309 | "userId": 6, 310 | "id": 52, 311 | "title": "qui enim et consequuntur quia animi quis voluptate quibusdam", 312 | "body": "iusto est quibusdam fuga quas quaerat molestias\na enim ut sit accusamus enim\ntemporibus iusto accusantium provident architecto\nsoluta esse reprehenderit qui laborum" 313 | }, 314 | { 315 | "userId": 6, 316 | "id": 53, 317 | "title": "ut quo aut ducimus alias", 318 | "body": "minima harum praesentium eum rerum illo dolore\nquasi exercitationem rerum nam\nporro quis neque quo\nconsequatur minus dolor quidem veritatis sunt non explicabo similique" 319 | }, 320 | { 321 | "userId": 6, 322 | "id": 54, 323 | "title": "sit asperiores ipsam eveniet odio non quia", 324 | "body": "totam corporis dignissimos\nvitae dolorem ut occaecati accusamus\nex velit deserunt\net exercitationem vero incidunt corrupti mollitia" 325 | }, 326 | { 327 | "userId": 6, 328 | "id": 55, 329 | "title": "sit vel voluptatem et non libero", 330 | "body": "debitis excepturi ea perferendis harum libero optio\neos accusamus cum fuga ut sapiente repudiandae\net ut incidunt omnis molestiae\nnihil ut eum odit" 331 | }, 332 | { 333 | "userId": 6, 334 | "id": 56, 335 | "title": "qui et at rerum necessitatibus", 336 | "body": "aut est omnis dolores\nneque rerum quod ea rerum velit pariatur beatae excepturi\net provident voluptas corrupti\ncorporis harum reprehenderit dolores eligendi" 337 | }, 338 | { 339 | "userId": 6, 340 | "id": 57, 341 | "title": "sed ab est est", 342 | "body": "at pariatur consequuntur earum quidem\nquo est laudantium soluta voluptatem\nqui ullam et est\net cum voluptas voluptatum repellat est" 343 | }, 344 | { 345 | "userId": 6, 346 | "id": 58, 347 | "title": "voluptatum itaque dolores nisi et quasi", 348 | "body": "veniam voluptatum quae adipisci id\net id quia eos ad et dolorem\naliquam quo nisi sunt eos impedit error\nad similique veniam" 349 | }, 350 | { 351 | "userId": 6, 352 | "id": 59, 353 | "title": "qui commodi dolor at maiores et quis id accusantium", 354 | "body": "perspiciatis et quam ea autem temporibus non voluptatibus qui\nbeatae a earum officia nesciunt dolores suscipit voluptas et\nanimi doloribus cum rerum quas et magni\net hic ut ut commodi expedita sunt" 355 | }, 356 | { 357 | "userId": 6, 358 | "id": 60, 359 | "title": "consequatur placeat omnis quisquam quia reprehenderit fugit veritatis facere", 360 | "body": "asperiores sunt ab assumenda cumque modi velit\nqui esse omnis\nvoluptate et fuga perferendis voluptas\nillo ratione amet aut et omnis" 361 | }, 362 | { 363 | "userId": 7, 364 | "id": 61, 365 | "title": "voluptatem doloribus consectetur est ut ducimus", 366 | "body": "ab nemo optio odio\ndelectus tenetur corporis similique nobis repellendus rerum omnis facilis\nvero blanditiis debitis in nesciunt doloribus dicta dolores\nmagnam minus velit" 367 | }, 368 | { 369 | "userId": 7, 370 | "id": 62, 371 | "title": "beatae enim quia vel", 372 | "body": "enim aspernatur illo distinctio quae praesentium\nbeatae alias amet delectus qui voluptate distinctio\nodit sint accusantium autem omnis\nquo molestiae omnis ea eveniet optio" 373 | }, 374 | { 375 | "userId": 7, 376 | "id": 63, 377 | "title": "voluptas blanditiis repellendus animi ducimus error sapiente et suscipit", 378 | "body": "enim adipisci aspernatur nemo\nnumquam omnis facere dolorem dolor ex quis temporibus incidunt\nab delectus culpa quo reprehenderit blanditiis asperiores\naccusantium ut quam in voluptatibus voluptas ipsam dicta" 379 | }, 380 | { 381 | "userId": 7, 382 | "id": 64, 383 | "title": "et fugit quas eum in in aperiam quod", 384 | "body": "id velit blanditiis\neum ea voluptatem\nmolestiae sint occaecati est eos perspiciatis\nincidunt a error provident eaque aut aut qui" 385 | }, 386 | { 387 | "userId": 7, 388 | "id": 65, 389 | "title": "consequatur id enim sunt et et", 390 | "body": "voluptatibus ex esse\nsint explicabo est aliquid cumque adipisci fuga repellat labore\nmolestiae corrupti ex saepe at asperiores et perferendis\nnatus id esse incidunt pariatur" 391 | }, 392 | { 393 | "userId": 7, 394 | "id": 66, 395 | "title": "repudiandae ea animi iusto", 396 | "body": "officia veritatis tenetur vero qui itaque\nsint non ratione\nsed et ut asperiores iusto eos molestiae nostrum\nveritatis quibusdam et nemo iusto saepe" 397 | }, 398 | { 399 | "userId": 7, 400 | "id": 67, 401 | "title": "aliquid eos sed fuga est maxime repellendus", 402 | "body": "reprehenderit id nostrum\nvoluptas doloremque pariatur sint et accusantium quia quod aspernatur\net fugiat amet\nnon sapiente et consequatur necessitatibus molestiae" 403 | }, 404 | { 405 | "userId": 7, 406 | "id": 68, 407 | "title": "odio quis facere architecto reiciendis optio", 408 | "body": "magnam molestiae perferendis quisquam\nqui cum reiciendis\nquaerat animi amet hic inventore\nea quia deleniti quidem saepe porro velit" 409 | }, 410 | { 411 | "userId": 7, 412 | "id": 69, 413 | "title": "fugiat quod pariatur odit minima", 414 | "body": "officiis error culpa consequatur modi asperiores et\ndolorum assumenda voluptas et vel qui aut vel rerum\nvoluptatum quisquam perspiciatis quia rerum consequatur totam quas\nsequi commodi repudiandae asperiores et saepe a" 415 | }, 416 | { 417 | "userId": 7, 418 | "id": 70, 419 | "title": "voluptatem laborum magni", 420 | "body": "sunt repellendus quae\nest asperiores aut deleniti esse accusamus repellendus quia aut\nquia dolorem unde\neum tempora esse dolore" 421 | }, 422 | { 423 | "userId": 8, 424 | "id": 71, 425 | "title": "et iusto veniam et illum aut fuga", 426 | "body": "occaecati a doloribus\niste saepe consectetur placeat eum voluptate dolorem et\nqui quo quia voluptas\nrerum ut id enim velit est perferendis" 427 | }, 428 | { 429 | "userId": 8, 430 | "id": 72, 431 | "title": "sint hic doloribus consequatur eos non id", 432 | "body": "quam occaecati qui deleniti consectetur\nconsequatur aut facere quas exercitationem aliquam hic voluptas\nneque id sunt ut aut accusamus\nsunt consectetur expedita inventore velit" 433 | }, 434 | { 435 | "userId": 8, 436 | "id": 73, 437 | "title": "consequuntur deleniti eos quia temporibus ab aliquid at", 438 | "body": "voluptatem cumque tenetur consequatur expedita ipsum nemo quia explicabo\naut eum minima consequatur\ntempore cumque quae est et\net in consequuntur voluptatem voluptates aut" 439 | }, 440 | { 441 | "userId": 8, 442 | "id": 74, 443 | "title": "enim unde ratione doloribus quas enim ut sit sapiente", 444 | "body": "odit qui et et necessitatibus sint veniam\nmollitia amet doloremque molestiae commodi similique magnam et quam\nblanditiis est itaque\nquo et tenetur ratione occaecati molestiae tempora" 445 | }, 446 | { 447 | "userId": 8, 448 | "id": 75, 449 | "title": "dignissimos eum dolor ut enim et delectus in", 450 | "body": "commodi non non omnis et voluptas sit\nautem aut nobis magnam et sapiente voluptatem\net laborum repellat qui delectus facilis temporibus\nrerum amet et nemo voluptate expedita adipisci error dolorem" 451 | }, 452 | { 453 | "userId": 8, 454 | "id": 76, 455 | "title": "doloremque officiis ad et non perferendis", 456 | "body": "ut animi facere\ntotam iusto tempore\nmolestiae eum aut et dolorem aperiam\nquaerat recusandae totam odio" 457 | }, 458 | { 459 | "userId": 8, 460 | "id": 77, 461 | "title": "necessitatibus quasi exercitationem odio", 462 | "body": "modi ut in nulla repudiandae dolorum nostrum eos\naut consequatur omnis\nut incidunt est omnis iste et quam\nvoluptates sapiente aliquam asperiores nobis amet corrupti repudiandae provident" 463 | }, 464 | { 465 | "userId": 8, 466 | "id": 78, 467 | "title": "quam voluptatibus rerum veritatis", 468 | "body": "nobis facilis odit tempore cupiditate quia\nassumenda doloribus rerum qui ea\nillum et qui totam\naut veniam repellendus" 469 | }, 470 | { 471 | "userId": 8, 472 | "id": 79, 473 | "title": "pariatur consequatur quia magnam autem omnis non amet", 474 | "body": "libero accusantium et et facere incidunt sit dolorem\nnon excepturi qui quia sed laudantium\nquisquam molestiae ducimus est\nofficiis esse molestiae iste et quos" 475 | }, 476 | { 477 | "userId": 8, 478 | "id": 80, 479 | "title": "labore in ex et explicabo corporis aut quas", 480 | "body": "ex quod dolorem ea eum iure qui provident amet\nquia qui facere excepturi et repudiandae\nasperiores molestias provident\nminus incidunt vero fugit rerum sint sunt excepturi provident" 481 | }, 482 | { 483 | "userId": 9, 484 | "id": 81, 485 | "title": "tempora rem veritatis voluptas quo dolores vero", 486 | "body": "facere qui nesciunt est voluptatum voluptatem nisi\nsequi eligendi necessitatibus ea at rerum itaque\nharum non ratione velit laboriosam quis consequuntur\nex officiis minima doloremque voluptas ut aut" 487 | }, 488 | { 489 | "userId": 9, 490 | "id": 82, 491 | "title": "laudantium voluptate suscipit sunt enim enim", 492 | "body": "ut libero sit aut totam inventore sunt\nporro sint qui sunt molestiae\nconsequatur cupiditate qui iste ducimus adipisci\ndolor enim assumenda soluta laboriosam amet iste delectus hic" 493 | }, 494 | { 495 | "userId": 9, 496 | "id": 83, 497 | "title": "odit et voluptates doloribus alias odio et", 498 | "body": "est molestiae facilis quis tempora numquam nihil qui\nvoluptate sapiente consequatur est qui\nnecessitatibus autem aut ipsa aperiam modi dolore numquam\nreprehenderit eius rem quibusdam" 499 | }, 500 | { 501 | "userId": 9, 502 | "id": 84, 503 | "title": "optio ipsam molestias necessitatibus occaecati facilis veritatis dolores aut", 504 | "body": "sint molestiae magni a et quos\neaque et quasi\nut rerum debitis similique veniam\nrecusandae dignissimos dolor incidunt consequatur odio" 505 | }, 506 | { 507 | "userId": 9, 508 | "id": 85, 509 | "title": "dolore veritatis porro provident adipisci blanditiis et sunt", 510 | "body": "similique sed nisi voluptas iusto omnis\nmollitia et quo\nassumenda suscipit officia magnam sint sed tempora\nenim provident pariatur praesentium atque animi amet ratione" 511 | }, 512 | { 513 | "userId": 9, 514 | "id": 86, 515 | "title": "placeat quia et porro iste", 516 | "body": "quasi excepturi consequatur iste autem temporibus sed molestiae beatae\net quaerat et esse ut\nvoluptatem occaecati et vel explicabo autem\nasperiores pariatur deserunt optio" 517 | }, 518 | { 519 | "userId": 9, 520 | "id": 87, 521 | "title": "nostrum quis quasi placeat", 522 | "body": "eos et molestiae\nnesciunt ut a\ndolores perspiciatis repellendus repellat aliquid\nmagnam sint rem ipsum est" 523 | }, 524 | { 525 | "userId": 9, 526 | "id": 88, 527 | "title": "sapiente omnis fugit eos", 528 | "body": "consequatur omnis est praesentium\nducimus non iste\nneque hic deserunt\nvoluptatibus veniam cum et rerum sed" 529 | }, 530 | { 531 | "userId": 9, 532 | "id": 89, 533 | "title": "sint soluta et vel magnam aut ut sed qui", 534 | "body": "repellat aut aperiam totam temporibus autem et\narchitecto magnam ut\nconsequatur qui cupiditate rerum quia soluta dignissimos nihil iure\ntempore quas est" 535 | }, 536 | { 537 | "userId": 9, 538 | "id": 90, 539 | "title": "ad iusto omnis odit dolor voluptatibus", 540 | "body": "minus omnis soluta quia\nqui sed adipisci voluptates illum ipsam voluptatem\neligendi officia ut in\neos soluta similique molestias praesentium blanditiis" 541 | }, 542 | { 543 | "userId": 10, 544 | "id": 91, 545 | "title": "aut amet sed", 546 | "body": "libero voluptate eveniet aperiam sed\nsunt placeat suscipit molestias\nsimilique fugit nam natus\nexpedita consequatur consequatur dolores quia eos et placeat" 547 | }, 548 | { 549 | "userId": 10, 550 | "id": 92, 551 | "title": "ratione ex tenetur perferendis", 552 | "body": "aut et excepturi dicta laudantium sint rerum nihil\nlaudantium et at\na neque minima officia et similique libero et\ncommodi voluptate qui" 553 | }, 554 | { 555 | "userId": 10, 556 | "id": 93, 557 | "title": "beatae soluta recusandae", 558 | "body": "dolorem quibusdam ducimus consequuntur dicta aut quo laboriosam\nvoluptatem quis enim recusandae ut sed sunt\nnostrum est odit totam\nsit error sed sunt eveniet provident qui nulla" 559 | }, 560 | { 561 | "userId": 10, 562 | "id": 94, 563 | "title": "qui qui voluptates illo iste minima", 564 | "body": "aspernatur expedita soluta quo ab ut similique\nexpedita dolores amet\nsed temporibus distinctio magnam saepe deleniti\nomnis facilis nam ipsum natus sint similique omnis" 565 | }, 566 | { 567 | "userId": 10, 568 | "id": 95, 569 | "title": "id minus libero illum nam ad officiis", 570 | "body": "earum voluptatem facere provident blanditiis velit laboriosam\npariatur accusamus odio saepe\ncumque dolor qui a dicta ab doloribus consequatur omnis\ncorporis cupiditate eaque assumenda ad nesciunt" 571 | }, 572 | { 573 | "userId": 10, 574 | "id": 96, 575 | "title": "quaerat velit veniam amet cupiditate aut numquam ut sequi", 576 | "body": "in non odio excepturi sint eum\nlabore voluptates vitae quia qui et\ninventore itaque rerum\nveniam non exercitationem delectus aut" 577 | }, 578 | { 579 | "userId": 10, 580 | "id": 97, 581 | "title": "quas fugiat ut perspiciatis vero provident", 582 | "body": "eum non blanditiis soluta porro quibusdam voluptas\nvel voluptatem qui placeat dolores qui velit aut\nvel inventore aut cumque culpa explicabo aliquid at\nperspiciatis est et voluptatem dignissimos dolor itaque sit nam" 583 | }, 584 | { 585 | "userId": 10, 586 | "id": 98, 587 | "title": "laboriosam dolor voluptates", 588 | "body": "doloremque ex facilis sit sint culpa\nsoluta assumenda eligendi non ut eius\nsequi ducimus vel quasi\nveritatis est dolores" 589 | }, 590 | { 591 | "userId": 10, 592 | "id": 99, 593 | "title": "temporibus sit alias delectus eligendi possimus magni", 594 | "body": "quo deleniti praesentium dicta non quod\naut est molestias\nmolestias et officia quis nihil\nitaque dolorem quia" 595 | }, 596 | { 597 | "userId": 10, 598 | "id": 100, 599 | "title": "at nam consequatur ea labore ea harum", 600 | "body": "cupiditate quo est a modi nesciunt soluta\nipsa voluptas error itaque dicta in\nautem qui minus magnam et distinctio eum\naccusamus ratione error aut" 601 | } 602 | ] -------------------------------------------------------------------------------- /data/users.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "name": "Leanne Graham", 5 | "username": "Bret", 6 | "email": "Sincere@april.biz", 7 | "address": { 8 | "street": "Kulas Light", 9 | "suite": "Apt. 556", 10 | "city": "Gwenborough", 11 | "zipcode": "92998-3874", 12 | "geo": { 13 | "lat": "-37.3159", 14 | "lng": "81.1496" 15 | } 16 | }, 17 | "phone": "1-770-736-8031 x56442", 18 | "website": "hildegard.org", 19 | "company": { 20 | "name": "Romaguera-Crona", 21 | "catchPhrase": "Multi-layered client-server neural-net", 22 | "bs": "harness real-time e-markets" 23 | } 24 | }, 25 | { 26 | "id": 2, 27 | "name": "Ervin Howell", 28 | "username": "Antonette", 29 | "email": "Shanna@melissa.tv", 30 | "address": { 31 | "street": "Victor Plains", 32 | "suite": "Suite 879", 33 | "city": "Wisokyburgh", 34 | "zipcode": "90566-7771", 35 | "geo": { 36 | "lat": "-43.9509", 37 | "lng": "-34.4618" 38 | } 39 | }, 40 | "phone": "010-692-6593 x09125", 41 | "website": "anastasia.net", 42 | "company": { 43 | "name": "Deckow-Crist", 44 | "catchPhrase": "Proactive didactic contingency", 45 | "bs": "synergize scalable supply-chains" 46 | } 47 | }, 48 | { 49 | "id": 3, 50 | "name": "Clementine Bauch", 51 | "username": "Samantha", 52 | "email": "Nathan@yesenia.net", 53 | "address": { 54 | "street": "Douglas Extension", 55 | "suite": "Suite 847", 56 | "city": "McKenziehaven", 57 | "zipcode": "59590-4157", 58 | "geo": { 59 | "lat": "-68.6102", 60 | "lng": "-47.0653" 61 | } 62 | }, 63 | "phone": "1-463-123-4447", 64 | "website": "ramiro.info", 65 | "company": { 66 | "name": "Romaguera-Jacobson", 67 | "catchPhrase": "Face to face bifurcated interface", 68 | "bs": "e-enable strategic applications" 69 | } 70 | }, 71 | { 72 | "id": 4, 73 | "name": "Patricia Lebsack", 74 | "username": "Karianne", 75 | "email": "Julianne.OConner@kory.org", 76 | "address": { 77 | "street": "Hoeger Mall", 78 | "suite": "Apt. 692", 79 | "city": "South Elvis", 80 | "zipcode": "53919-4257", 81 | "geo": { 82 | "lat": "29.4572", 83 | "lng": "-164.2990" 84 | } 85 | }, 86 | "phone": "493-170-9623 x156", 87 | "website": "kale.biz", 88 | "company": { 89 | "name": "Robel-Corkery", 90 | "catchPhrase": "Multi-tiered zero tolerance productivity", 91 | "bs": "transition cutting-edge web services" 92 | } 93 | }, 94 | { 95 | "id": 5, 96 | "name": "Chelsey Dietrich", 97 | "username": "Kamren", 98 | "email": "Lucio_Hettinger@annie.ca", 99 | "address": { 100 | "street": "Skiles Walks", 101 | "suite": "Suite 351", 102 | "city": "Roscoeview", 103 | "zipcode": "33263", 104 | "geo": { 105 | "lat": "-31.8129", 106 | "lng": "62.5342" 107 | } 108 | }, 109 | "phone": "(254)954-1289", 110 | "website": "demarco.info", 111 | "company": { 112 | "name": "Keebler LLC", 113 | "catchPhrase": "User-centric fault-tolerant solution", 114 | "bs": "revolutionize end-to-end systems" 115 | } 116 | }, 117 | { 118 | "id": 6, 119 | "name": "Mrs. Dennis Schulist", 120 | "username": "Leopoldo_Corkery", 121 | "email": "Karley_Dach@jasper.info", 122 | "address": { 123 | "street": "Norberto Crossing", 124 | "suite": "Apt. 950", 125 | "city": "South Christy", 126 | "zipcode": "23505-1337", 127 | "geo": { 128 | "lat": "-71.4197", 129 | "lng": "71.7478" 130 | } 131 | }, 132 | "phone": "1-477-935-8478 x6430", 133 | "website": "ola.org", 134 | "company": { 135 | "name": "Considine-Lockman", 136 | "catchPhrase": "Synchronised bottom-line interface", 137 | "bs": "e-enable innovative applications" 138 | } 139 | }, 140 | { 141 | "id": 7, 142 | "name": "Kurtis Weissnat", 143 | "username": "Elwyn.Skiles", 144 | "email": "Telly.Hoeger@billy.biz", 145 | "address": { 146 | "street": "Rex Trail", 147 | "suite": "Suite 280", 148 | "city": "Howemouth", 149 | "zipcode": "58804-1099", 150 | "geo": { 151 | "lat": "24.8918", 152 | "lng": "21.8984" 153 | } 154 | }, 155 | "phone": "210.067.6132", 156 | "website": "elvis.io", 157 | "company": { 158 | "name": "Johns Group", 159 | "catchPhrase": "Configurable multimedia task-force", 160 | "bs": "generate enterprise e-tailers" 161 | } 162 | }, 163 | { 164 | "id": 8, 165 | "name": "Nicholas Runolfsdottir V", 166 | "username": "Maxime_Nienow", 167 | "email": "Sherwood@rosamond.me", 168 | "address": { 169 | "street": "Ellsworth Summit", 170 | "suite": "Suite 729", 171 | "city": "Aliyaview", 172 | "zipcode": "45169", 173 | "geo": { 174 | "lat": "-14.3990", 175 | "lng": "-120.7677" 176 | } 177 | }, 178 | "phone": "586.493.6943 x140", 179 | "website": "jacynthe.com", 180 | "company": { 181 | "name": "Abernathy Group", 182 | "catchPhrase": "Implemented secondary concept", 183 | "bs": "e-enable extensible e-tailers" 184 | } 185 | }, 186 | { 187 | "id": 9, 188 | "name": "Glenna Reichert", 189 | "username": "Delphine", 190 | "email": "Chaim_McDermott@dana.io", 191 | "address": { 192 | "street": "Dayna Park", 193 | "suite": "Suite 449", 194 | "city": "Bartholomebury", 195 | "zipcode": "76495-3109", 196 | "geo": { 197 | "lat": "24.6463", 198 | "lng": "-168.8889" 199 | } 200 | }, 201 | "phone": "(775)976-6794 x41206", 202 | "website": "conrad.com", 203 | "company": { 204 | "name": "Yost and Sons", 205 | "catchPhrase": "Switchable contextually-based project", 206 | "bs": "aggregate real-time technologies" 207 | } 208 | }, 209 | { 210 | "id": 10, 211 | "name": "Clementina DuBuque", 212 | "username": "Moriah.Stanton", 213 | "email": "Rey.Padberg@karina.biz", 214 | "address": { 215 | "street": "Kattie Turnpike", 216 | "suite": "Suite 198", 217 | "city": "Lebsackbury", 218 | "zipcode": "31428-2261", 219 | "geo": { 220 | "lat": "-38.2386", 221 | "lng": "57.2232" 222 | } 223 | }, 224 | "phone": "024-648-3804", 225 | "website": "ambrose.net", 226 | "company": { 227 | "name": "Hoeger LLC", 228 | "catchPhrase": "Centralized empowering task-force", 229 | "bs": "target end-to-end models" 230 | } 231 | } 232 | ] -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 12 | 13 | 16 | 17 | Blog 18 | 19 | 20 | 21 | 26 |
27 |

Feel free to share your opinions

28 | 31 | 32 | 56 |
57 | 82 | 105 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blog-with-api", 3 | "version": "1.0.0", 4 | "description": "`#html` `#css` `#js` `#dom` `#JSON` `#HTTP` `#API` `#Bootstrap` `#master-in-software-development`", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "server": "json-server --watch ./data/db.json" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/alejandroaperez1994g/blog-with-api.git" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "bugs": { 18 | "url": "https://github.com/alejandroaperez1994g/blog-with-api/issues" 19 | }, 20 | "homepage": "https://github.com/alejandroaperez1994g/blog-with-api#readme", 21 | "dependencies": { 22 | "json-server": "0.17.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/assets/Aablog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alejandroaperez1994g/blog-with-api/742b1d21b4645087b9ddea4cec3cef6049a417e1/src/assets/Aablog.jpg -------------------------------------------------------------------------------- /src/assets/bloglogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alejandroaperez1994g/blog-with-api/742b1d21b4645087b9ddea4cec3cef6049a417e1/src/assets/bloglogo.png -------------------------------------------------------------------------------- /src/assets/icon/blog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alejandroaperez1994g/blog-with-api/742b1d21b4645087b9ddea4cec3cef6049a417e1/src/assets/icon/blog.png -------------------------------------------------------------------------------- /src/assets/images/demo-mobile.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alejandroaperez1994g/blog-with-api/742b1d21b4645087b9ddea4cec3cef6049a417e1/src/assets/images/demo-mobile.gif -------------------------------------------------------------------------------- /src/assets/images/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alejandroaperez1994g/blog-with-api/742b1d21b4645087b9ddea4cec3cef6049a417e1/src/assets/images/demo.gif -------------------------------------------------------------------------------- /src/js/api.js: -------------------------------------------------------------------------------- 1 | import { updatePosts } from "./main.js"; 2 | 3 | const fetchPosts = async () => { 4 | return await fetch("http://localhost:3000/posts") 5 | .then((response) => response.json()) 6 | .then((data) => data) 7 | .catch((e) => console.error(e)); 8 | }; 9 | 10 | const fetchUser = async (userId) => { 11 | return await fetch(`http://localhost:3000/users?id=${userId}`) 12 | .then((response) => response.json()) 13 | .then((data) => data) 14 | .catch((e) => console.error(e)); 15 | }; 16 | 17 | const fetchComments = async (postId) => { 18 | return await fetch(`http://localhost:3000/comments?postId=${postId}`) 19 | .then((response) => response.json()) 20 | .then((data) => data) 21 | .catch((e) => console.error(e)); 22 | }; 23 | const modifyPost = async (postId, postTitle, postBody) => { 24 | return await fetch(`http://localhost:3000/posts/${postId}`, { 25 | method: "PATCH", 26 | headers: { 27 | "Content-Type": "application/json", 28 | }, 29 | body: JSON.stringify({ title: postTitle, body: postBody }), 30 | }) 31 | .then((response) => 32 | response.json().then((data) => { 33 | updatePosts(); 34 | }) 35 | ) 36 | .catch((e) => console.error(e)); 37 | }; 38 | 39 | const deletePost = async (postId) => { 40 | fetch(`http://localhost:3000/posts/${postId}`, { 41 | method: "DELETE", 42 | headers: { 43 | "Content-Type": "application/json", 44 | }, 45 | }) 46 | .then((response) => 47 | response.json().then((data) => { 48 | updatePosts(); 49 | }) 50 | ) 51 | .catch((e) => console.error(e)); 52 | }; 53 | 54 | export { fetchPosts, fetchUser, fetchComments, modifyPost, deletePost }; 55 | -------------------------------------------------------------------------------- /src/js/main.js: -------------------------------------------------------------------------------- 1 | import { 2 | fetchPosts, 3 | fetchUser, 4 | fetchComments, 5 | modifyPost, 6 | deletePost, 7 | } from "./api.js"; 8 | import { 9 | createPost, 10 | addPaginators, 11 | updatePostsDisplay, 12 | updateDisplay, 13 | startNumberPagination, 14 | endNumberPagination, 15 | } from "./utils.js"; 16 | 17 | const postList = document.getElementById("postList"); 18 | const btnComments = document.getElementById("btnComents"); 19 | const commentsUl = document.getElementById("modal__comments"); 20 | const saveBtn = document.getElementById("saveBtn"); 21 | const modifyTitle = document.getElementById("modifyTitle"); 22 | const modifyBody = document.getElementById("modifyBody"); 23 | const deleteBtn = document.getElementById("deleteButton"); 24 | 25 | const getPosts = (startNumber, endNumber) => { 26 | fetchPosts().then((data) => { 27 | data.forEach((post, index) => { 28 | if (index >= startNumber && index < endNumber) { 29 | const liElement = createPost( 30 | post.userId, 31 | post.id, 32 | post.title, 33 | post.body, 34 | index 35 | ); 36 | 37 | postList.append(liElement); 38 | } 39 | }); 40 | addMultiEvents(); 41 | }); 42 | }; 43 | 44 | function addMultiEvents() { 45 | const modalTitle = document.getElementById("modalTitle"); 46 | const modalBody = document.getElementById("modal__post_body"); 47 | const userName = document.getElementById("user_name"); 48 | const userEmail = document.getElementById("user_email"); 49 | 50 | Array.from(postList.children).map((post) => { 51 | const title = post.querySelector("h3"); 52 | const modifyBtn = post.querySelector("[data-modify]"); 53 | const body = title.nextElementSibling; 54 | modifyBtn.addEventListener("click", (e) => { 55 | let id = e.target.getAttribute("data-id"); 56 | modifyTitle.value = title.textContent; 57 | modifyBody.value = body.textContent; 58 | modifyTitle.setAttribute("data-id", id); 59 | }); 60 | 61 | const deleteButton = post.querySelector("[data-delete]"); 62 | deleteButton.addEventListener("click", (e) => { 63 | const dataId = e.target.getAttribute("data-id"); 64 | deleteBtn.setAttribute("data-id", dataId); 65 | }); 66 | 67 | title.addEventListener("click", (e) => { 68 | if (btnComments.classList.value.includes("hide")) { 69 | btnComments.classList.remove("hide"); 70 | commentsUl.classList.add("hide"); 71 | } 72 | 73 | let user = fetchUser(e.target.getAttribute("data-userId")); 74 | user.then((data) => { 75 | userName.textContent = data[0].username; 76 | userEmail.textContent = data[0].email.toLowerCase(); 77 | }); 78 | btnComments.setAttribute( 79 | "data-postId", 80 | `${e.target.getAttribute("data-id")}` 81 | ); 82 | modalTitle.textContent = e.target.textContent; 83 | modalBody.textContent = e.target.nextSibling.textContent; 84 | }); 85 | }); 86 | } 87 | 88 | const updatePosts = () => { 89 | updatePostsDisplay(); 90 | getPosts(startNumberPagination, endNumberPagination); 91 | }; 92 | 93 | saveBtn.addEventListener("click", (e) => { 94 | e.preventDefault(); 95 | 96 | const title = document.getElementById("modifyTitle"); 97 | const body = document.getElementById("modifyBody"); 98 | const id = title.getAttribute("data-id"); 99 | modifyPost(id, title.value, body.value); 100 | }); 101 | 102 | btnComments.addEventListener("click", (e) => { 103 | commentsUl.classList.toggle("hide"); 104 | btnComments.classList.toggle("hide"); 105 | let postId = e.target.getAttribute("data-postId"); 106 | fetchComments(postId).then((data) => { 107 | updateDisplay(); 108 | data.forEach((dataComment) => { 109 | const commentsLi = document.createElement("li"); 110 | const commentsTitle = document.createElement("p"); 111 | const commentsBody = document.createElement("p"); 112 | const commentsUser = document.createElement("p"); 113 | commentsTitle.textContent = `Title: ${dataComment.name}`; 114 | commentsBody.textContent = `Comment: ${dataComment.body}`; 115 | commentsUser.textContent = `e.mail: ${dataComment.email}`; 116 | commentsLi.append(commentsTitle, commentsBody, commentsUser); 117 | commentsUl.appendChild(commentsLi); 118 | commentsUl.classList.add("comments__ul"); 119 | commentsUl.setAttribute("data-bs-spy", "scroll"); 120 | commentsUl.setAttribute("data-target", ".navbar"); 121 | commentsUl.setAttribute("data-offset", "'50'"); 122 | commentsLi.classList.add("comments__li"); 123 | commentsTitle.classList.add("comments__title"); 124 | commentsUser.classList.add("comments_user"); 125 | // commentsTitle, 126 | }); 127 | }); 128 | }); 129 | deleteBtn.addEventListener("click", (e) => { 130 | const dataId = e.target.getAttribute("data-id"); 131 | console.log(dataId); 132 | deletePost(dataId); 133 | updatePostsDisplay(); 134 | getPosts(startNumberPagination, endNumberPagination); 135 | }); 136 | 137 | getPosts(0, 10); 138 | addPaginators(); 139 | 140 | export { getPosts, postList, commentsUl, updatePosts }; 141 | -------------------------------------------------------------------------------- /src/js/utils.js: -------------------------------------------------------------------------------- 1 | import { getPosts, postList, commentsUl } from "./main.js"; 2 | const paginatorNumbers = document.querySelectorAll("[data-type]"); 3 | const previousPage = document.getElementById("previous-page"); 4 | const nextPage = document.getElementById("next-page"); 5 | let startNumberPagination = 0; 6 | let endNumberPagination = 10; 7 | 8 | previousPage.addEventListener("click", (e) => { 9 | e.preventDefault(); 10 | if (startNumberPagination < 10) return; 11 | startNumberPagination -= 10; 12 | endNumberPagination -= 10; 13 | updatePostsDisplay(); 14 | getPosts(startNumberPagination, endNumberPagination); 15 | }); 16 | 17 | nextPage.addEventListener("click", (e) => { 18 | e.preventDefault(); 19 | if (endNumberPagination > 90) return; 20 | startNumberPagination += 10; 21 | endNumberPagination += 10; 22 | updatePostsDisplay(); 23 | getPosts(startNumberPagination, endNumberPagination); 24 | }); 25 | 26 | const createPost = (userId, id, title, body, index) => { 27 | const liElement = document.createElement("li"); 28 | liElement.classList.add("article__post"); 29 | const avatarImg = document.createElement("img"); 30 | avatarImg.classList.add("img__avatar"); 31 | const postContainer = document.createElement("div"); 32 | postContainer.classList.add("post__container"); 33 | const postTitle = document.createElement("h3"); 34 | postTitle.classList.add("post__title", "openModal"); 35 | const postBody = document.createElement("p"); 36 | postBody.classList.add("post__body"); 37 | const buttonsContainer = document.createElement("div"); 38 | buttonsContainer.classList.add("buttons__container"); 39 | const modifyButton = document.createElement("button"); 40 | modifyButton.classList.add("btn", "btn-secondary", "btn__modify"); 41 | const iconModify = document.createElement("i"); 42 | iconModify.classList.add("bi", "bi-bookmark-check"); 43 | const deleteButton = document.createElement("button"); 44 | deleteButton.classList.add("btn", "btn-warning", "btn__delete"); 45 | const iconDelete = document.createElement("i"); 46 | iconDelete.classList.add("bi", "bi-file-x"); 47 | 48 | postTitle.textContent = `${title}`; 49 | postTitle.setAttribute("data-id", id); 50 | postTitle.setAttribute("data-userId", userId); 51 | 52 | postTitle.setAttribute("data-bs-toggle", "modal"); 53 | postTitle.setAttribute("data-bs-target", "#modalWindow"); 54 | modifyButton.setAttribute("data-bs-toggle", "modal"); 55 | postBody.textContent = body; 56 | deleteButton.setAttribute("data-id", id); 57 | deleteButton.setAttribute("data-bs-toggle", "modal"); 58 | deleteButton.setAttribute("data-bs-target", "#modalDelete"); 59 | 60 | deleteButton.textContent = "Delete"; 61 | modifyButton.setAttribute("data-id", id); 62 | modifyButton.setAttribute("data-bs-target", "#modalModify"); 63 | modifyButton.setAttribute("data-modify", true); 64 | modifyButton.textContent = "Modify"; 65 | deleteButton.setAttribute("data-delete", true); 66 | 67 | avatarImg.src = `https://source.unsplash.com/16${index}x9${index}/?profile picture?orientation=portrait`; 68 | 69 | deleteButton.append(iconDelete); 70 | modifyButton.append(iconModify); 71 | buttonsContainer.append(modifyButton, deleteButton); 72 | postContainer.append(postTitle, postBody, buttonsContainer); 73 | liElement.append(avatarImg, postContainer); 74 | 75 | return liElement; 76 | }; 77 | 78 | const updatePostsDisplay = () => { 79 | while (postList.firstChild) { 80 | postList.removeChild(postList.lastChild); 81 | } 82 | }; 83 | 84 | const updateDisplay = () => { 85 | while (commentsUl.firstChild) { 86 | commentsUl.removeChild(commentsUl.lastChild); 87 | } 88 | }; 89 | 90 | const addPaginators = () => { 91 | Array.from(paginatorNumbers).map((number) => { 92 | number.addEventListener("click", (e) => { 93 | e.preventDefault(); 94 | updatePostsDisplay(); 95 | startNumberPagination = (e.target.getAttribute("value") - 1) * 10; 96 | endNumberPagination = e.target.getAttribute("value") * 10; 97 | getPosts( 98 | (e.target.getAttribute("value") - 1) * 10, 99 | e.target.getAttribute("value") * 10 100 | ); 101 | }); 102 | }); 103 | }; 104 | 105 | export { 106 | createPost, 107 | addPaginators, 108 | updatePostsDisplay, 109 | updateDisplay, 110 | startNumberPagination, 111 | endNumberPagination, 112 | }; 113 | -------------------------------------------------------------------------------- /src/styles/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | body { 32 | line-height: 1; 33 | } 34 | ol, ul { 35 | list-style: none; 36 | } 37 | blockquote, q { 38 | quotes: none; 39 | } 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | table { 46 | border-collapse: collapse; 47 | border-spacing: 0; 48 | } -------------------------------------------------------------------------------- /src/styles/style.css: -------------------------------------------------------------------------------- 1 | @import url(./reset.css); 2 | @import url("https://fonts.googleapis.com/css2?family=Nunito&display=swap"); 3 | 4 | * { 5 | font-family: "Nunito", sans-serif; 6 | } 7 | body { 8 | display: flex; 9 | flex-direction: column; 10 | align-items: center; 11 | justify-content: center; 12 | background-image: url("../assets/Aablog.jpg"); 13 | background-size: cover; 14 | background-repeat: no-repeat; 15 | background-attachment: fixed; 16 | } 17 | main { 18 | display: flex; 19 | flex-direction: column; 20 | align-items: center; 21 | position: relative; 22 | width: 90vw; 23 | } 24 | 25 | .article__post { 26 | display: flex; 27 | padding: 2%; 28 | margin: 20px 10%; 29 | border-radius: 5px; 30 | box-shadow: 4px 4px 4px 4px rgb(199, 199, 199); 31 | } 32 | .post__container { 33 | width: 100%; 34 | } 35 | 36 | .postList { 37 | background-color: aliceblue; 38 | height: 70vh; 39 | width: 75%; 40 | margin: 0 15%; 41 | padding-top: 2rem; 42 | padding-bottom: 5rem; 43 | overflow: overlay; 44 | background-color: #fff6ea; 45 | } 46 | 47 | .navbar { 48 | position: sticky !important; 49 | padding: 15%; 50 | top: 0; 51 | width: 100%; 52 | z-index: 1; 53 | } 54 | .subTitle { 55 | width: 75%; 56 | padding: 20px; 57 | margin: 0 15%; 58 | font-weight: 700; 59 | border-radius: 10px 10px 0 0; 60 | margin-top: 2rem; 61 | background-color: #fff6ea; 62 | color: black; 63 | text-align: center; 64 | } 65 | 66 | .img__avatar { 67 | height: 4rem; 68 | width: 4rem; 69 | border-radius: 50%; 70 | margin-right: 1rem; 71 | } 72 | 73 | .buttons__container { 74 | display: flex; 75 | flex-wrap: wrap; 76 | justify-content: flex-end; 77 | margin-top: 20px; 78 | } 79 | 80 | .btn__delete { 81 | margin-left: 2rem; 82 | } 83 | 84 | .openModal:hover { 85 | color: rgb(224, 89, 89); 86 | cursor: pointer; 87 | } 88 | 89 | .footer { 90 | width: 75%; 91 | margin-bottom: 0; 92 | } 93 | .pagination { 94 | display: flex; 95 | justify-content: center; 96 | background-color: aliceblue; 97 | border-radius: 0 0 10px 10px; 98 | background-color: #fff6ea; 99 | } 100 | .comments__li { 101 | list-style-type: none; 102 | box-shadow: 2px 2px 2px 2px rgb(199, 199, 199); 103 | padding: 2%; 104 | margin: 20px 0; 105 | } 106 | .comments__li:hover { 107 | background-color: beige; 108 | } 109 | .modify__title{ 110 | width: 100%; 111 | border: 1.5px solid black; 112 | border-radius: 5px; 113 | margin: 10px 0 20px 0; 114 | box-shadow: 2px 2px 2px 2px rgb(199, 199, 199); 115 | } 116 | .modifyBody { 117 | resize: none; 118 | width: 100%; 119 | border: 1.5px solid black; 120 | border-radius: 5px; 121 | margin: 10px 0 20px 0; 122 | box-shadow: 2px 2px 2px 2px rgb(199, 199, 199); 123 | } 124 | .modal-body { 125 | display: flex; 126 | flex-direction: column; 127 | align-items: flex-start; 128 | justify-content: center; 129 | } 130 | .modal__comments { 131 | overflow-y: overlay; 132 | height: 70vh; 133 | } 134 | .hide { 135 | display: none !important; 136 | } 137 | 138 | /* Firefox */ 139 | * { 140 | scrollbar-width: auto; 141 | scrollbar-color: #9f9d9d #ffffff; 142 | } 143 | 144 | /* Chrome, Edge, and Safari */ 145 | *::-webkit-scrollbar { 146 | width: 16px; 147 | } 148 | 149 | *::-webkit-scrollbar-track { 150 | background: #fff6ea; 151 | margin-top: 10px; 152 | margin-bottom: 10px; 153 | } 154 | 155 | *::-webkit-scrollbar-thumb { 156 | background-color: #9f9d9d; 157 | border-radius: 10px; 158 | border: 3px solid #ffffff; 159 | } 160 | 161 | @media (max-width: 700px) { 162 | .navbar img { 163 | margin: 0 auto; 164 | align-items: center; 165 | text-align: center; 166 | justify-content: center; 167 | } 168 | .article__post { 169 | display: flex; 170 | flex-direction: column; 171 | padding: 2%; 172 | margin: 20px 0%; 173 | border-radius: 5px; 174 | box-shadow: 4px 4px 4px 4px rgb(199, 199, 199); 175 | } 176 | .postList { 177 | margin: 0 2%; 178 | padding-top: 2rem; 179 | padding-bottom: 5rem; 180 | } 181 | .btn__modify { 182 | margin-top: 0.7rem; 183 | width: 100%; 184 | } 185 | .btn__delete { 186 | margin-top: 0.7rem; 187 | margin-left: 0; 188 | } 189 | .img__avatar { 190 | margin: 10px auto; 191 | width: 9rem; 192 | height: 9rem; 193 | } 194 | .buttons__container { 195 | display: flex; 196 | flex-direction: column; 197 | justify-content: flex-end; 198 | margin-top: 20px; 199 | } 200 | ul#postList.postList { 201 | padding-left: 0; 202 | } 203 | .postList{ 204 | overflow: initial; 205 | height: 100%; 206 | width: 100%; 207 | margin: 0 0; 208 | } 209 | .subTitle { 210 | width: 100%; 211 | padding: 20px; 212 | margin: 0 15%; 213 | font-weight: 700; 214 | border-radius: 10px 10px 0 0; 215 | margin-top: 2rem; 216 | background-color: #fff6ea; 217 | color: black; 218 | text-align: center; 219 | } 220 | } --------------------------------------------------------------------------------