diff --git a/frontend/src/api/userService.tsx b/frontend/src/api/userService.tsx index 0eb01622d..8ec3e3b1d 100644 --- a/frontend/src/api/userService.tsx +++ b/frontend/src/api/userService.tsx @@ -7,8 +7,10 @@ export const getAllUsers = (context?: GetServerSidePropsContext): Promise => fetchData(`/users/teams`, { context, serverSide: !!context }); +): Promise<{ userWithTeams: UserWithTeams[]; hasNextPage: boolean; page: number }> => + fetchData(`/users/teams?page=${pageParam ?? 0}`, { context, serverSide: !!context }); export const updateUserIsAdminRequest = (user: UpdateUserIsAdmin): Promise => fetchData(`/users/sadmin/`, { method: 'PUT', data: user }); diff --git a/frontend/src/components/Users/UsersList/index.tsx b/frontend/src/components/Users/UsersList/index.tsx index 547c4d2ca..260051dcd 100644 --- a/frontend/src/components/Users/UsersList/index.tsx +++ b/frontend/src/components/Users/UsersList/index.tsx @@ -2,10 +2,6 @@ import React from 'react'; import ListOfCards from './partials/ListOfCards'; -type UsersWithTeamsProps = { - isFetching: boolean; -}; - -const TeamsList = ({ isFetching }: UsersWithTeamsProps) => ; +const TeamsList = () => ; export default TeamsList; diff --git a/frontend/src/components/Users/UsersList/partials/ListOfCards/index.tsx b/frontend/src/components/Users/UsersList/partials/ListOfCards/index.tsx index cd5cccb81..4364a29c3 100644 --- a/frontend/src/components/Users/UsersList/partials/ListOfCards/index.tsx +++ b/frontend/src/components/Users/UsersList/partials/ListOfCards/index.tsx @@ -1,34 +1,90 @@ -import React from 'react'; +import React, { useMemo, useRef } from 'react'; import { DotsLoading } from '@/components/loadings/DotsLoading'; import Flex from '@/components/Primitives/Flex'; import { UserWithTeams } from '@/types/user/user'; import Text from '@/components/Primitives/Text'; import SearchInput from '@/components/Teams/CreateTeam/ListMembers/SearchInput'; -import { useRecoilValue } from 'recoil'; -import { usersWithTeamsState } from '@/store/user/atoms/user.atom'; +import { useSetRecoilState } from 'recoil'; +// import { usersWithTeamsState } from '@/store/user/atoms/user.atom'; +import { useInfiniteQuery } from 'react-query'; +import { getAllUsersWithTeams } from '@/api/userService'; +import { ToastStateEnum } from '@/utils/enums/toast-types'; +import { toastState } from '@/store/toast/atom/toast.atom'; import { ScrollableContent } from '../../../../Boards/MyBoards/styles'; import CardBody from '../CardUser/CardBody'; -type ListOfCardsProp = { - isLoading: boolean; -}; +const ListOfCards = React.memo(() => { + const setToastState = useSetRecoilState(toastState); + // const setUsersWithTeamsState = useSetRecoilState(usersWithTeamsState); + const scrollRef = useRef(null); + + const fetchUsers = useInfiniteQuery( + 'usersWithTeams', + ({ pageParam = 0 }) => getAllUsersWithTeams(pageParam), + { + enabled: true, + refetchOnWindowFocus: false, + getNextPageParam: (lastPage) => { + const { hasNextPage, page } = lastPage; + if (hasNextPage) return page + 1; + return undefined; + }, + onError: () => { + setToastState({ + open: true, + content: 'Error getting the users', + type: ToastStateEnum.ERROR, + }); + }, + }, + ); + + const { data, isLoading } = fetchUsers; + + // if (data) { + // setUsersWithTeamsState(data?.pages[0].userWithTeams); + // } + + const users = useMemo(() => { + const usersArray: UserWithTeams[] = []; + data?.pages.forEach((page) => { + page.userWithTeams?.forEach((user) => { + usersArray.push(user); + }); + }); + return usersArray; + }, [data?.pages]); + + const onScroll = () => { + if (scrollRef.current) { + const { scrollTop, scrollHeight, clientHeight } = scrollRef.current; + if (scrollTop + clientHeight + 2 >= scrollHeight && fetchUsers.hasNextPage) { + fetchUsers.fetchNextPage(); + } + } + }; -const ListOfCards = React.memo(({ isLoading }) => { - const usersWithTeams = useRecoilValue(usersWithTeamsState); return ( <> - {usersWithTeams.length} registered users + {users.length} registered users - + - {usersWithTeams?.map((user: UserWithTeams) => ( + {users.map((user: UserWithTeams) => ( ))} diff --git a/frontend/src/hooks/useUser.tsx b/frontend/src/hooks/useUser.tsx index 12cf21142..a1f85976b 100644 --- a/frontend/src/hooks/useUser.tsx +++ b/frontend/src/hooks/useUser.tsx @@ -17,7 +17,7 @@ import { updateUserIsAdminRequest } from '../api/userService'; import useUserUtils from './useUserUtils'; const useUser = (): UseUserType => { - const { setToastState, usersWithTeamsList, setUsersWithTeamsList, queryClient } = useUserUtils(); + const { setToastState, queryClient } = useUserUtils(); const resetToken = useMutation( (emailUser: EmailUser) => resetTokenEmail(emailUser), @@ -43,15 +43,15 @@ const useUser = (): UseUserType => { }; const updateUserIsAdmin = useMutation(updateUserIsAdminRequest, { - onSuccess: (data) => { + onSuccess: () => { queryClient.invalidateQueries('usersWithTeams'); - // updates the usersList recoil - const users = usersWithTeamsList.map((user) => - user.user._id === data._id ? { ...user, isAdmin: data.isSAdmin } : user, - ); + // // updates the usersList recoil + // const users = usersWithTeamsList.map((user) => + // user.user._id === data._id ? { ...user, isAdmin: data.isSAdmin } : user, + // ); - setUsersWithTeamsList(users); + // setUsersWithTeamsList(users); setToastState({ open: true, diff --git a/frontend/src/pages/users/index.tsx b/frontend/src/pages/users/index.tsx index 805aaea6c..3fd485cb8 100644 --- a/frontend/src/pages/users/index.tsx +++ b/frontend/src/pages/users/index.tsx @@ -1,47 +1,22 @@ import { ReactElement, Suspense } from 'react'; -import { dehydrate, QueryClient, useQuery } from 'react-query'; -import { GetServerSideProps, GetServerSidePropsContext } from 'next'; import { useSession } from 'next-auth/react'; -import { useSetRecoilState } from 'recoil'; import QueryError from '@/components/Errors/QueryError'; import Layout from '@/components/layouts/Layout'; import LoadingPage from '@/components/loadings/LoadingPage'; import Flex from '@/components/Primitives/Flex'; import UsersList from '@/components/Users/UsersList'; -import { getAllUsersWithTeams } from '../../api/userService'; -import requireAuthentication from '../../components/HOC/requireAuthentication'; -import { toastState } from '../../store/toast/atom/toast.atom'; -import { usersWithTeamsState } from '../../store/user/atoms/user.atom'; -import { ToastStateEnum } from '../../utils/enums/toast-types'; const Users = () => { const { data: session } = useSession({ required: true }); - const setToastState = useSetRecoilState(toastState); - const setUsersWithTeamsState = useSetRecoilState(usersWithTeamsState); - const { data, isFetching } = useQuery(['usersWithTeams'], () => getAllUsersWithTeams(), { - enabled: false, - refetchOnWindowFocus: false, - onError: () => { - setToastState({ - open: true, - content: 'Error getting the users', - type: ToastStateEnum.ERROR, - }); - }, - }); - - if (data) { - setUsersWithTeamsState(data); - } - if (!session || !data) return null; + if (!session) return null; return ( }> - + @@ -51,16 +26,3 @@ const Users = () => { Users.getLayout = (page: ReactElement) => {page}; export default Users; - -export const getServerSideProps: GetServerSideProps = requireAuthentication( - async (context: GetServerSidePropsContext) => { - const queryClient = new QueryClient(); - await queryClient.prefetchQuery('usersWithTeams', () => getAllUsersWithTeams(context)); - - return { - props: { - dehydratedState: JSON.parse(JSON.stringify(dehydrate(queryClient))), - }, - }; - }, -);