diff --git a/backend/src/controllers/UserController.js b/backend/src/controllers/UserController.js index 771d2b2..0a88394 100644 --- a/backend/src/controllers/UserController.js +++ b/backend/src/controllers/UserController.js @@ -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) => { diff --git a/frontend/src/pages/Contacts/index.js b/frontend/src/pages/Contacts/index.js index e8a7b08..ab6bb4b 100644 --- a/frontend/src/pages/Contacts/index.js +++ b/frontend/src/pages/Contacts/index.js @@ -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") { diff --git a/frontend/src/pages/Users/index.js b/frontend/src/pages/Users/index.js index faa76c9..45c3476 100644 --- a/frontend/src/pages/Users/index.js +++ b/frontend/src/pages/Users/index.js @@ -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 ( { - +