From 2d79e649fc3ef84b90d762667ba23b9364204bba Mon Sep 17 00:00:00 2001 From: Rafael Batista <118206043+RafaelSBatista97@users.noreply.github.com> Date: Mon, 21 Nov 2022 11:23:01 +0000 Subject: [PATCH] [FEATURE]: get all users (#610) * feat: added users page layout * feat: get all users Co-authored-by: GuiSanto --- .../applications/get.user.application.ts | 4 ++ .../users/controller/users.controller.ts | 49 +++++++++++++++++ .../get.user.application.interface.ts | 2 + .../services/get.user.service.interface.ts | 2 + .../users/services/get.user.service.ts | 4 ++ backend/src/modules/users/users.module.ts | 2 + frontend/src/api/userService.tsx | 8 +++ frontend/src/pages/users/index.tsx | 53 +++++++++++++++++-- 8 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 backend/src/modules/users/controller/users.controller.ts create mode 100644 frontend/src/api/userService.tsx diff --git a/backend/src/modules/users/applications/get.user.application.ts b/backend/src/modules/users/applications/get.user.application.ts index 9dc362b02..f06b1ebbd 100644 --- a/backend/src/modules/users/applications/get.user.application.ts +++ b/backend/src/modules/users/applications/get.user.application.ts @@ -18,4 +18,8 @@ export class GetUserApplicationImpl implements GetUserApplication { countUsers() { return this.getUserService.countUsers(); } + + getAllUsers() { + return this.getUserService.getAllUsers(); + } } diff --git a/backend/src/modules/users/controller/users.controller.ts b/backend/src/modules/users/controller/users.controller.ts new file mode 100644 index 000000000..6af5dd132 --- /dev/null +++ b/backend/src/modules/users/controller/users.controller.ts @@ -0,0 +1,49 @@ +import { Controller, Get, Inject, UseGuards } from '@nestjs/common'; +import { + ApiBadRequestResponse, + ApiBearerAuth, + ApiInternalServerErrorResponse, + ApiOkResponse, + ApiOperation, + ApiTags, + ApiUnauthorizedResponse +} from '@nestjs/swagger'; + +import JwtAuthenticationGuard from 'libs/guards/jwtAuth.guard'; +import { BadRequestResponse } from 'libs/swagger/errors/bad-request.swagger'; +import { InternalServerErrorResponse } from 'libs/swagger/errors/internal-server-error.swagger'; +import { UnauthorizedResponse } from 'libs/swagger/errors/unauthorized.swagger'; + +import UserDto from '../dto/user.dto'; +import { GetUserApplication } from '../interfaces/applications/get.user.application.interface'; +import { TYPES } from '../interfaces/types'; + +@ApiBearerAuth('access-token') +@ApiTags('Users') +@UseGuards(JwtAuthenticationGuard) +@Controller('users') +export default class UsersController { + constructor( + @Inject(TYPES.applications.GetUserApplication) + private getUserApp: GetUserApplication + ) {} + + @ApiOperation({ summary: 'Retrieve a list of existing users' }) + @ApiOkResponse({ description: 'Users successfully retrieved!', type: UserDto, isArray: true }) + @ApiUnauthorizedResponse({ + description: 'Unauthorized', + type: UnauthorizedResponse + }) + @ApiBadRequestResponse({ + description: 'Bad Request', + type: BadRequestResponse + }) + @ApiInternalServerErrorResponse({ + description: 'Internal Server Error', + type: InternalServerErrorResponse + }) + @Get() + getAllUsers() { + return this.getUserApp.getAllUsers(); + } +} diff --git a/backend/src/modules/users/interfaces/applications/get.user.application.interface.ts b/backend/src/modules/users/interfaces/applications/get.user.application.interface.ts index ce6570c7f..4f48827df 100644 --- a/backend/src/modules/users/interfaces/applications/get.user.application.interface.ts +++ b/backend/src/modules/users/interfaces/applications/get.user.application.interface.ts @@ -6,4 +6,6 @@ export interface GetUserApplication { getByEmail(email: string): Promise | null>; countUsers(): Promise; + + getAllUsers(): Promise[]>; } diff --git a/backend/src/modules/users/interfaces/services/get.user.service.interface.ts b/backend/src/modules/users/interfaces/services/get.user.service.interface.ts index 77746d17d..9251037da 100644 --- a/backend/src/modules/users/interfaces/services/get.user.service.interface.ts +++ b/backend/src/modules/users/interfaces/services/get.user.service.interface.ts @@ -13,4 +13,6 @@ export interface GetUserService { ): Promise | false>; countUsers(): Promise; + + getAllUsers(): Promise[]>; } diff --git a/backend/src/modules/users/services/get.user.service.ts b/backend/src/modules/users/services/get.user.service.ts index e5be8b20e..67d6d88bf 100644 --- a/backend/src/modules/users/services/get.user.service.ts +++ b/backend/src/modules/users/services/get.user.service.ts @@ -35,4 +35,8 @@ export default class GetUserServiceImpl implements GetUserService { countUsers() { return this.userModel.countDocuments().exec(); } + + getAllUsers() { + return this.userModel.find().select('-password -currentHashedRefreshToken').lean().exec(); + } } diff --git a/backend/src/modules/users/users.module.ts b/backend/src/modules/users/users.module.ts index 31cc96ece..67e4c4e8a 100644 --- a/backend/src/modules/users/users.module.ts +++ b/backend/src/modules/users/users.module.ts @@ -3,6 +3,7 @@ import { Module } from '@nestjs/common'; import { mongooseResetModule, mongooseUserModule } from 'infrastructure/database/mongoose.module'; import TeamsModule from 'modules/teams/teams.module'; +import UsersController from './controller/users.controller'; import { createUserService, getUserApplication, @@ -20,6 +21,7 @@ import { updateUserApplication, getUserApplication ], + controllers: [UsersController], exports: [ createUserService, getUserService, diff --git a/frontend/src/api/userService.tsx b/frontend/src/api/userService.tsx new file mode 100644 index 000000000..2eb3ab7a0 --- /dev/null +++ b/frontend/src/api/userService.tsx @@ -0,0 +1,8 @@ +import { GetServerSidePropsContext } from 'next'; + +import fetchData from 'utils/fetchData'; +import { User } from '../types/user/user'; + +export const getAllUsers = (context?: GetServerSidePropsContext): Promise => { + return fetchData(`/users`, { context, serverSide: !!context }); +}; diff --git a/frontend/src/pages/users/index.tsx b/frontend/src/pages/users/index.tsx index 865fde040..36d3af31f 100644 --- a/frontend/src/pages/users/index.tsx +++ b/frontend/src/pages/users/index.tsx @@ -1,16 +1,63 @@ -import { ReactElement } from 'react'; +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 { getAllUsers } from '../../api/userService'; +import requireAuthentication from '../../components/HOC/requireAuthentication'; +import { toastState } from '../../store/toast/atom/toast.atom'; +import { ToastStateEnum } from '../../utils/enums/toast-types'; const Users = () => { const { data: session } = useSession({ required: true }); + const setToastState = useSetRecoilState(toastState); - if (!session) return null; // after getUsers issue, need to add || !data to the if - return ; + const { data } = useQuery(['users'], () => getAllUsers(), { + enabled: true, + refetchOnWindowFocus: false, + onError: () => { + setToastState({ + open: true, + content: 'Error getting the users', + type: ToastStateEnum.ERROR + }); + } + }); + + if (!session || !data) return null; + + return ( + + }> + + {data.map((user) => ( +

{user.email}

+ ))} +
+
+
+ ); }; Users.getLayout = (page: ReactElement) => {page}; export default Users; + +export const getServerSideProps: GetServerSideProps = requireAuthentication( + async (context: GetServerSidePropsContext) => { + const queryClient = new QueryClient(); + await queryClient.prefetchQuery('users', () => getAllUsers(context)); + + return { + props: { + dehydratedState: JSON.parse(JSON.stringify(dehydrate(queryClient))) + } + }; + } +); +