Skip to content

Commit

Permalink
[FEATURE]: get all users (#610)
Browse files Browse the repository at this point in the history
* feat: added users page layout

* feat: get all users

Co-authored-by: GuiSanto <guiontheworks@gmail.com>
  • Loading branch information
RafaelSBatista97 and GuiSanto authored Nov 21, 2022
1 parent 5789457 commit 2d79e64
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@ export class GetUserApplicationImpl implements GetUserApplication {
countUsers() {
return this.getUserService.countUsers();
}

getAllUsers() {
return this.getUserService.getAllUsers();
}
}
49 changes: 49 additions & 0 deletions backend/src/modules/users/controller/users.controller.ts
Original file line number Diff line number Diff line change
@@ -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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ export interface GetUserApplication {
getByEmail(email: string): Promise<LeanDocument<UserDocument> | null>;

countUsers(): Promise<number>;

getAllUsers(): Promise<LeanDocument<UserDocument>[]>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ export interface GetUserService {
): Promise<LeanDocument<UserDocument> | false>;

countUsers(): Promise<number>;

getAllUsers(): Promise<LeanDocument<UserDocument>[]>;
}
4 changes: 4 additions & 0 deletions backend/src/modules/users/services/get.user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
2 changes: 2 additions & 0 deletions backend/src/modules/users/users.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -20,6 +21,7 @@ import {
updateUserApplication,
getUserApplication
],
controllers: [UsersController],
exports: [
createUserService,
getUserService,
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/api/userService.tsx
Original file line number Diff line number Diff line change
@@ -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<User[]> => {
return fetchData(`/users`, { context, serverSide: !!context });
};
53 changes: 50 additions & 3 deletions frontend/src/pages/users/index.tsx
Original file line number Diff line number Diff line change
@@ -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 <Flex direction="column" />;
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 (
<Flex direction="column">
<Suspense fallback={<LoadingPage />}>
<QueryError>
{data.map((user) => (
<h2>{user.email}</h2>
))}
</QueryError>
</Suspense>
</Flex>
);
};

Users.getLayout = (page: ReactElement) => <Layout>{page}</Layout>;

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)))
}
};
}
);

0 comments on commit 2d79e64

Please sign in to comment.