Skip to content

Commit

Permalink
Ojn03/feat applications table (#66)
Browse files Browse the repository at this point in the history
* fake endpoint

* application table frontend draft

* lint: fixed any type issue

* feat: added controlled table selection

* feat: working view application

* feat: working copy of admin view

---------

Co-authored-by: Harrison Kim <[email protected]>
  • Loading branch information
ojn03 and kimharr24 authored Sep 26, 2024
1 parent d684416 commit eb47bf6
Show file tree
Hide file tree
Showing 9 changed files with 679 additions and 13 deletions.
5 changes: 4 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,8 @@
"extends": ["plugin:@nx/javascript"],
"rules": {}
}
]
],
"rules": {
"@typescript-eslint/no-useless-constructor": "off"
}
}
2 changes: 1 addition & 1 deletion apps/backend/src/applications/application.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class Application {
@JoinColumn()
user: User;

@Column({ nullable: false })
@Column({ nullable: false, default: () => 'CURRENT_TIMESTAMP' })
@IsDateString()
createdAt: Date;

Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/applications/applications.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class ApplicationsController {
//Delegate the decision making to the service.
await this.applicationsService.processDecision(applicantId, decisionEnum);
}

@UseGuards(AuthGuard('jwt'))
@Get('/')
async getApplications(
Expand All @@ -76,7 +77,6 @@ export class ApplicationsController {
'Calling user is not a recruiter or admin.',
);
}

return this.applicationsService.findAllCurrentApplications();
}

Expand Down
20 changes: 20 additions & 0 deletions apps/backend/src/users/users.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Param,
ParseIntPipe,
Patch,
Post,
Request,
UnauthorizedException,
UseGuards,
Expand All @@ -18,13 +19,32 @@ import { CurrentUserInterceptor } from '../interceptors/current-user.interceptor
import { GetUserResponseDto } from './dto/get-user.response.dto';
import { UserStatus } from './types';
import { toGetUserResponseDto } from './users.utils';
import { User } from './user.entity';

@Controller('users')
@UseInterceptors(CurrentUserInterceptor)
@UseGuards(AuthGuard('jwt'))
export class UsersController {
constructor(private usersService: UsersService) {}

@Post('email')
async getUserByEmail(
@Body('email') email: string,
@Request() req,
): Promise<User[]> {
// This endpoint is used by our Google Form AppScript to check whether a user already exists in our
// database. If not, then the AppScript creates a new user. This is how the AppScript knows when to create a new user.
if (req.user.status !== UserStatus.ADMIN) {
throw new UnauthorizedException();
}
return await this.usersService.findByEmail(email);
}

@Get('/fullname')
async getFullName(@Request() req): Promise<string> {
return `${req.user.firstName} ${req.user.lastName}`;
}

@Get('/:userId')
async getUser(
@Param('userId', ParseIntPipe) userId: number,
Expand Down
46 changes: 42 additions & 4 deletions apps/frontend/src/api/apiClient.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import axios, { type AxiosInstance } from 'axios';

import axios, { type AxiosInstance, AxiosRequestConfig } from 'axios';
import type {
Application,
applicationRow,
} from '@components/ApplicationTables';
const defaultBaseUrl =
import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:3000';

Expand All @@ -14,8 +17,43 @@ export class ApiClient {
return this.get('/api') as Promise<string>;
}

private async get(path: string): Promise<unknown> {
return this.axiosInstance.get(path).then((response) => response.data);
public async getAllApplications(
accessToken: string,
): Promise<applicationRow[]> {
return (await this.get('/api/apps', {
headers: {
Authorization: `Bearer ${accessToken}`,
},
})) as Promise<applicationRow[]>;
}

public async getApplication(
accessToken: string,
userId: number,
): Promise<Application> {
return (await this.get(`/api/apps/${userId}`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
})) as Promise<Application>;
}

public async getFullName(accessToken: string): Promise<string> {
return (await this.get('/api/users/fullname', {
headers: {
Authorization: `Bearer ${accessToken}`,
},
})) as Promise<string>;
}

private async get(
path: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
headers: AxiosRequestConfig<any> | undefined = undefined,
): Promise<unknown> {
return this.axiosInstance
.get(path, headers)
.then((response) => response.data);
}

private async post(path: string, body: unknown): Promise<unknown> {
Expand Down
Loading

0 comments on commit eb47bf6

Please sign in to comment.