Skip to content

Commit 3424340

Browse files
author
Yauhen
committed
Lesson 17: Work with API. Part II
1 parent 901873c commit 3424340

File tree

13 files changed

+454
-1
lines changed

13 files changed

+454
-1
lines changed

src/17_api/components/input/input.css

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
.inputWrapper {
2+
position: relative;
3+
border-bottom: 1px solid #ededed;
4+
flex: 1 0 100%;
5+
}
6+
7+
.input {
8+
font-family: 'Indie Flower', cursive;
9+
padding: 16px 16px 16px 60px;
10+
border: none;
11+
background: rgba(0, 0, 0, 0.003);
12+
width: 100%;
13+
box-sizing: border-box;
14+
font-size: 28px;
15+
font-style: italic;
16+
box-shadow: inset 0 -2px 40px rgba(0,0,0,0.03);
17+
}
18+
19+
.fa-search {
20+
position: absolute;
21+
font-size: 24px;
22+
top: 50%;
23+
transform: translateY(-50%);
24+
left: 20px;
25+
}
26+
27+
.input::-webkit-input-placeholder {
28+
font-family: 'Indie Flower', cursive;
29+
}
30+
.input::-moz-placeholder {
31+
font-family: 'Indie Flower', cursive;
32+
}
33+
.input:-moz-placeholder {
34+
font-family: 'Indie Flower', cursive;
35+
}
36+
.input:-ms-input-placeholder {
37+
font-family: 'Indie Flower', cursive;
38+
}

src/17_api/components/input/input.jsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
import './input.css';
5+
6+
const Input = ({ onChange, value, onKeyPress }) => (
7+
<div className="inputWrapper">
8+
<i className="fas fa-search" />
9+
<input
10+
className="input"
11+
placeholder="Click to search"
12+
onChange={onChange}
13+
onKeyPress={onKeyPress}
14+
value={value}
15+
/>
16+
</div>
17+
);
18+
19+
Input.propTypes = {
20+
onChange: PropTypes.func,
21+
onKeyPress: PropTypes.func,
22+
value: PropTypes.string,
23+
}
24+
25+
Input.defaultProps = {
26+
onChange: () => {},
27+
onKeyPress: () => {},
28+
value: ''
29+
}
30+
31+
export default Input;

src/17_api/components/news/news.css

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
.newsList {
2+
margin: 0;
3+
padding: 0;
4+
list-style-type: none;
5+
flex: 1 0 100%;
6+
}
7+
8+
.news {
9+
margin: 10px 0;
10+
padding: 20px 30px;
11+
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
12+
0 25px 50px 0 rgba(0, 0, 0, 0.1);
13+
}
14+
15+
.newsTitle {
16+
display: block;
17+
margin-bottom: 10px;
18+
}
19+
20+
.description span {
21+
padding: 0 10px;
22+
}
23+
24+
.description .text {
25+
padding-left: 0;
26+
}
27+
28+
.description span:not(:last-child) {
29+
border-right: 1px solid #000;
30+
}

src/17_api/components/news/news.jsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
import './news.css';
5+
6+
const NewsPost = ({ author, created_at, num_comments, title, points, url }) => (
7+
<li className="news">
8+
<div className="description">
9+
<a href={url} className="newsTitle">{title}</a>
10+
<span className="text">{`${points} points`}</span>
11+
<span className="comments">{`${num_comments} comments`}</span>
12+
<span className="date">{new Date(created_at).toLocaleDateString()}</span>
13+
<span className="author">{author}</span>
14+
</div>
15+
</li>
16+
);
17+
18+
NewsPost.propTypes = {
19+
author: PropTypes.string,
20+
created_at: PropTypes.string.isRequired,
21+
num_comments: PropTypes.number,
22+
title: PropTypes.string,
23+
points: PropTypes.number,
24+
url: PropTypes.string,
25+
}
26+
27+
NewsPost.defaultProps = {
28+
author: '',
29+
num_comments: 0,
30+
title: 'Here should be a title',
31+
points: 0,
32+
url: '#'
33+
}
34+
35+
export default NewsPost;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.paginationWrapper {
2+
margin-bottom: 20px;
3+
display: inline-block;
4+
padding: 20px 40px;
5+
background-color: #fff;
6+
font-weight: 700;
7+
}
8+
9+
.paginationWrapper button {
10+
font-weight: 700;
11+
background-color: transparent;
12+
padding: 5px 10px;
13+
border: 1px solid #e7e7e7;
14+
cursor: pointer;
15+
outline: none;
16+
}
17+
18+
.paginationWrapper button.active {
19+
background-color: rgba(175, 47, 47, 0.15);
20+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
import './pagination.css';
5+
6+
const renderPaginationBtns = (onClick, page, lastPage) => {
7+
const startBtns = [page, page + 1, page + 2];
8+
const gapBtns = [page - 2, page - 1, page];
9+
const middleBtn = [ '...' ];
10+
const lastBtns = [lastPage - 3, lastPage - 2, lastPage - 1];
11+
12+
let btnsArr = [];
13+
14+
if (page < lastPage - 6) {
15+
btnsArr = [...startBtns, ...middleBtn, ...lastBtns]
16+
} else if (page < lastPage - 4) {
17+
btnsArr = [...gapBtns, ...middleBtn, ...lastBtns]
18+
} else if (page < lastPage - 3) {
19+
btnsArr = [...gapBtns, ...lastBtns] // last 6 pages
20+
} else {
21+
btnsArr = [...middleBtn, ...lastBtns] // last 3 pages
22+
}
23+
24+
return btnsArr.map(num => {
25+
return num === '...' ?
26+
num :
27+
<button
28+
key={num}
29+
onClick={onClick}
30+
data-name={num}
31+
className={num === page ? 'active' : ''}
32+
>{num}</button>
33+
});
34+
};
35+
36+
const Pagination = ({ onClick, page, lastPage }) => (
37+
<div className="paginationWrapper">
38+
{ page !== 0 && <button onClick={onClick} data-name="prev">{'<<'}</button> }
39+
{renderPaginationBtns(onClick, page, lastPage)}
40+
{ page !== lastPage - 1 && <button onClick={onClick} data-name="next">{'>>'}</button> }
41+
</div>
42+
);
43+
44+
Pagination.propTypes = {
45+
onClick: PropTypes.func,
46+
page: PropTypes.number,
47+
lastPage: PropTypes.number,
48+
}
49+
50+
Pagination.defaultProps = {
51+
onClick: () => {},
52+
page: 0,
53+
lastPage: 0,
54+
}
55+
56+
export default Pagination;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.selectWrapper {
2+
margin-bottom: 20px;
3+
display: inline-block;
4+
padding: 20px 40px;
5+
background-color: #fff;
6+
}
7+
8+
.selectWrapper,
9+
.selectWrapper select {
10+
font-size: 20px;
11+
}
12+
13+
.selectText {
14+
margin-left: 10px;
15+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
import './select.css';
5+
6+
const Input = ({ handleChange, options, value }) => (
7+
<div className="selectWrapper">
8+
<select onChange={handleChange} value={value}>
9+
{options.map(({ value, label }) =>
10+
<option key={value} value={value}>{label}</option>
11+
)}
12+
</select>
13+
<span className="selectText">per page</span>
14+
</div>
15+
);
16+
17+
Input.propTypes = {
18+
handleChange: PropTypes.func,
19+
options: PropTypes.array,
20+
value: PropTypes.number,
21+
}
22+
23+
Input.defaultProps = {
24+
onChange: () => {},
25+
options: [],
26+
value: 0,
27+
}
28+
29+
export default Input;

src/17_api/components/title/title.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.title {
2+
font-family: 'Permanent Marker', cursive;
3+
font-size: 80px;
4+
text-align: center;
5+
font-weight: 900;
6+
color: rgba(175, 47, 47, 0.15);
7+
margin-bottom: 20px;
8+
}

src/17_api/components/title/title.jsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
import './title.css';
5+
6+
const Title = ({ title }) => (
7+
<h1 className="title">{title}</h1>
8+
);
9+
10+
Title.propTypes = {
11+
title: PropTypes.string,
12+
}
13+
14+
Title.defaultProps = {
15+
title: 'Simple title',
16+
}
17+
18+
export default Title;

src/17_api/containers/news/news.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.wrapper {
2+
padding: 0 20px;
3+
position: relative;
4+
display: flex;
5+
flex-wrap: wrap;
6+
justify-content: space-between;
7+
}

0 commit comments

Comments
 (0)