improvement: adopted infinity scroll in users and contacts

This commit is contained in:
canove
2020-09-03 17:43:04 -03:00
parent dfde175c07
commit 514f1c3b75
3 changed files with 75 additions and 44 deletions

View File

@@ -7,7 +7,7 @@ const User = require("../models/User");
const { getIO } = require("../libs/socket");
exports.index = async (req, res) => {
const { searchParam = "", pageNumber = 1, rowsPerPage = 10 } = req.query;
const { searchParam = "", pageNumber = 1 } = req.query;
const whereCondition = {
[Op.or]: [
@@ -22,7 +22,7 @@ exports.index = async (req, res) => {
],
};
let limit = +rowsPerPage;
let limit = 20;
let offset = limit * (pageNumber - 1);
const { count, rows: users } = await User.findAndCountAll({
@@ -33,7 +33,9 @@ exports.index = async (req, res) => {
order: [["createdAt", "DESC"]],
});
return res.status(200).json({ users, count });
const hasMore = count > offset + users.length;
return res.status(200).json({ users, count, hasMore });
};
exports.store = async (req, res, next) => {

View File

@@ -47,25 +47,22 @@ const reducer = (state, action) => {
return [...state, ...newContacts];
}
if (action.type === "UPDATE_CONTACT") {
const updatedContact = action.payload;
const contactIndex = state.findIndex(c => c.id === updatedContact.id);
if (action.type === "UPDATE_CONTACTS") {
const contact = action.payload;
const contactIndex = state.findIndex(c => c.id === contact.id);
if (contactIndex !== -1) {
state[contactIndex] = updatedContact;
state[contactIndex] = contact;
}
return [...state];
return [contact, ...state];
}
if (action.type === "DELETE_CONTACT") {
const contactId = action.payload;
console.log("cai aqui", contactId);
const contactIndex = state.findIndex(c => c.id === contactId);
if (contactIndex !== -1) {
console.log("cai no if");
state.splice(contactIndex, 1);
}
return [...state];
@@ -119,7 +116,7 @@ const Contacts = () => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
socket.on("contact", data => {
if (data.action === "update" || data.action === "create") {
dispatch({ type: "UPDATE_CONTACT", payload: data.contact });
dispatch({ type: "UPDATE_CONTACTS", payload: data.contact });
}
if (data.action === "delete") {

View File

@@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useReducer } from "react";
import openSocket from "socket.io-client";
@@ -28,6 +28,45 @@ import TableRowSkeleton from "../../components/TableRowSkeleton";
import UserModal from "../../components/UserModal";
import ConfirmationModal from "../../components/ConfirmationModal";
const reducer = (state, action) => {
if (action.type === "LOAD_USERS") {
const users = action.payload;
const newUsers = [];
users.forEach(user => {
const userIndex = state.findIndex(u => u.id === user.id);
if (userIndex !== -1) {
state[userIndex] = user;
} else {
newUsers.push(user);
}
});
return [...state, ...newUsers];
}
if (action.type === "UPDATE_USERS") {
const user = action.payload;
const userIndex = state.findIndex(u => u.id === user.id);
if (userIndex !== -1) {
state[userIndex] = user;
}
return [user, ...state];
}
if (action.type === "DELETE_USER") {
const userId = action.payload;
const userIndex = state.findIndex(u => u.id === userId);
if (userIndex !== -1) {
state.splice(userIndex, 1);
}
return [...state];
}
};
const useStyles = makeStyles(theme => ({
mainPaper: {
flex: 1,
@@ -42,22 +81,24 @@ const Users = () => {
const [loading, setLoading] = useState(false);
const [pageNumber, setPageNumber] = useState(1);
const [hasMore, setHasMore] = useState(false);
const [selectedUserId, setSelectedUserId] = useState(null);
const [userModalOpen, setUserModalOpen] = useState(false);
const [confirmModalOpen, setConfirmModalOpen] = useState(false);
const [deletingUser, setDeletingUser] = useState(null);
const [searchParam, setSearchParam] = useState("");
const [users, setUsers] = useState([]);
const [users, dispatch] = useReducer(reducer, []);
useEffect(() => {
setLoading(true);
const delayDebounceFn = setTimeout(() => {
const fetchUsers = async () => {
try {
const res = await api.get("/users/", {
const { data } = await api.get("/users/", {
params: { searchParam, pageNumber },
});
setUsers(res.data.users);
dispatch({ type: "LOAD_USERS", payload: data.users });
setHasMore(data.hasMore);
setLoading(false);
} catch (err) {
console.log(err);
@@ -73,11 +114,11 @@ const Users = () => {
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
socket.on("user", data => {
if (data.action === "update" || data.action === "create") {
updateUsers(data.user);
dispatch({ type: "UPDATE_USERS", payload: data.user });
}
if (data.action === "delete") {
deleteUser(data.userId);
dispatch({ type: "DELETE_USER", payload: +data.userId });
}
});
@@ -86,31 +127,6 @@ const Users = () => {
};
}, []);
const updateUsers = user => {
setUsers(prevState => {
const userIndex = prevState.findIndex(c => c.id === user.id);
if (userIndex === -1) {
return [user, ...prevState];
}
const aux = [...prevState];
aux[userIndex] = user;
return aux;
});
};
const deleteUser = userId => {
setUsers(prevState => {
const userIndex = prevState.findIndex(c => c.id === +userId);
if (userIndex === -1) return prevState;
const aux = [...prevState];
aux.splice(userIndex, 1);
return aux;
});
};
const handleOpenUserModal = () => {
setSelectedUserId(null);
setUserModalOpen(true);
@@ -141,6 +157,18 @@ const Users = () => {
setPageNumber(1);
};
const loadMore = () => {
setPageNumber(prevState => prevState + 1);
};
const handleScroll = e => {
if (!hasMore || loading) return;
const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
if (scrollHeight - (scrollTop + 100) < clientHeight) {
loadMore();
}
};
return (
<MainContainer>
<ConfirmationModal
@@ -182,7 +210,11 @@ const Users = () => {
</Button>
</MainHeaderButtonsWrapper>
</MainHeader>
<Paper className={classes.mainPaper} variant="outlined">
<Paper
className={classes.mainPaper}
variant="outlined"
onScroll={handleScroll}
>
<Table size="small">
<TableHead>
<TableRow>