Skip to content

Commit

Permalink
react redux pagination server side
Browse files Browse the repository at this point in the history
  • Loading branch information
DEVfancybear committed Mar 24, 2020
1 parent 86c0e4f commit 00e37a2
Show file tree
Hide file tree
Showing 10 changed files with 14,158 additions and 73 deletions.
13,918 changes: 13,918 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"axios": "^0.19.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1"
"react-redux": "^7.2.0",
"react-scripts": "3.4.1",
"redux": "^4.0.5",
"redux-devtools-extension": "^2.13.8",
"redux-thunk": "^2.3.0"
},
"scripts": {
"start": "react-scripts start",
"start": "PORT=2001 react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
Expand Down
38 changes: 0 additions & 38 deletions src/App.css

This file was deleted.

120 changes: 96 additions & 24 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,98 @@
import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
import React, { Component } from "react";
import styles from "./App.module.css";
import { connect } from "react-redux";
import { makeHttpRequestWithPage } from "./actions/index";
class App extends Component {
componentDidMount() {
this.props.makeHttpRequestWithPage(1);
}

render() {
let users, renderPageNumbers;

if (this.props.data.users !== null) {
users = this.props.data.users.map(user => (
<tr key={user.id}>
<td>{user.id}</td>
<td>{user.first_name}</td>
<td>{user.last_name}</td>
</tr>
));
}

const pageNumbers = [];
if (this.props.data.total !== null) {
for (
let i = 1;
i <= Math.ceil(this.props.data.total / this.props.data.per_page);
i++
) {
pageNumbers.push(i);
}

renderPageNumbers = pageNumbers.map(number => {
let classes =
this.props.data.current_page === number ? styles.active : "";

if (
number === 1 ||
number === this.props.data.total ||
(number >= this.props.data.current_page - 2 &&
number <= this.props.data.current_page + 2)
) {
return (
<span
key={number}
className={classes}
onClick={() => this.props.makeHttpRequestWithPage(number)}
>
{number}
</span>
);
}
});
}

return (
<div className={styles.app}>
<table className={styles.table}>
<thead>
<tr>
<th>S/N</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
</thead>
<tbody>{users}</tbody>
</table>

<div className={styles.pagination}>
<div className={styles.pagination}>
<span onClick={() => this.props.makeHttpRequestWithPage(1)}>
&laquo;
</span>
{renderPageNumbers}
<span onClick={() => this.props.makeHttpRequestWithPage(1)}>
&raquo;
</span>
</div>
</div>
</div>
);
}
}

export default App;
const mapStateToProps = state => {
return {
data: state.rootReducers
};
};
const mapDispatchToProps = (dispatch, props) => {
return {
makeHttpRequestWithPage: pageNumber => {
dispatch(makeHttpRequestWithPage(pageNumber));
}
};
};

export default connect(mapStateToProps, mapDispatchToProps)(App);
79 changes: 79 additions & 0 deletions src/App.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
.app {
width: 50%;
margin: 0 auto;
}

table {
border-collapse: collapse;
border-spacing: 0;
}

table {
border-collapse: separate;
border-spacing: 0;
color: #4a4a4d;
font: 14px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 100%;
}
tr {
overflow-x: scroll;
}
th,
td {
padding: 15px 15px;
vertical-align: middle;
/* text-align: left; */
}
thead {
font-size: 14px;
line-height: 24px;
font-family: Lato;
border: 1px solid transparent;

max-width: 100%;
font-weight: 900;
line-height: 24px;
mix-blend-mode: normal;

color: rgba(51, 51, 51, 0.5);
background: rgba(255, 255, 255, 0.9);
}
thead tr th {
padding: 15px 15px;
border: 1px solid transparent;

text-align: left;
}
tbody {
max-width: 100%;
}
tbody tr:nth-child(odd) {
background: #f0f0f2;
}
tbody tr:hover {
background: #f0f0f2;
}
td {
padding: 15px 15px;
}
td:first-child {
}

.pagination {
margin-top: 25px;
}
.pagination span {
cursor: pointer;
color: black;
float: left;
padding: 8px 16px;
text-decoration: none;
transition: background-color 0.3s;
border: 1px solid #ddd;
}

.pagination span.active {
background-color: #0099ff;
color: white;
border: 1px solid #0099ff;
}
15 changes: 15 additions & 0 deletions src/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as types from "../constants/ActionTypes";
import axios from "axios";
export const makeHttpRequestWithPage = pageNumber => {
return async dispatch => {
const response = await axios.get(
`https://reqres.in/api/users?page=${pageNumber}`
);

const data = await response.data;
dispatch({
type: types.FETCH_DATA,
payload: data
});
};
};
1 change: 1 addition & 0 deletions src/constants/ActionTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const FETCH_DATA = "FETCH_DATA";
26 changes: 17 additions & 9 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { createStore, applyMiddleware } from "redux";
import rootReducer from "./reducers/index";
import { Provider } from "react-redux";
import { composeWithDevTools } from "redux-devtools-extension";
import thunk from "redux-thunk";
const store = createStore(
rootReducer,
composeWithDevTools(applyMiddleware(thunk))
);
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</React.StrictMode>,
document.getElementById('root')
</Provider>,
document.getElementById("root")
);

// If you want your app to work offline and load faster, you can change
Expand Down
3 changes: 3 additions & 0 deletions src/reducers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { combineReducers } from "redux";
import rootReducers from "./rootReducers";
export default combineReducers({ rootReducers });
22 changes: 22 additions & 0 deletions src/reducers/rootReducers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as types from "../constants/ActionTypes";
const initialState = {
users: [],
total: null,
per_page: null,
current_page: 1
};
export default (state = initialState, action) => {
switch (action.type) {
case types.FETCH_DATA:
console.log(action.payload)
return {
...state,
users: action.payload.data,
total: action.payload.total,
per_page: action.payload.per_page,
current_page: action.payload.page
};
default:
return state;
}
};

0 comments on commit 00e37a2

Please sign in to comment.