├── .gitignore
├── LICENSE
├── README.md
├── index.html
├── package.json
└── src
├── css
├── avatar
│ ├── avatar.css
│ ├── avatar.css.map
│ └── avatar.scss
├── create-post
│ ├── createPost.css
│ ├── createPost.css.map
│ └── createPost.scss
├── fonts
│ └── fonts.css
├── layout
│ └── main-layout.css
├── main.css
├── modal
│ └── loginModal.css
├── post
│ ├── post.css
│ ├── post.css.map
│ └── post.scss
└── reset
│ └── normalize.css
├── data
└── db.json
├── img
├── 150.gif
├── 1564534_customer_man_user_account_profile_icon.png
├── 25.gif
├── Project IMG.png
├── icon
│ ├── comment-icon.png
│ ├── create-comment-icon.png
│ ├── delete-icon.png
│ └── edit-icon.png
└── pokemon-background.jpg
└── js
├── api-communication.js
├── login.js
├── main.js
├── poke-api-communication.js
└── post.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
--------------------------------------------------------------------------------
/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 | > In this pill we have learned how to create a blog with an API serving the necessary data to create it.
6 | > We have used:
7 | * HTML: skeleton of the project
8 | * CSS: styles of our page
9 | * Bootstrap and SASS: as css framework
10 | * JS Vanilla: project logic
11 | * PokeAPI and JSON Server: get data and send data to create our own API.
12 |
13 |
14 | ## Project Img
15 | 
16 |
17 |
18 | ## Repository
19 |
20 | To get our project, you can clone it and do npm install to get the dependencies
21 |
22 |
23 | ## Team Members
24 |
25 | [Roger Olive Delgado](https://github.com/RogerOliveDelgado).
26 | [Julio Macias Caldera](https://github.com/juliomc23).
27 |
28 |
29 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
9 |
12 |
13 |
14 | Blog with API
15 |
16 |
17 |
18 |
19 |
20 |
21 |
23 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Post
36 |
37 |
38 |
39 |
40 |
41 |
45 |
46 |
49 |
50 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
65 |
66 |
69 |
70 |
73 |
74 |
75 |
76 |
77 |
90 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/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 ./src/data/db.json"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/RogerOliveDelgado/blog-with-api.git"
13 | },
14 | "author": "",
15 | "license": "ISC",
16 | "bugs": {
17 | "url": "https://github.com/RogerOliveDelgado/blog-with-api/issues"
18 | },
19 | "homepage": "https://github.com/RogerOliveDelgado/blog-with-api#readme",
20 | "keywords": [],
21 | "dependencies": {
22 | "json-server": "^0.17.0"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/css/avatar/avatar.css:
--------------------------------------------------------------------------------
1 | .avatar {
2 | display: -webkit-box;
3 | display: -ms-flexbox;
4 | display: flex;
5 | -webkit-box-orient: horizontal;
6 | -webkit-box-direction: normal;
7 | -ms-flex-direction: row;
8 | flex-direction: row;
9 | }
10 |
11 | .avatar__image {
12 | width: 4rem;
13 | height: 4rem;
14 | margin-left: 0.5rem;
15 | padding: 0.3rem;
16 | background-color: black;
17 | border: 1px solid black;
18 | border-radius: 50%;
19 | }
20 |
21 | .avatar__user {
22 | margin-left: 0.5rem;
23 | }
24 | /*# sourceMappingURL=avatar.css.map */
--------------------------------------------------------------------------------
/src/css/avatar/avatar.css.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "mappings": "AAAA,AAAA,OAAO,CAAA;EACH,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,GAAG;CAgBtB;;AAdI,AAAD,cAAQ,CAAA;EACJ,KAAK,EAAC,IAAI;EACV,MAAM,EAAE,IAAI;EACZ,WAAW,EAAE,MAAM;EACnB,OAAO,EAAE,MAAM;EACf,gBAAgB,EAAE,KAAK;EACvB,MAAM,EAAE,eAAe;EACvB,aAAa,EAAE,GAAG;CACrB;;AAEA,AAAD,aAAO,CAAA;EACH,WAAW,EAAE,MAAM;CACtB",
4 | "sources": [
5 | "avatar.scss"
6 | ],
7 | "names": [],
8 | "file": "avatar.css"
9 | }
--------------------------------------------------------------------------------
/src/css/avatar/avatar.scss:
--------------------------------------------------------------------------------
1 | .avatar{
2 | display: flex;
3 | flex-direction: row;
4 |
5 | &__image{
6 | width:4rem;
7 | height: 4rem;
8 | margin-left: 0.5rem;
9 | padding: 0.3rem;
10 | background-color: black;
11 | border: 1px solid black;
12 | border-radius: 50%;
13 | }
14 |
15 | &__user{
16 | margin-left: 0.5rem;
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/src/css/create-post/createPost.css:
--------------------------------------------------------------------------------
1 | .create-post {
2 | display: -webkit-box;
3 | display: -ms-flexbox;
4 | display: flex;
5 | position: relative;
6 | width: 100%;
7 | border-top: 1px solid #ccc;
8 | border-bottom: 1px solid #ccc;
9 | margin-bottom: 0.5rem;
10 | }
11 |
12 | .create-post__avatar {
13 | width: 4rem;
14 | height: 4rem;
15 | margin-top: 1rem;
16 | margin-left: 1rem;
17 | border: 1px solid black;
18 | border-radius: 50%;
19 | background-color: #f56161;
20 | }
21 |
22 | .create-post__text {
23 | width: 100%;
24 | margin-left: 1rem;
25 | padding-top: 2.0rem;
26 | font-size: 1.5rem;
27 | border: 1px solid #688a95;
28 | border-radius: 0.5rem;
29 | outline: none;
30 | resize: none;
31 | }
32 |
33 | .btn__createPost {
34 | -ms-flex-item-align: end;
35 | align-self: flex-end;
36 | width: -webkit-fit-content;
37 | width: -moz-fit-content;
38 | width: fit-content;
39 | height: -webkit-fit-content;
40 | height: -moz-fit-content;
41 | height: fit-content;
42 | margin-right: 0.5rem;
43 | margin-bottom: 0.5rem;
44 | background-color: #57a0a1;
45 | color: black;
46 | font-weight: bold;
47 | border-color: #ccc;
48 | -webkit-transition: all 300ms;
49 | transition: all 300ms;
50 | }
51 |
52 | .btn__createPost:hover {
53 | background-color: transparent;
54 | color: black;
55 | -webkit-transform: scale(1.1);
56 | transform: scale(1.1);
57 | border-color: #919191;
58 | }
59 | /*# sourceMappingURL=createPost.css.map */
--------------------------------------------------------------------------------
/src/css/create-post/createPost.css.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "mappings": "AAAA,AAAA,YAAY,CAAA;EACR,OAAO,EAAE,IAAI;EACb,QAAQ,EAAE,QAAQ;EAClB,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,cAAc;EAC1B,aAAa,EAAE,cAAc;EAC7B,aAAa,EAAE,MAAM;CAuBxB;;AArBI,AAAD,oBAAS,CAAA;EACL,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,UAAU,EAAE,IAAI;EAChB,WAAW,EAAE,IAAI;EACjB,MAAM,EAAE,eAAe;EACvB,aAAa,EAAE,GAAG;EAClB,gBAAgB,EAAE,OAAgB;CACrC;;AAEA,AAAD,kBAAO,CAAC;EACJ,KAAK,EAAE,IAAI;EACX,WAAW,EAAE,IAAI;EACjB,WAAW,EAAE,MAAM;EACnB,SAAS,EAAE,MAAM;EACjB,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,OAAkB;EACpC,aAAa,EAAE,MAAM;EACrB,OAAO,EAAE,IAAI;EACb,MAAM,EAAE,IAAI;CACf;;AAIL,AAAA,gBAAgB,CAAA;EACZ,UAAU,EAAE,QAAQ;EACpB,KAAK,EAAE,WAAW;EAClB,MAAM,EAAE,WAAW;EACnB,YAAY,EAAE,MAAM;EACpB,aAAa,EAAE,MAAM;EACrB,gBAAgB,EAAE,OAAiB;EACnC,KAAK,EAAE,KAAK;EACZ,WAAW,EAAE,IAAI;EACjB,YAAY,EAAE,IAAI;EAClB,UAAU,EAAE,SAAS;CACxB;;AAED,AAAA,gBAAgB,AAAA,MAAM,CAAA;EAClB,gBAAgB,EAAE,WAAW;EAC7B,KAAK,EAAE,KAAK;EACZ,SAAS,EAAE,UAAU;EACrB,YAAY,EAAE,OAAkB;CACnC",
4 | "sources": [
5 | "createPost.scss"
6 | ],
7 | "names": [],
8 | "file": "createPost.css"
9 | }
--------------------------------------------------------------------------------
/src/css/create-post/createPost.scss:
--------------------------------------------------------------------------------
1 | .create-post{
2 | display: flex;
3 | position: relative;
4 | width: 100%;
5 | border-top: 1px solid #ccc;
6 | border-bottom: 1px solid #ccc;
7 | margin-bottom: 0.5rem;
8 |
9 | &__avatar{
10 | width: 4rem;
11 | height: 4rem;
12 | margin-top: 1rem;
13 | margin-left: 1rem;
14 | border: 1px solid black;
15 | border-radius: 50%;
16 | background-color: rgb(245, 97, 97);
17 | }
18 |
19 | &__text {
20 | width: 100%;
21 | margin-left: 1rem;
22 | padding-top: 2.0rem;
23 | font-size: 1.5rem;
24 | border: 1px solid rgb(104, 138, 149);
25 | border-radius: 0.5rem;
26 | outline: none;
27 | resize: none;
28 | }
29 |
30 | }
31 |
32 | .btn__createPost{
33 | align-self: flex-end;
34 | width: fit-content;
35 | height: fit-content;
36 | margin-right: 0.5rem;
37 | margin-bottom: 0.5rem;
38 | background-color: rgb(87, 160, 161);
39 | color: black;
40 | font-weight: bold;
41 | border-color: #ccc;
42 | transition: all 300ms;
43 | }
44 |
45 | .btn__createPost:hover{
46 | background-color: transparent;
47 | color: black;
48 | transform: scale(1.1);
49 | border-color: rgb(145, 145, 145);
50 | }
--------------------------------------------------------------------------------
/src/css/fonts/fonts.css:
--------------------------------------------------------------------------------
1 | /*FONTS*/
2 |
3 | @import url('https://fonts.googleapis.com/css2?family=Rubik:wght@300&display=swap');
4 |
5 | .main__container{
6 | font-family: 'Rubik', sans-serif;
7 | }
8 |
--------------------------------------------------------------------------------
/src/css/layout/main-layout.css:
--------------------------------------------------------------------------------
1 | body {
2 | display: flex;
3 | flex-direction: column;
4 | justify-content: center;
5 | align-items: center;
6 | background: url(../../img/pokemon-background.jpg) center repeat;
7 | }
8 |
9 | .main__posts{
10 | display: flex;
11 | flex-direction: column;
12 | }
13 |
14 | .main__container{
15 | display: flex;
16 | flex-direction: column;
17 | width: 50%;
18 | min-width: 30rem;
19 | border-left: 1px solid #ccc;
20 | border-right: 1px solid #ccc;
21 | background: rgb(179, 219, 248);
22 | }
23 |
24 | .main__header{
25 | display: flex;
26 | justify-content: space-between;
27 | align-items: center;
28 | width: 100%;
29 | margin-bottom: 2rem;
30 | }
31 |
32 | .header__title{
33 | margin-left: 2rem;
34 | }
35 | .img__userProfile{
36 | width: 2rem;
37 | height: 2rem;
38 | margin-right: 2rem;
39 | cursor: pointer;
40 | }
41 |
42 | .posts__article {
43 | display: flex;
44 | flex-direction: column;
45 | border-bottom: 1px solid #ccc;
46 | margin-bottom: 0.5rem;
47 | padding: 0.5rem;
48 | }
49 |
50 | .post__title, .article__span--username{
51 | text-transform: uppercase;
52 | font-weight: bold;
53 | }
54 |
55 | .post__body, .article__span--comment{
56 | margin-left: 0.3rem;
57 | margin-bottom: 5rem;
58 | }
59 |
60 | .article__button--showComments{
61 | background: url('../../img/icon/comment-icon.png') center no-repeat;
62 | width: 3rem;
63 | height: 3rem;
64 | /* position: absolute; */
65 | /* top: 75%; */
66 | /* left: 1%; */
67 | border: none;
68 | }
69 |
70 | .article__button--createComments{
71 | background: url('../../img/icon/create-comment-icon.png') center no-repeat;
72 | width: 3rem;
73 | height: 3rem;
74 | position: absolute;
75 | top: 75%;
76 | left: 9%;
77 | border: none;
78 | }
79 |
80 | .article__button--editButton{
81 | background: url('../../img/icon/edit-icon.png') center no-repeat;
82 | width: 3rem;
83 | height: 3rem;
84 | position: absolute;
85 | top: 75%;
86 | left: 17%;
87 | border: none;
88 | }
89 |
90 | .article__button--deleteButton{
91 | background: url('../../img/icon/delete-icon.png') center no-repeat;
92 | width: 3rem;
93 | height: 3rem;
94 | position: absolute;
95 | top: 75%;
96 | left: 25%;
97 | border: none;
98 | }
99 |
100 | .comments__article{
101 | display: flex;
102 | flex-direction: column;
103 | border: 1px solid rgb(10, 10, 10);
104 | padding: 0.3rem;
105 | }
106 |
107 | .comment__avatar{
108 | width: 3rem;
109 | height: 3rem;
110 | border: 1px solid black;
111 | border-radius: 50%;
112 | padding: 0.25rem;
113 | background: lightcyan;
114 | }
--------------------------------------------------------------------------------
/src/css/main.css:
--------------------------------------------------------------------------------
1 | /*RESET*/
2 | @import url(./reset/normalize.css);
3 |
4 | /*FONTS*/
5 | @import url(./fonts/fonts.css);
6 |
7 | /*MODAL*/
8 | @import url(./modal/loginModal.css);
9 |
10 | /*MAIN LAYOUT*/
11 | @import url(./layout/main-layout.css);
12 |
13 | /*CREATE POST*/
14 | @import url(./create-post/createPost.css);
15 |
16 | /*AVATAR*/
17 | @import url(./avatar/avatar.css);
18 |
19 | /*POST*/
20 | @import url(./post/post.css)
21 |
--------------------------------------------------------------------------------
/src/css/modal/loginModal.css:
--------------------------------------------------------------------------------
1 | .btn__openModal{
2 | background-color: transparent;
3 | border: none;
4 | margin-right: 2rem;
5 | }
6 |
7 | .modal-body{
8 | display: flex;
9 | flex-direction: column;
10 | }
11 |
12 | .register__form{
13 | height: 5rem;
14 | display: flex;
15 | flex-direction: column;
16 | justify-content: space-around;
17 | }
18 |
19 | .hide{
20 | display: none;
21 | }
22 |
23 | .wrong{
24 | border: 1px solid red;
25 | }
--------------------------------------------------------------------------------
/src/css/post/post.css:
--------------------------------------------------------------------------------
1 | .post__header {
2 | display: -webkit-box;
3 | display: -ms-flexbox;
4 | display: flex;
5 | -webkit-box-orient: horizontal;
6 | -webkit-box-direction: normal;
7 | -ms-flex-direction: row;
8 | flex-direction: row;
9 | -webkit-box-pack: justify;
10 | -ms-flex-pack: justify;
11 | justify-content: space-between;
12 | }
13 |
14 | .post__text {
15 | width: 90%;
16 | padding-left: 0.5rem;
17 | margin-top: 1rem;
18 | margin-left: 5%;
19 | border: 1px solid black;
20 | border-radius: 0.25rem;
21 | }
22 |
23 | .post__comments-status {
24 | display: -webkit-box;
25 | display: -ms-flexbox;
26 | display: flex;
27 | -webkit-box-orient: horizontal;
28 | -webkit-box-direction: normal;
29 | -ms-flex-direction: row;
30 | flex-direction: row;
31 | -webkit-box-pack: center;
32 | -ms-flex-pack: center;
33 | justify-content: center;
34 | -webkit-box-align: center;
35 | -ms-flex-align: center;
36 | align-items: center;
37 | }
38 |
39 | .post__comments-btn {
40 | background: url("../../img/icon/edit-icon.png") center no-repeat;
41 | position: absolute;
42 | width: 3rem;
43 | height: 3rem;
44 | border: none;
45 | }
46 |
47 | .post__comments-counter {
48 | padding-top: 0.8rem;
49 | }
50 |
51 | .post__modify-cont {
52 | display: -webkit-box;
53 | display: -ms-flexbox;
54 | display: flex;
55 | -webkit-box-orient: horizontal;
56 | -webkit-box-direction: normal;
57 | -ms-flex-direction: row;
58 | flex-direction: row;
59 | }
60 |
61 | .post__delete-btn {
62 | background: url("../../img/icon/delete-icon.png") center no-repeat;
63 | width: 3rem;
64 | height: 3rem;
65 | border: none;
66 | }
67 |
68 | .post__edit-btn {
69 | background: url("../../img/icon/edit-icon.png") center no-repeat;
70 | width: 3rem;
71 | height: 3rem;
72 | border: none;
73 | }
74 | /*# sourceMappingURL=post.css.map */
--------------------------------------------------------------------------------
/src/css/post/post.css.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "mappings": "AACK,AAAD,aAAS,CAAA;EACL,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,GAAG;EACnB,eAAe,EAAE,aAAa;CACjC;;AAEA,AAAD,WAAO,CAAA;EACH,KAAK,EAAE,GAAG;EACV,YAAY,EAAE,MAAM;EACpB,UAAU,EAAE,IAAI;EAChB,WAAW,EAAE,EAAE;EACf,MAAM,EAAE,eAAe;EACvB,aAAa,EAAE,OAAO;CACzB;;AAGI,AAAD,sBAAQ,CAAA;EACJ,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,GAAG;EACnB,eAAe,EAAE,MAAM;EACvB,WAAW,EAAE,MAAM;CACtB;;AACA,AAAD,mBAAK,CAAA;EACD,UAAU,EAAE,mCAAmC,CAAC,MAAM,CAAC,SAAS;EAChE,QAAQ,EAAE,QAAQ;EAClB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,MAAM,EAAE,IAAI;CACf;;AACA,AAAD,uBAAS,CAAA;EACL,WAAW,EAAE,MAAM;CACtB;;AAGJ,AAAD,kBAAc,CAAA;EACV,OAAO,EAAC,IAAI;EACZ,cAAc,EAAE,GAAG;CACtB;;AAEA,AAAD,iBAAa,CAAA;EACT,UAAU,EAAE,qCAAqC,CAAC,MAAM,CAAC,SAAS;EAClE,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,MAAM,EAAE,IAAI;CACf;;AAEA,AAAD,eAAW,CAAA;EACP,UAAU,EAAE,mCAAmC,CAAC,MAAM,CAAC,SAAS;EAChE,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,MAAM,EAAE,IAAI;CACf",
4 | "sources": [
5 | "post.scss"
6 | ],
7 | "names": [],
8 | "file": "post.css"
9 | }
--------------------------------------------------------------------------------
/src/css/post/post.scss:
--------------------------------------------------------------------------------
1 | .post{
2 | &__header{
3 | display: flex;
4 | flex-direction: row;
5 | justify-content: space-between;
6 | }
7 |
8 | &__text{
9 | width: 90%;
10 | padding-left: 0.5rem;
11 | margin-top: 1rem;
12 | margin-left: 5%;
13 | border: 1px solid black;
14 | border-radius: 0.25rem;
15 | }
16 |
17 | &__comments{
18 | &-status{
19 | display: flex;
20 | flex-direction: row;
21 | justify-content: center;
22 | align-items: center;
23 | }
24 | &-btn{
25 | background: url('../../img/icon/edit-icon.png') center no-repeat;
26 | position: absolute;
27 | width: 3rem;
28 | height: 3rem;
29 | border: none;
30 | }
31 | &-counter{
32 | padding-top: 0.8rem;
33 | }
34 | }
35 |
36 | &__modify-cont{
37 | display:flex;
38 | flex-direction: row;
39 | }
40 |
41 | &__delete-btn{
42 | background: url('../../img/icon/delete-icon.png') center no-repeat;
43 | width: 3rem;
44 | height: 3rem;
45 | border: none;
46 | }
47 |
48 | &__edit-btn{
49 | background: url('../../img/icon/edit-icon.png') center no-repeat;
50 | width: 3rem;
51 | height: 3rem;
52 | border: none;
53 | }
54 | }
--------------------------------------------------------------------------------
/src/css/reset/normalize.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
2 |
3 | /* Document
4 | ========================================================================== */
5 |
6 | /**
7 | * 1. Correct the line height in all browsers.
8 | * 2. Prevent adjustments of font size after orientation changes in iOS.
9 | */
10 |
11 | html {
12 | line-height: 1.15; /* 1 */
13 | -webkit-text-size-adjust: 100%; /* 2 */
14 | }
15 |
16 | /* Sections
17 | ========================================================================== */
18 |
19 | /**
20 | * Remove the margin in all browsers.
21 | */
22 |
23 | body {
24 | margin: 0;
25 | }
26 |
27 | /**
28 | * Render the `main` element consistently in IE.
29 | */
30 |
31 | main {
32 | display: block;
33 | }
34 |
35 | /**
36 | * Correct the font size and margin on `h1` elements within `section` and
37 | * `article` contexts in Chrome, Firefox, and Safari.
38 | */
39 |
40 | h1 {
41 | font-size: 2em;
42 | margin: 0.67em 0;
43 | }
44 |
45 | /* Grouping content
46 | ========================================================================== */
47 |
48 | /**
49 | * 1. Add the correct box sizing in Firefox.
50 | * 2. Show the overflow in Edge and IE.
51 | */
52 |
53 | hr {
54 | box-sizing: content-box; /* 1 */
55 | height: 0; /* 1 */
56 | overflow: visible; /* 2 */
57 | }
58 |
59 | /**
60 | * 1. Correct the inheritance and scaling of font size in all browsers.
61 | * 2. Correct the odd `em` font sizing in all browsers.
62 | */
63 |
64 | pre {
65 | font-family: monospace, monospace; /* 1 */
66 | font-size: 1em; /* 2 */
67 | }
68 |
69 | /* Text-level semantics
70 | ========================================================================== */
71 |
72 | /**
73 | * Remove the gray background on active links in IE 10.
74 | */
75 |
76 | a {
77 | background-color: transparent;
78 | }
79 |
80 | /**
81 | * 1. Remove the bottom border in Chrome 57-
82 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
83 | */
84 |
85 | abbr[title] {
86 | border-bottom: none; /* 1 */
87 | text-decoration: underline; /* 2 */
88 | text-decoration: underline dotted; /* 2 */
89 | }
90 |
91 | /**
92 | * Add the correct font weight in Chrome, Edge, and Safari.
93 | */
94 |
95 | b,
96 | strong {
97 | font-weight: bolder;
98 | }
99 |
100 | /**
101 | * 1. Correct the inheritance and scaling of font size in all browsers.
102 | * 2. Correct the odd `em` font sizing in all browsers.
103 | */
104 |
105 | code,
106 | kbd,
107 | samp {
108 | font-family: monospace, monospace; /* 1 */
109 | font-size: 1em; /* 2 */
110 | }
111 |
112 | /**
113 | * Add the correct font size in all browsers.
114 | */
115 |
116 | small {
117 | font-size: 80%;
118 | }
119 |
120 | /**
121 | * Prevent `sub` and `sup` elements from affecting the line height in
122 | * all browsers.
123 | */
124 |
125 | sub,
126 | sup {
127 | font-size: 75%;
128 | line-height: 0;
129 | position: relative;
130 | vertical-align: baseline;
131 | }
132 |
133 | sub {
134 | bottom: -0.25em;
135 | }
136 |
137 | sup {
138 | top: -0.5em;
139 | }
140 |
141 | /* Embedded content
142 | ========================================================================== */
143 |
144 | /**
145 | * Remove the border on images inside links in IE 10.
146 | */
147 |
148 | img {
149 | border-style: none;
150 | }
151 |
152 | /* Forms
153 | ========================================================================== */
154 |
155 | /**
156 | * 1. Change the font styles in all browsers.
157 | * 2. Remove the margin in Firefox and Safari.
158 | */
159 |
160 | button,
161 | input,
162 | optgroup,
163 | select,
164 | textarea {
165 | font-family: inherit; /* 1 */
166 | font-size: 100%; /* 1 */
167 | line-height: 1.15; /* 1 */
168 | margin: 0; /* 2 */
169 | }
170 |
171 | /**
172 | * Show the overflow in IE.
173 | * 1. Show the overflow in Edge.
174 | */
175 |
176 | button,
177 | input { /* 1 */
178 | overflow: visible;
179 | }
180 |
181 | /**
182 | * Remove the inheritance of text transform in Edge, Firefox, and IE.
183 | * 1. Remove the inheritance of text transform in Firefox.
184 | */
185 |
186 | button,
187 | select { /* 1 */
188 | text-transform: none;
189 | }
190 |
191 | /**
192 | * Correct the inability to style clickable types in iOS and Safari.
193 | */
194 |
195 | button,
196 | [type="button"],
197 | [type="reset"],
198 | [type="submit"] {
199 | -webkit-appearance: button;
200 | }
201 |
202 | /**
203 | * Remove the inner border and padding in Firefox.
204 | */
205 |
206 | button::-moz-focus-inner,
207 | [type="button"]::-moz-focus-inner,
208 | [type="reset"]::-moz-focus-inner,
209 | [type="submit"]::-moz-focus-inner {
210 | border-style: none;
211 | padding: 0;
212 | }
213 |
214 | /**
215 | * Restore the focus styles unset by the previous rule.
216 | */
217 |
218 | button:-moz-focusring,
219 | [type="button"]:-moz-focusring,
220 | [type="reset"]:-moz-focusring,
221 | [type="submit"]:-moz-focusring {
222 | outline: 1px dotted ButtonText;
223 | }
224 |
225 | /**
226 | * Correct the padding in Firefox.
227 | */
228 |
229 | fieldset {
230 | padding: 0.35em 0.75em 0.625em;
231 | }
232 |
233 | /**
234 | * 1. Correct the text wrapping in Edge and IE.
235 | * 2. Correct the color inheritance from `fieldset` elements in IE.
236 | * 3. Remove the padding so developers are not caught out when they zero out
237 | * `fieldset` elements in all browsers.
238 | */
239 |
240 | legend {
241 | box-sizing: border-box; /* 1 */
242 | color: inherit; /* 2 */
243 | display: table; /* 1 */
244 | max-width: 100%; /* 1 */
245 | padding: 0; /* 3 */
246 | white-space: normal; /* 1 */
247 | }
248 |
249 | /**
250 | * Add the correct vertical alignment in Chrome, Firefox, and Opera.
251 | */
252 |
253 | progress {
254 | vertical-align: baseline;
255 | }
256 |
257 | /**
258 | * Remove the default vertical scrollbar in IE 10+.
259 | */
260 |
261 | textarea {
262 | resize: none;
263 | overflow: auto;
264 | }
265 |
266 | /**
267 | * 1. Add the correct box sizing in IE 10.
268 | * 2. Remove the padding in IE 10.
269 | */
270 |
271 | [type="checkbox"],
272 | [type="radio"] {
273 | box-sizing: border-box; /* 1 */
274 | padding: 0; /* 2 */
275 | }
276 |
277 | /**
278 | * Correct the cursor style of increment and decrement buttons in Chrome.
279 | */
280 |
281 | [type="number"]::-webkit-inner-spin-button,
282 | [type="number"]::-webkit-outer-spin-button {
283 | height: auto;
284 | }
285 |
286 | /**
287 | * 1. Correct the odd appearance in Chrome and Safari.
288 | * 2. Correct the outline style in Safari.
289 | */
290 |
291 | [type="search"] {
292 | -webkit-appearance: textfield; /* 1 */
293 | outline-offset: -2px; /* 2 */
294 | }
295 |
296 | /**
297 | * Remove the inner padding in Chrome and Safari on macOS.
298 | */
299 |
300 | [type="search"]::-webkit-search-decoration {
301 | -webkit-appearance: none;
302 | }
303 |
304 | /**
305 | * 1. Correct the inability to style clickable types in iOS and Safari.
306 | * 2. Change font properties to `inherit` in Safari.
307 | */
308 |
309 | ::-webkit-file-upload-button {
310 | -webkit-appearance: button; /* 1 */
311 | font: inherit; /* 2 */
312 | }
313 |
314 | /* Interactive
315 | ========================================================================== */
316 |
317 | /*
318 | * Add the correct display in Edge, IE 10+, and Firefox.
319 | */
320 |
321 | details {
322 | display: block;
323 | }
324 |
325 | /*
326 | * Add the correct display in all browsers.
327 | */
328 |
329 | summary {
330 | display: list-item;
331 | }
332 |
333 | /* Misc
334 | ========================================================================== */
335 |
336 | /**
337 | * Add the correct display in IE 10+.
338 | */
339 |
340 | template {
341 | display: none;
342 | }
343 |
344 | /**
345 | * Add the correct display in IE 10.
346 | */
347 |
348 | [hidden] {
349 | display: none;
350 | }
351 |
--------------------------------------------------------------------------------
/src/data/db.json:
--------------------------------------------------------------------------------
1 | {
2 | "posts": [
3 | {
4 | "userId": "6",
5 | "id": 1,
6 | "username": "charizard",
7 | "body": "Soy un poquito chulillo",
8 | "commentsQty": 3
9 | },
10 | {
11 | "userId": "3",
12 | "id": 2,
13 | "username": "venusaur",
14 | "body": "Ataque rayo solar!",
15 | "commentsQty": 2
16 | },
17 | {
18 | "userId": "25",
19 | "id": 3,
20 | "username": "pikachu",
21 | "body": "Bon dia nois!\n\nComencem PHP!",
22 | "commentsQty": 4
23 | },
24 | {
25 | "userId": "15",
26 | "id": 5,
27 | "username": "beedrill",
28 | "body": "Abejita",
29 | "commentsQty": 1
30 | },
31 | {
32 | "userId": "144",
33 | "id": 6,
34 | "username": "articuno",
35 | "body": "Buenos días, \n\nQue frío hace!",
36 | "commentsQty": 0
37 | },
38 | {
39 | "userId": "151",
40 | "id": 7,
41 | "username": "mew",
42 | "body": "Mew Mew Mew",
43 | "commentsQty": 0
44 | },
45 | {
46 | "userId": "150",
47 | "id": 8,
48 | "username": "mewtwo",
49 | "body": "He venido a colonizar la tierra!\n\nTodos tranquilitos.\n\n;)",
50 | "commentsQty": 0
51 | },
52 | {
53 | "userId": "9",
54 | "id": 10,
55 | "username": "blastoise",
56 | "body": "Blastoise!\n\nBlastoise\n\nBlastoise",
57 | "commentsQty": 0
58 | },
59 | {
60 | "userId": "145",
61 | "id": 11,
62 | "username": "zapdos",
63 | "body": "Assembler School!",
64 | "commentsQty": 0
65 | },
66 | {
67 | "userId": "145",
68 | "id": 12,
69 | "username": "zapdos",
70 | "body": "Zapdos dos dos",
71 | "commentsQty": 0
72 | },
73 | {
74 | "userId": "145",
75 | "id": 13,
76 | "username": "zapdos",
77 | "body": "Zapdos dos dos",
78 | "commentsQty": 0
79 | },
80 | {
81 | "userId": "145",
82 | "id": 14,
83 | "username": "zapdos",
84 | "body": "Zapdos dos dos dos",
85 | "commentsQty": 0
86 | },
87 | {
88 | "userId": "145",
89 | "id": 15,
90 | "username": "zapdos",
91 | "body": "d asjdfn ajf asdhfbsdnfhudsbfhijsd",
92 | "commentsQty": 0
93 | },
94 | {
95 | "userId": "145",
96 | "id": 16,
97 | "username": "zapdos",
98 | "body": "wwwwwwwww",
99 | "commentsQty": 0
100 | },
101 | {
102 | "userId": "145",
103 | "id": 17,
104 | "username": "zapdos",
105 | "body": "dadfjqdnuqwndfq\ndfjneqjdfnq\ndfqjwedfnqjdfnq+\ndfmqd",
106 | "commentsQty": 0
107 | },
108 | {
109 | "userId": "145",
110 | "id": 18,
111 | "username": "zapdos",
112 | "body": "dadasd",
113 | "commentsQty": 0
114 | },
115 | {
116 | "userId": "145",
117 | "id": 19,
118 | "username": "zapdos",
119 | "body": "dda dfjnadf\nafjadfkmaf\nadfikadmfoadksifmqawe,f\nweiof\nwefkowek\nfwefko\nwekfo\nwefwe",
120 | "commentsQty": 0
121 | },
122 | {
123 | "userId": "3",
124 | "id": 20,
125 | "username": "venusaur",
126 | "body": "dad",
127 | "commentsQty": 0
128 | },
129 | {
130 | "userId": "6",
131 | "id": 21,
132 | "username": "charizard",
133 | "body": "Fire\n\nfire \n\nfire",
134 | "commentsQty": 0
135 | },
136 | {
137 | "userId": "25",
138 | "id": 22,
139 | "username": "pikachu",
140 | "body": "dadsdadad",
141 | "commentsQty": 0
142 | }
143 | ],
144 | "users": [
145 | {
146 | "id": 1,
147 | "username": "bulbasaur",
148 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/1.gif"
149 | },
150 | {
151 | "id": 2,
152 | "username": "ivysaur",
153 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/2.gif"
154 | },
155 | {
156 | "id": 3,
157 | "username": "venusaur",
158 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/3.gif"
159 | },
160 | {
161 | "id": 4,
162 | "username": "charmander",
163 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/4.gif"
164 | },
165 | {
166 | "id": 5,
167 | "username": "charmeleon",
168 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/5.gif"
169 | },
170 | {
171 | "id": 6,
172 | "username": "charizard",
173 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/6.gif"
174 | },
175 | {
176 | "id": 7,
177 | "username": "squirtle",
178 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/7.gif"
179 | },
180 | {
181 | "id": 8,
182 | "username": "wartortle",
183 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/8.gif"
184 | },
185 | {
186 | "id": 9,
187 | "username": "blastoise",
188 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/9.gif"
189 | },
190 | {
191 | "id": 10,
192 | "username": "caterpie",
193 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/10.gif"
194 | },
195 | {
196 | "id": 11,
197 | "username": "metapod",
198 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/11.gif"
199 | },
200 | {
201 | "id": 12,
202 | "username": "butterfree",
203 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/12.gif"
204 | },
205 | {
206 | "id": 13,
207 | "username": "weedle",
208 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/13.gif"
209 | },
210 | {
211 | "id": 14,
212 | "username": "kakuna",
213 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/14.gif"
214 | },
215 | {
216 | "id": 15,
217 | "username": "beedrill",
218 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/15.gif"
219 | },
220 | {
221 | "id": 22,
222 | "username": "fearow",
223 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/22.gif"
224 | },
225 | {
226 | "id": 23,
227 | "username": "ekans",
228 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/23.png"
229 | },
230 | {
231 | "id": 24,
232 | "username": "arbok",
233 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/24.png"
234 | },
235 | {
236 | "id": 25,
237 | "username": "pikachu",
238 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/25.gif"
239 | },
240 | {
241 | "id": 27,
242 | "username": "sandshrew",
243 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/27.png"
244 | },
245 | {
246 | "id": 28,
247 | "username": "sandslash",
248 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/28.png"
249 | },
250 | {
251 | "id": 26,
252 | "username": "raichu",
253 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/26.gif"
254 | },
255 | {
256 | "id": 29,
257 | "username": "nidoran-f",
258 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/29.png"
259 | },
260 | {
261 | "id": 30,
262 | "username": "nidorina",
263 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/30.png"
264 | },
265 | {
266 | "id": 31,
267 | "username": "nidoqueen",
268 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/31.png"
269 | },
270 | {
271 | "id": 144,
272 | "username": "articuno",
273 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/144.gif"
274 | },
275 | {
276 | "id": 145,
277 | "username": "zapdos",
278 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/145.gif"
279 | },
280 | {
281 | "id": 146,
282 | "username": "moltres",
283 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/146.gif"
284 | },
285 | {
286 | "id": 147,
287 | "username": "datrini",
288 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/147.gif"
289 | },
290 | {
291 | "id": 148,
292 | "username": "dagronair",
293 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/148.gif"
294 | },
295 | {
296 | "id": 149,
297 | "username": "dragonite",
298 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/149.gif"
299 | },
300 | {
301 | "id": 150,
302 | "username": "mewtwo",
303 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/150.gif"
304 | },
305 | {
306 | "id": 151,
307 | "username": "mew",
308 | "imgSrc": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/151.gif"
309 | }
310 | ],
311 | "comments": [
312 | {
313 | "postId": 1,
314 | "userId": 3,
315 | "id": 1,
316 | "name": "venusaur",
317 | "body": "Tranquilo amigo, que nosotros también estamos aquí!"
318 | },
319 | {
320 | "postId": 1,
321 | "userId": 9,
322 | "id": 2,
323 | "name": "blastoise",
324 | "body": "Si te quema, yo te tiro un poco de agua"
325 | },
326 | {
327 | "postId": 1,
328 | "userId": 150,
329 | "id": 3,
330 | "name": "mewtwo",
331 | "body": "Como no paréis, os paro yo"
332 | },
333 | {
334 | "postId": 2,
335 | "userId": 3,
336 | "id": 4,
337 | "name": "venusaur",
338 | "body": "No me quemes, por favor"
339 | },
340 | {
341 | "postId": 2,
342 | "userId": 9,
343 | "id": 5,
344 | "name": "blastoise",
345 | "body": "Si te quema, yo te tiro un poco de agua"
346 | },
347 | {
348 | "postId": 3,
349 | "userId": 150,
350 | "id": 6,
351 | "name": "mewtwo",
352 | "body": "Como no paréis, os paro yo"
353 | },
354 | {
355 | "postId": 3,
356 | "userId": 3,
357 | "id": 7,
358 | "name": "venusaur",
359 | "body": "No me quemes, por favor"
360 | },
361 | {
362 | "postId": 3,
363 | "userId": 9,
364 | "id": 8,
365 | "name": "blastoise",
366 | "body": "Si te quema, yo te tiro un poco de agua"
367 | },
368 | {
369 | "postId": 3,
370 | "userId": 150,
371 | "id": 9,
372 | "name": "mewtwo",
373 | "body": "Como no paréis, os paro yo"
374 | },
375 | {
376 | "postId": 5,
377 | "userId": 150,
378 | "id": 12,
379 | "name": "mewtwo",
380 | "body": "Como no paréis, os paro yo"
381 | }
382 | ]
383 | }
--------------------------------------------------------------------------------
/src/img/150.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juliomc23/blog-with-api/02fa0d0bd78efbd17e4f80ff038b686ebbb9486f/src/img/150.gif
--------------------------------------------------------------------------------
/src/img/1564534_customer_man_user_account_profile_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juliomc23/blog-with-api/02fa0d0bd78efbd17e4f80ff038b686ebbb9486f/src/img/1564534_customer_man_user_account_profile_icon.png
--------------------------------------------------------------------------------
/src/img/25.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juliomc23/blog-with-api/02fa0d0bd78efbd17e4f80ff038b686ebbb9486f/src/img/25.gif
--------------------------------------------------------------------------------
/src/img/Project IMG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juliomc23/blog-with-api/02fa0d0bd78efbd17e4f80ff038b686ebbb9486f/src/img/Project IMG.png
--------------------------------------------------------------------------------
/src/img/icon/comment-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juliomc23/blog-with-api/02fa0d0bd78efbd17e4f80ff038b686ebbb9486f/src/img/icon/comment-icon.png
--------------------------------------------------------------------------------
/src/img/icon/create-comment-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juliomc23/blog-with-api/02fa0d0bd78efbd17e4f80ff038b686ebbb9486f/src/img/icon/create-comment-icon.png
--------------------------------------------------------------------------------
/src/img/icon/delete-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juliomc23/blog-with-api/02fa0d0bd78efbd17e4f80ff038b686ebbb9486f/src/img/icon/delete-icon.png
--------------------------------------------------------------------------------
/src/img/icon/edit-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juliomc23/blog-with-api/02fa0d0bd78efbd17e4f80ff038b686ebbb9486f/src/img/icon/edit-icon.png
--------------------------------------------------------------------------------
/src/img/pokemon-background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juliomc23/blog-with-api/02fa0d0bd78efbd17e4f80ff038b686ebbb9486f/src/img/pokemon-background.jpg
--------------------------------------------------------------------------------
/src/js/api-communication.js:
--------------------------------------------------------------------------------
1 | //API url path
2 | const commentsPath = 'http://localhost:3000/comments'
3 | const postsPath = 'http://localhost:3000/posts'
4 | const usersPath = 'http://localhost:3000/users'
5 |
6 | // Comments
7 | async function createComment(body, postId){
8 | try {
9 | fetch(`${commentsPath}`, {
10 | method: "POST",
11 | headers: {"Content-type": "application/json; charset=UTF-8"},
12 | body: JSON.stringify({
13 | userId: parseInt(sessionStorage.getItem("userId")),
14 | id: "",
15 | postId: postId,
16 | name: sessionStorage.getItem("username"),
17 | body: body
18 | })
19 | })
20 | } catch (error) {
21 | console.error(error)
22 | }
23 | }
24 |
25 | async function editComment(id, edittedBody){
26 | try{
27 | fetch(`${commentsPath}/${id}`, {
28 | method: 'PATCH',
29 | headers: {"Content-type": "application/json; charset= UTF-8"},
30 | body: JSON.stringify({body: edittedBody})
31 | })
32 | } catch(error) {
33 | console.error(error)
34 | }
35 | }
36 |
37 | async function deleteComment(id){
38 | try{
39 | fetch(`${commentsPath}/${id}`, {
40 | method: 'DELETE',
41 | headers: {"Content-type": "application/json; charset= UTF-8"},
42 | });
43 |
44 | }catch(error){
45 | console.error(error)
46 | }
47 | }
48 |
49 | //Posts
50 |
51 | async function getPost(id){
52 | try {
53 | fetch(`${postsPath}/${id}`,{
54 | method:'GET'
55 | })
56 | const post = await response.json()
57 | return post
58 | } catch (error) {
59 | console.error(error)
60 | }
61 | }
62 |
63 | async function getPosts(){
64 | try {
65 | const response = await fetch(`${postsPath}`, {
66 | method: 'GET'
67 | })
68 | const posts = await response.json()
69 | return posts
70 | } catch (error) {
71 | console.error(error)
72 | }
73 | }
74 |
75 | async function getPostsCommentsQty (postId){
76 | try{
77 | const response = await fetch(`${commentsPath}/?postId=${postId}`, {
78 | method: 'GET'
79 | })
80 | const posts = await response.json()
81 | return posts.length
82 | } catch (error) {
83 | console.error(error)
84 | }
85 | }
86 |
87 | async function createPost(body){
88 | try {
89 | fetch(`${postsPath}`, {
90 | method: "POST",
91 | headers: {"Content-type": "application/json; charset=UTF-8"},
92 | body: JSON.stringify({
93 | userId: sessionStorage.getItem("userId"),
94 | id: "",
95 | username: sessionStorage.getItem("username"),
96 | body: body,
97 | commentsQty: 0
98 | })
99 | })
100 | } catch (error) {
101 | console.error(error)
102 | }
103 | }
104 |
105 | async function deletePost(id){
106 | try{
107 | fetch(`${postsPath}/${id}`, {
108 | method: 'DELETE',
109 | headers: {"Content-type": "application/json; charset= UTF-8"},
110 | });
111 |
112 | }catch(error){
113 | console.error(error)
114 | }
115 | }
116 |
117 | async function editPost(id, edittedBody){
118 | try{
119 | fetch(`${postsPath}/${id}`, {
120 | method: 'PATCH',
121 | headers: {"Content-type": "application/json; charset= UTF-8"},
122 | body: JSON.stringify({body: edittedBody})
123 | })
124 | } catch(error) {
125 | console.error(error)
126 | }
127 | }
128 |
129 | //Users
130 | async function getUser(id){
131 | try{
132 | const response = await fetch(`${usersPath}/${id}`, {
133 | method : 'GET'
134 | })
135 | const user = await response.json()
136 | return user
137 | } catch(error) {
138 | console.error(error)
139 | }
140 | }
141 |
142 | async function getUserName(name){
143 | try{
144 | const response = await fetch(`${usersPath}/?username=${name}`, {
145 | method : 'GET'
146 | })
147 | const user = await response.json()
148 | return user
149 | } catch(error) {
150 | console.error(error)
151 | }
152 | }
153 |
154 | async function getUsers(){
155 | try{
156 | const response = await fetch(`${usersPath}`, {
157 | method : 'GET'
158 | })
159 | const users = await response.json()
160 | return users
161 | } catch(error) {
162 | console.error(error)
163 | }
164 | }
165 |
166 | async function postUser(userId, userName, pokemonImg){
167 | try {
168 | await fetch(`${usersPath}`, {
169 | method: 'POST',
170 | headers: {
171 | "Content-type": "application/json; charset=UTF-8",
172 | },
173 | body: JSON.stringify({
174 | id: userId,
175 | username: `${userName}`,
176 | imgSrc: `${pokemonImg}`
177 | })
178 | })
179 | } catch (err) {
180 | console.error(err)
181 | }
182 | }
183 |
184 | export {createComment, editComment, deleteComment}
185 | export {getPost, getPosts, createPost, editPost, deletePost, getPostsCommentsQty}
186 | export {getUser, getUserName, getUsers, postUser}
--------------------------------------------------------------------------------
/src/js/login.js:
--------------------------------------------------------------------------------
1 | import {getUserName} from './api-communication.js'
2 |
3 | //Username & Email
4 | async function loginUser(username) {
5 |
6 | const registeredUsers = await getUserName(username)
7 |
8 | if(registeredUsers.length !== 0){
9 | sessionStorage.setItem('userId', registeredUsers[0].id)
10 | sessionStorage.setItem('username', registeredUsers[0].username)
11 | sessionStorage.setItem('avatarimg', registeredUsers[0].imgSrc)
12 |
13 | location.reload()
14 | }
15 | }
16 |
17 | export default loginUser
--------------------------------------------------------------------------------
/src/js/main.js:
--------------------------------------------------------------------------------
1 | /*IMPORTS*/
2 | import loginUser from "./login.js"
3 | import {createComment, editComment, deleteComment} from './api-communication.js'
4 | import {getPosts, createPost, editPost, deletePost} from './api-communication.js'
5 | import {createPostCard} from './post.js'
6 |
7 | /*VARIABLES*/
8 | const postsCont = document.getElementById('main__posts')
9 | const loginBtn = document.getElementById('loginButton')
10 | const saveComment = document.getElementById('editModal__save')
11 | const deleteCommentBtn = document.getElementById('deleteModalBtn');
12 | const createPostButton = document.getElementById('createPostButton');
13 |
14 | window.onload = async function (){
15 | if (!sessionStorage.getItem('userId')){
16 | defaultUser()
17 | }
18 | await displayPosts()
19 | getUserLoginImg()
20 | }
21 |
22 | //Default user
23 | const defaultUser = () => {
24 | sessionStorage.setItem('username', "pikachu")
25 | sessionStorage.setItem('userId', 25)
26 | sessionStorage.setItem('avatarimg', "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/25.png")
27 | }
28 |
29 | //Load userInfo from sessionStorage
30 | const getUserLoginImg = () =>{
31 | const userDiv = document.getElementById('dropdownMenuLink')
32 | const createPostAvatar = document.getElementById('createPostAvatar')
33 | userDiv.textContent = sessionStorage.getItem('username')
34 | createPostAvatar.src = sessionStorage.getItem('avatarimg')
35 | }
36 |
37 | //Create Post
38 | createPostButton.addEventListener('click', async () => {
39 | const textPost = document.getElementById('create-post__text').value;
40 | const response = await createPost(textPost)
41 | location.reload()
42 | })
43 |
44 | //Login
45 | loginBtn.addEventListener('click', () => {
46 | const userName = document.getElementById('login__Username');
47 | loginUser(userName.value)
48 | })
49 |
50 | //Show/hide post comments
51 | postsCont.addEventListener('click', (e) => {
52 |
53 | if (e.target.hasAttribute('data-hide-comments')){
54 | const postId = e.target.getAttribute('data-show-comments')
55 | e.target.removeAttribute('data-hide-comments')
56 | const postContainer =document.querySelector(`[data-post-comments="${postId}"]`)
57 | postContainer.remove()
58 |
59 | } else if (e.target.hasAttribute('data-show-comments')){
60 |
61 | e.target.setAttribute('data-hide-comments', '')
62 |
63 | const postId = e.target.getAttribute('data-show-comments')
64 | const postContainer = document.querySelector(`[data-post-id="${postId}"]`)
65 | const commentsContainer = document.createElement(`div`)
66 |
67 | commentsContainer.setAttribute(`data-post-comments`, postId )
68 | postContainer.append(commentsContainer)
69 |
70 | displayComments(postId, commentsContainer)
71 |
72 | // e.target.disabled = true
73 | }
74 | })
75 |
76 | //SaveComment
77 | saveComment.addEventListener('click', async () => {
78 | let newText = document.getElementById('editModal__text').value
79 | const saveAttrb = saveComment.getAttribute('data-edit')
80 | const id = saveComment.getAttribute('data-id')
81 |
82 | if(saveAttrb === 'post'){
83 | await editPost(id, newText)
84 | } else if (saveAttrb === 'comment'){
85 | await editComment(id, newText)
86 | }
87 |
88 | location.reload()
89 | newText = ''
90 | })
91 |
92 | deleteCommentBtn.addEventListener('click', async ()=> {
93 | const deleteAttrb = deleteCommentBtn.getAttribute('data-delete')
94 | const id = deleteCommentBtn.getAttribute('data-id')
95 | if(deleteAttrb === 'post'){
96 | await deletePost(id)
97 | } else if (deleteAttrb === 'comment'){
98 | await deleteComment(id)
99 | }
100 | location.reload()
101 | })
102 |
103 | async function displayPosts() {
104 | const postList = await getPosts()
105 | postList.map(post => {
106 | postsCont.append(createPostCard(post))
107 | })
108 | }
109 |
110 | const displayComments = async (postId, postContainer) => {
111 | fetch('http://localhost:3000/comments', {
112 | method: 'GET'
113 | })
114 | .then(response => response.json())
115 | .then(data => data.map(commentsData => {
116 |
117 | if (parseInt(postId) === commentsData.postId) {
118 | const comment = document.createElement('article')
119 | comment.setAttribute('class', 'comments__article')
120 | const name = document.createElement('span')
121 | const body = document.createElement('span');
122 | const avatarImage = document.createElement('img')
123 | avatarImage.src = `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/${commentsData.userId}.gif`
124 | avatarImage.classList.add('comment__avatar')
125 |
126 | const deleteButton = document.createElement('button');
127 | deleteButton.textContent = "DELETE";
128 | deleteButton.setAttribute('data-delete-comment', commentsData.id)
129 |
130 | const editButton = document.createElement('button');
131 | editButton.textContent = "EDIT";
132 | editButton.setAttribute('data-edit-comment', commentsData.id)
133 | editButton.setAttribute('data-bs-toggle', "modal")
134 | editButton.setAttribute('data-bs-target', "#editModal")
135 |
136 | editButton.addEventListener('click', () => {
137 | const saveComment = document.getElementById('editModal__save')
138 | saveComment.setAttribute("data-edit", "comment");
139 | saveComment.setAttribute('data-id', commentsData.id);
140 | })
141 |
142 | deleteButton.addEventListener('click', ()=>{
143 | const deleteComment = document.getElementById('deleteModalBtn')
144 | deleteComment.setAttribute('data-delete', "comment");
145 | deleteComment.setAttribute('data-id', commentsData.id);
146 | })
147 |
148 | comment.setAttribute('data-comment-id', commentsData.id)
149 | comment.setAttribute('data-post-id', commentsData.postId)
150 |
151 | name.classList.add('article__span--username');
152 | body.classList.add('article__span--comment');
153 | name.textContent = `@${commentsData.name}`
154 | body.textContent = commentsData.body
155 |
156 | comment.append(avatarImage, name, body)
157 |
158 | if (commentsData.userId === parseInt(sessionStorage.getItem("userId"))) {
159 | comment.append(editButton, deleteButton)
160 | }
161 |
162 | postContainer.append(comment)
163 | }
164 |
165 | }))
166 | .catch(err => console.warn(err))
167 | }
--------------------------------------------------------------------------------
/src/js/poke-api-communication.js:
--------------------------------------------------------------------------------
1 | import {postUser} from './api-communication.js'
2 | const url = `https://pokeapi.co/api/v2/pokemon`
3 |
4 | async function getPokemon(){
5 |
6 | try {
7 | for (let id = 16; id<=31; id++){
8 | const response = await fetch(`${url}/${id}`)
9 | const data = await response.json()
10 | postUser(id, data.name, data.sprites.front_default)
11 | }
12 | } catch(error) {
13 | console.error(error)
14 | }
15 |
16 | }
17 |
18 | export default getPokemon
--------------------------------------------------------------------------------
/src/js/post.js:
--------------------------------------------------------------------------------
1 | const avatarCard = params => {
2 | const avatar = document.createElement('div')
3 | const avatarImage = document.createElement('img')
4 | const avatarName = document.createElement('p')
5 |
6 | avatar.classList.add('avatar')
7 | avatarImage.classList.add('avatar__image')
8 | avatarName.classList.add('avatar__user')
9 |
10 | avatarImage.src = `${params.src}`
11 | avatarImage.alt = `${params.alt}`
12 | avatarName.textContent = `@${params.name}`
13 |
14 | avatar.append(avatarImage, avatarName)
15 |
16 | return avatar
17 | }
18 |
19 | const postStatusCard = (postId, commentQty) => {
20 | const comments = document.createElement('div')
21 | const commentsCounter = document.createElement('p')
22 | const commentsBtn = document.createElement('button')
23 | const createCommentBtn = document.createElement('p')
24 |
25 | createCommentBtn.setAttribute('data-create-comment', postId)
26 | createCommentBtn.classList.add('post__comment-create')
27 |
28 | //this next lines are going to be refactored
29 | createCommentBtn.addEventListener('click', ()=>{
30 | const idPost = createCommentButton.getAttribute('data-create-comment');
31 | const textPost = document.getElementById('create-post__text').value;
32 | createComment(textPost, parseInt(idPost))
33 | location.reload();
34 | })
35 | commentsCounter.textContent = commentQty
36 |
37 | comments.classList.add('post__comments-status')
38 | commentsCounter.classList.add('post__comments-counter')
39 | commentsBtn.classList.add('article__button--showComments')
40 | commentsBtn.setAttribute('data-show-comments', postId)
41 |
42 | comments.append(commentsBtn, commentsCounter, createCommentBtn)
43 |
44 | return comments
45 | }
46 |
47 | const modifyCard = postId => {
48 | const modifyCont = document.createElement('div')
49 | const editBtn = document.createElement('button')
50 | const deleteBtn = document.createElement('button')
51 |
52 | modifyCont.classList.add('post__modify-cont')
53 | editBtn.classList.add('post__edit-btn')
54 | editBtn.setAttribute('data-bs-toggle', "modal")
55 | editBtn.setAttribute('data-bs-target', "#editModal")
56 | deleteBtn.classList.add('post__delete-btn')
57 | deleteBtn.setAttribute('data-bs-toggle', "modal")
58 | deleteBtn.setAttribute('data-bs-target', "#deleteModal")
59 |
60 | editBtn.addEventListener('click', () => {
61 | const saveComment = document.getElementById('editModal__save')
62 | saveComment.setAttribute('data-edit', "post");
63 | saveComment.setAttribute('data-id', postId);
64 | })
65 | deleteBtn.addEventListener('click', ()=>{
66 | const deleteComment = document.getElementById('deleteModalBtn')
67 | deleteComment.setAttribute('data-delete', "post");
68 | deleteComment.setAttribute('data-id', postId);
69 | })
70 |
71 | modifyCont.append(editBtn, deleteBtn)
72 |
73 | return modifyCont
74 | }
75 |
76 | //params is post information {userId, id, username, body}
77 | function createPostCard (params){
78 | const content = document.createElement('article')
79 | const header = document.createElement('div')
80 | const text = document.createElement('p')
81 | const imgSrc = `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/${params.userId}.gif`
82 | const avatar = avatarCard({src: imgSrc, alt: params.username, name: params.username})
83 | const postDescription = postStatusCard(params.id, params.commentsQty)
84 | const modify = modifyCard(params.id)
85 | const activeUserId = sessionStorage.getItem('userId')
86 |
87 | text.innerText = params.body
88 |
89 | content.setAttribute('data-post-id', params.id)
90 | content.setAttribute('data-user-id', params.userId)
91 | content.classList.add('posts__article')
92 |
93 | text.classList.add('post__text')
94 | header.classList.add('post__header')
95 |
96 | if (params.userId === activeUserId){
97 | header.append(avatar, modify)
98 | } else {
99 | header.append(avatar)
100 | }
101 |
102 | content.append(header,text,postDescription)
103 |
104 | return content
105 | }
106 |
107 | export {createPostCard}
108 |
109 |
--------------------------------------------------------------------------------