Skip to content

Commit 00e37a2

Browse files
author
DEVfancybear
committed
react redux pagination server side
1 parent 86c0e4f commit 00e37a2

File tree

10 files changed

+14158
-73
lines changed

10 files changed

+14158
-73
lines changed

package-lock.json

Lines changed: 13918 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@
66
"@testing-library/jest-dom": "^4.2.4",
77
"@testing-library/react": "^9.3.2",
88
"@testing-library/user-event": "^7.1.2",
9+
"axios": "^0.19.2",
910
"react": "^16.13.1",
1011
"react-dom": "^16.13.1",
11-
"react-scripts": "3.4.1"
12+
"react-redux": "^7.2.0",
13+
"react-scripts": "3.4.1",
14+
"redux": "^4.0.5",
15+
"redux-devtools-extension": "^2.13.8",
16+
"redux-thunk": "^2.3.0"
1217
},
1318
"scripts": {
14-
"start": "react-scripts start",
19+
"start": "PORT=2001 react-scripts start",
1520
"build": "react-scripts build",
1621
"test": "react-scripts test",
1722
"eject": "react-scripts eject"

src/App.css

Lines changed: 0 additions & 38 deletions
This file was deleted.

src/App.js

Lines changed: 96 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,98 @@
1-
import React from 'react';
2-
import logo from './logo.svg';
3-
import './App.css';
4-
5-
function App() {
6-
return (
7-
<div className="App">
8-
<header className="App-header">
9-
<img src={logo} className="App-logo" alt="logo" />
10-
<p>
11-
Edit <code>src/App.js</code> and save to reload.
12-
</p>
13-
<a
14-
className="App-link"
15-
href="https://reactjs.org"
16-
target="_blank"
17-
rel="noopener noreferrer"
18-
>
19-
Learn React
20-
</a>
21-
</header>
22-
</div>
23-
);
1+
import React, { Component } from "react";
2+
import styles from "./App.module.css";
3+
import { connect } from "react-redux";
4+
import { makeHttpRequestWithPage } from "./actions/index";
5+
class App extends Component {
6+
componentDidMount() {
7+
this.props.makeHttpRequestWithPage(1);
8+
}
9+
10+
render() {
11+
let users, renderPageNumbers;
12+
13+
if (this.props.data.users !== null) {
14+
users = this.props.data.users.map(user => (
15+
<tr key={user.id}>
16+
<td>{user.id}</td>
17+
<td>{user.first_name}</td>
18+
<td>{user.last_name}</td>
19+
</tr>
20+
));
21+
}
22+
23+
const pageNumbers = [];
24+
if (this.props.data.total !== null) {
25+
for (
26+
let i = 1;
27+
i <= Math.ceil(this.props.data.total / this.props.data.per_page);
28+
i++
29+
) {
30+
pageNumbers.push(i);
31+
}
32+
33+
renderPageNumbers = pageNumbers.map(number => {
34+
let classes =
35+
this.props.data.current_page === number ? styles.active : "";
36+
37+
if (
38+
number === 1 ||
39+
number === this.props.data.total ||
40+
(number >= this.props.data.current_page - 2 &&
41+
number <= this.props.data.current_page + 2)
42+
) {
43+
return (
44+
<span
45+
key={number}
46+
className={classes}
47+
onClick={() => this.props.makeHttpRequestWithPage(number)}
48+
>
49+
{number}
50+
</span>
51+
);
52+
}
53+
});
54+
}
55+
56+
return (
57+
<div className={styles.app}>
58+
<table className={styles.table}>
59+
<thead>
60+
<tr>
61+
<th>S/N</th>
62+
<th>First Name</th>
63+
<th>Last Name</th>
64+
</tr>
65+
</thead>
66+
<tbody>{users}</tbody>
67+
</table>
68+
69+
<div className={styles.pagination}>
70+
<div className={styles.pagination}>
71+
<span onClick={() => this.props.makeHttpRequestWithPage(1)}>
72+
&laquo;
73+
</span>
74+
{renderPageNumbers}
75+
<span onClick={() => this.props.makeHttpRequestWithPage(1)}>
76+
&raquo;
77+
</span>
78+
</div>
79+
</div>
80+
</div>
81+
);
82+
}
2483
}
2584

26-
export default App;
85+
const mapStateToProps = state => {
86+
return {
87+
data: state.rootReducers
88+
};
89+
};
90+
const mapDispatchToProps = (dispatch, props) => {
91+
return {
92+
makeHttpRequestWithPage: pageNumber => {
93+
dispatch(makeHttpRequestWithPage(pageNumber));
94+
}
95+
};
96+
};
97+
98+
export default connect(mapStateToProps, mapDispatchToProps)(App);

src/App.module.css

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
.app {
2+
width: 50%;
3+
margin: 0 auto;
4+
}
5+
6+
table {
7+
border-collapse: collapse;
8+
border-spacing: 0;
9+
}
10+
11+
table {
12+
border-collapse: separate;
13+
border-spacing: 0;
14+
color: #4a4a4d;
15+
font: 14px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif;
16+
width: 100%;
17+
}
18+
tr {
19+
overflow-x: scroll;
20+
}
21+
th,
22+
td {
23+
padding: 15px 15px;
24+
vertical-align: middle;
25+
/* text-align: left; */
26+
}
27+
thead {
28+
font-size: 14px;
29+
line-height: 24px;
30+
font-family: Lato;
31+
border: 1px solid transparent;
32+
33+
max-width: 100%;
34+
font-weight: 900;
35+
line-height: 24px;
36+
mix-blend-mode: normal;
37+
38+
color: rgba(51, 51, 51, 0.5);
39+
background: rgba(255, 255, 255, 0.9);
40+
}
41+
thead tr th {
42+
padding: 15px 15px;
43+
border: 1px solid transparent;
44+
45+
text-align: left;
46+
}
47+
tbody {
48+
max-width: 100%;
49+
}
50+
tbody tr:nth-child(odd) {
51+
background: #f0f0f2;
52+
}
53+
tbody tr:hover {
54+
background: #f0f0f2;
55+
}
56+
td {
57+
padding: 15px 15px;
58+
}
59+
td:first-child {
60+
}
61+
62+
.pagination {
63+
margin-top: 25px;
64+
}
65+
.pagination span {
66+
cursor: pointer;
67+
color: black;
68+
float: left;
69+
padding: 8px 16px;
70+
text-decoration: none;
71+
transition: background-color 0.3s;
72+
border: 1px solid #ddd;
73+
}
74+
75+
.pagination span.active {
76+
background-color: #0099ff;
77+
color: white;
78+
border: 1px solid #0099ff;
79+
}

src/actions/index.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import * as types from "../constants/ActionTypes";
2+
import axios from "axios";
3+
export const makeHttpRequestWithPage = pageNumber => {
4+
return async dispatch => {
5+
const response = await axios.get(
6+
`https://reqres.in/api/users?page=${pageNumber}`
7+
);
8+
9+
const data = await response.data;
10+
dispatch({
11+
type: types.FETCH_DATA,
12+
payload: data
13+
});
14+
};
15+
};

src/constants/ActionTypes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const FETCH_DATA = "FETCH_DATA";

src/index.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
1-
import React from 'react';
2-
import ReactDOM from 'react-dom';
3-
import './index.css';
4-
import App from './App';
5-
import * as serviceWorker from './serviceWorker';
6-
1+
import React from "react";
2+
import ReactDOM from "react-dom";
3+
import "./index.css";
4+
import App from "./App";
5+
import * as serviceWorker from "./serviceWorker";
6+
import { createStore, applyMiddleware } from "redux";
7+
import rootReducer from "./reducers/index";
8+
import { Provider } from "react-redux";
9+
import { composeWithDevTools } from "redux-devtools-extension";
10+
import thunk from "redux-thunk";
11+
const store = createStore(
12+
rootReducer,
13+
composeWithDevTools(applyMiddleware(thunk))
14+
);
715
ReactDOM.render(
8-
<React.StrictMode>
16+
<Provider store={store}>
917
<App />
10-
</React.StrictMode>,
11-
document.getElementById('root')
18+
</Provider>,
19+
document.getElementById("root")
1220
);
1321

1422
// If you want your app to work offline and load faster, you can change

src/reducers/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { combineReducers } from "redux";
2+
import rootReducers from "./rootReducers";
3+
export default combineReducers({ rootReducers });

src/reducers/rootReducers.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import * as types from "../constants/ActionTypes";
2+
const initialState = {
3+
users: [],
4+
total: null,
5+
per_page: null,
6+
current_page: 1
7+
};
8+
export default (state = initialState, action) => {
9+
switch (action.type) {
10+
case types.FETCH_DATA:
11+
console.log(action.payload)
12+
return {
13+
...state,
14+
users: action.payload.data,
15+
total: action.payload.total,
16+
per_page: action.payload.per_page,
17+
current_page: action.payload.page
18+
};
19+
default:
20+
return state;
21+
}
22+
};

0 commit comments

Comments
 (0)