From 56df9dbed0282de61a0c67d2493d360a91c4e224 Mon Sep 17 00:00:00 2001 From: Aaron Date: Thu, 6 Feb 2025 19:20:20 -0500 Subject: [PATCH 1/8] Updated user entity to include 'recruiters' column Added a 'recruiters' column, which is defined as a one-to-many relation --- apps/backend/src/testing/factories/user.factory.ts | 1 + apps/backend/src/users/user.entity.ts | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/apps/backend/src/testing/factories/user.factory.ts b/apps/backend/src/testing/factories/user.factory.ts index ea42f4a7..926f841c 100644 --- a/apps/backend/src/testing/factories/user.factory.ts +++ b/apps/backend/src/testing/factories/user.factory.ts @@ -15,6 +15,7 @@ export const defaultUser: User = { team: null, role: null, applications: [], + recruiters: [], }; export const userFactory = (user: Partial = {}): User => diff --git a/apps/backend/src/users/user.entity.ts b/apps/backend/src/users/user.entity.ts index 702be10b..391384df 100644 --- a/apps/backend/src/users/user.entity.ts +++ b/apps/backend/src/users/user.entity.ts @@ -71,4 +71,10 @@ export class User { @IsObject({ each: true }) @OneToMany(() => Application, (application) => application.user) applications: Application[]; + + @Column('jsonb', { nullable: true, default: [] }) + @IsArray() + @IsObject({ each: true }) + @OneToMany(() => User, (user) => user.firstName + user.lastName) + recruiters: User[]; } From 578de73be78ec4c47992750591ea6f148b195dd5 Mon Sep 17 00:00:00 2001 From: Aaron Date: Thu, 6 Feb 2025 19:40:04 -0500 Subject: [PATCH 2/8] Added recruiters column to update user request dto --- apps/backend/src/users/dto/update-user.request.dto.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/backend/src/users/dto/update-user.request.dto.ts b/apps/backend/src/users/dto/update-user.request.dto.ts index 1bb0cf39..d00a1627 100644 --- a/apps/backend/src/users/dto/update-user.request.dto.ts +++ b/apps/backend/src/users/dto/update-user.request.dto.ts @@ -1,3 +1,4 @@ +import { User } from '../../users/user.entity'; import { Application } from '../../applications/application.entity'; import { UserStatus, Role, Team } from '../types'; import { @@ -55,4 +56,9 @@ export class UpdateUserRequestDTO { @IsArray() @IsObject({ each: true }) applications?: Application[]; + + @IsOptional() + @IsArray() + @IsObject({ each: true }) + recruiters?: User[]; } From 98bad00f14326601fad875b62dbf182c1e78d0c7 Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 11 Feb 2025 10:26:08 -0500 Subject: [PATCH 3/8] Added assign recruiters column to application table --- apps/backend/src/users/users.controller.ts | 2 ++ apps/frontend/src/components/ApplicationTables/columns.ts | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/apps/backend/src/users/users.controller.ts b/apps/backend/src/users/users.controller.ts index ab7880db..f5754af8 100644 --- a/apps/backend/src/users/users.controller.ts +++ b/apps/backend/src/users/users.controller.ts @@ -64,6 +64,8 @@ export class UsersController { return toGetUserResponseDto(user); } + // TODO: Ask David if new endpoint is even necessary; can't we just call this one with + // an updated recruiters array? @Patch('/:userId') async updateUser( @Body() updateUserDTO: UpdateUserRequestDTO, diff --git a/apps/frontend/src/components/ApplicationTables/columns.ts b/apps/frontend/src/components/ApplicationTables/columns.ts index a2d8f52f..d1f6b96e 100644 --- a/apps/frontend/src/components/ApplicationTables/columns.ts +++ b/apps/frontend/src/components/ApplicationTables/columns.ts @@ -29,6 +29,11 @@ export const applicationColumns = [ headerName: 'Date', width: 150, }, + { + field: 'assignedRecruiters', + headerName: 'Assigned Recruiters', + width: 150, + }, { field: 'meanRatingAllStages', headerName: 'Rating All Stages', From e5116413a4bffcd321db1ca34beef58d031960ce Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 11 Feb 2025 11:04:03 -0500 Subject: [PATCH 4/8] Created fetchRecruiters method to fetch recruiters data from API endpoint --- apps/frontend/src/api/apiClient.ts | 9 ++++ .../components/ApplicationTables/index.tsx | 9 +++- apps/frontend/src/components/types.ts | 52 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/apps/frontend/src/api/apiClient.ts b/apps/frontend/src/api/apiClient.ts index 13215957..29a21e9c 100644 --- a/apps/frontend/src/api/apiClient.ts +++ b/apps/frontend/src/api/apiClient.ts @@ -3,6 +3,7 @@ import type { Application, ApplicationRow, ApplicationStage, + User, } from '@components/types'; const defaultBaseUrl = @@ -47,6 +48,14 @@ export class ApiClient { })) as Promise; } + public async getAllRecruiters(accessToken: string): Promise { + return (await this.get('/api/users/recruiters', { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + })) as Promise; + } + public async getApplication( accessToken: string, userId: number, diff --git a/apps/frontend/src/components/ApplicationTables/index.tsx b/apps/frontend/src/components/ApplicationTables/index.tsx index ac4c7572..e1875b69 100644 --- a/apps/frontend/src/components/ApplicationTables/index.tsx +++ b/apps/frontend/src/components/ApplicationTables/index.tsx @@ -12,7 +12,7 @@ import { } from '@mui/material'; import { DoneOutline } from '@mui/icons-material'; -import { ApplicationRow, Application, Semester } from '../types'; +import { ApplicationRow, Application, Semester, User } from '../types'; import apiClient from '@api/apiClient'; import { applicationColumns } from './columns'; import { ReviewModal } from './reviewModal'; @@ -43,6 +43,8 @@ export function ApplicationTable() { const [selectedUserRow, setSelectedUserRow] = useState( null, ); + const [recruitersList, setRecruitersList] = useState>([]); + const [selectedApplication, setSelectedApplication] = useState(null); @@ -52,6 +54,11 @@ export function ApplicationTable() { setOpenReviewModal(true); }; + const fetchRecruiters = async () => { + const data = await apiClient.getAllRecruiters(accessToken); + setRecruitersList(data); + }; + const fetchData = async () => { const data = await apiClient.getAllApplications(accessToken); // Each application needs an id for the DataGrid to work diff --git a/apps/frontend/src/components/types.ts b/apps/frontend/src/components/types.ts index bac5d09b..1ab4a237 100644 --- a/apps/frontend/src/components/types.ts +++ b/apps/frontend/src/components/types.ts @@ -18,6 +18,39 @@ enum Position { DESIGNER = 'DESIGNER', } +enum UserStatus { + MEMBER = 'Member', + RECRUITER = 'Recruiter', + ADMIN = 'Admin', + ALUMNI = 'Alumni', + APPLICANT = 'Applicant', +} + +enum Team { + SFTT = 'Speak for the Trees', + CONSTELLATION = 'Constellation', + JPAL = 'J-PAL', + BREAKTIME = 'Breaktime', + GI = 'Green Infrastructure', + CI = 'Core Infrastructure', + EBOARD = 'E-Board', +} + +enum Role { + DIRECTOR_OF_ENGINEERING = 'Director of Engineering', + DIRECTOR_OF_PRODUCT = 'Director of Product', + DIRECTOR_OF_FINANCE = 'Director of Finance', + DIRECTOR_OF_MARKETING = 'Director of Marketing', + DIRECTOR_OF_RECRUITMENT = 'Director of Recruitment', + DIRECTOR_OF_OPERATIONS = 'Director of Operations', + DIRECTOR_OF_EVENTS = 'Director of Events', + DIRECTOR_OF_DESIGN = 'Director of Design', + PRODUCT_MANAGER = 'Product Manager', + PRODUCT_DESIGNER = 'Product Designer', + TECH_LEAD = 'Technical Lead', + DEVELOPER = 'Developer', +} + type ApplicationRow = { id: number; userId: number; @@ -64,12 +97,31 @@ type Application = { reviews: Review[]; }; +type User = { + id: number; + status: UserStatus; + firstName: string; + lastName: string; + email: string; + profilePicture: string | null; + linkedin: string | null; + github: string | null; + team: Team | null; + role: Role[] | null; + applications: Application[]; + recruiters: User[]; +}; + export { ApplicationRow, Application, + User, ApplicationStage, ApplicationStep, Position, + UserStatus, + Team, + Role, Response, Review, Semester, From 5a71a658b210105b7477953e6d498a3e2e5348ec Mon Sep 17 00:00:00 2001 From: Aaron Date: Thu, 13 Feb 2025 15:47:15 -0500 Subject: [PATCH 5/8] Added dropdown menu to select recruiters for a single applicant --- .../components/ApplicationTables/index.tsx | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/apps/frontend/src/components/ApplicationTables/index.tsx b/apps/frontend/src/components/ApplicationTables/index.tsx index e1875b69..e4844ce4 100644 --- a/apps/frontend/src/components/ApplicationTables/index.tsx +++ b/apps/frontend/src/components/ApplicationTables/index.tsx @@ -9,7 +9,11 @@ import { ListItemText, ListItemIcon, Button, + Checkbox, + TextField, + Autocomplete, } from '@mui/material'; +import { CheckBoxOutlineBlank, CheckBox } from '@mui/icons-material'; import { DoneOutline } from '@mui/icons-material'; import { ApplicationRow, Application, Semester, User } from '../types'; @@ -17,9 +21,13 @@ import apiClient from '@api/apiClient'; import { applicationColumns } from './columns'; import { ReviewModal } from './reviewModal'; import useLoginContext from '@components/LoginPage/useLoginContext'; +import { light } from '@mui/material/styles/createPalette'; const TODAY = new Date(); +const checkBoxIconUnchecked = ; +const checkBoxIconChecked = ; + const getCurrentSemester = (): Semester => { const month: number = TODAY.getMonth(); if (month >= 1 && month <= 7) { @@ -122,6 +130,7 @@ export function ApplicationTable() { onRowSelectionModelChange={(newRowSelectionModel) => { setRowSelection(newRowSelectionModel); getApplication(data[newRowSelectionModel[0] as number].userId); + fetchRecruiters(); }} rowSelectionModel={rowSelection} /> @@ -157,6 +166,42 @@ export function ApplicationTable() { Applications: {selectedApplication.numApps} + Recruiters: + + recruiter.firstName + ' ' + recruiter.lastName + } + renderOption={(props, option, { selected }) => { + const { key, ...optionProps } = + props as React.HTMLAttributes & { + key: string; + }; + return ( +
  • + + {option.firstName + ' ' + option.lastName} +
  • + ); + }} + style={{ + width: 200, + height: 100, + }} + renderInput={(params) => ( + + )} + /> Application Responses From 5cce9440649cbfc086a62f1c215eac6b44f1df4c Mon Sep 17 00:00:00 2001 From: Aaron Date: Thu, 13 Feb 2025 15:49:01 -0500 Subject: [PATCH 6/8] Removed height from styling --- apps/frontend/src/components/ApplicationTables/index.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/frontend/src/components/ApplicationTables/index.tsx b/apps/frontend/src/components/ApplicationTables/index.tsx index e4844ce4..c01fd54b 100644 --- a/apps/frontend/src/components/ApplicationTables/index.tsx +++ b/apps/frontend/src/components/ApplicationTables/index.tsx @@ -190,10 +190,7 @@ export function ApplicationTable() { ); }} - style={{ - width: 200, - height: 100, - }} + style={{ width: 200 }} renderInput={(params) => ( Date: Sat, 22 Feb 2025 13:03:19 -0500 Subject: [PATCH 7/8] Created rough version of implementation of 'updateApplication' patch request --- .../src/applications/application.entity.ts | 13 +++++ .../applications/applications.controller.ts | 26 +++++++++- .../src/applications/applications.service.ts | 38 +++++++++++++++ .../dto/get-all-application.response.dto.ts | 6 ++- .../dto/get-application.response.dto.ts | 3 ++ .../dto/update-application.request.dto.ts | 48 +++++++++++++++++++ apps/backend/src/applications/utils.ts | 19 ++++++++ .../src/users/dto/get-user.response.dto.ts | 1 + apps/backend/src/users/users.controller.ts | 2 - apps/frontend/src/components/types.ts | 1 + 10 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 apps/backend/src/applications/dto/update-application.request.dto.ts diff --git a/apps/backend/src/applications/application.entity.ts b/apps/backend/src/applications/application.entity.ts index 5bc315cb..b3fee940 100644 --- a/apps/backend/src/applications/application.entity.ts +++ b/apps/backend/src/applications/application.entity.ts @@ -58,12 +58,23 @@ export class Application { @IsObject({ each: true }) response: Response[]; + @Column('jsonb', { nullable: true, default: [] }) + @IsArray() + @IsObject({ each: true }) + @OneToMany(() => User, (user) => user.firstName + user.lastName) + recruiters: User[]; + @Column('varchar', { array: true, default: {} }) @IsArray() @IsObject({ each: true }) @OneToMany(() => Review, (review) => review.application) reviews: Review[]; + @Column({ nullable: false, default: 0 }) + @IsPositive() + @Min(0) + numApps: number; + toGetAllApplicationResponseDTO( meanRatingAllReviews, meanRatingResume, @@ -80,6 +91,7 @@ export class Application { step: applicationStep, position: this.position, createdAt: this.createdAt, + recruiters: this.recruiters, meanRatingAllReviews, meanRatingResume, meanRatingChallenge, @@ -101,6 +113,7 @@ export class Application { stage: this.stage, step: applicationStep, response: this.response, + recruiters: this.recruiters, reviews: this.reviews, numApps, }; diff --git a/apps/backend/src/applications/applications.controller.ts b/apps/backend/src/applications/applications.controller.ts index b8fb322a..fd499df3 100644 --- a/apps/backend/src/applications/applications.controller.ts +++ b/apps/backend/src/applications/applications.controller.ts @@ -7,6 +7,7 @@ import { UseInterceptors, UseGuards, Post, + Patch, Body, BadRequestException, NotFoundException, @@ -17,11 +18,12 @@ import { ApplicationsService } from './applications.service'; import { CurrentUserInterceptor } from '../interceptors/current-user.interceptor'; import { AuthGuard } from '@nestjs/passport'; import { GetApplicationResponseDTO } from './dto/get-application.response.dto'; -import { getAppForCurrentCycle } from './utils'; +import { getAppForCurrentCycle, toGetApplicationResponseDTO } from './utils'; import { UserStatus } from '../users/types'; import { Application } from './application.entity'; import { GetAllApplicationResponseDTO } from './dto/get-all-application.response.dto'; import { ApplicationStep } from './types'; +import { UpdateApplicationRequestDTO } from './dto/update-application.request.dto'; @Controller('apps') @UseInterceptors(CurrentUserInterceptor) @@ -115,4 +117,26 @@ export class ApplicationsController { return app.toGetApplicationResponseDTO(apps.length, applicationStep); } + + // TODO: Update DTOs + @Patch('/:applicantId') + async updateApplication( + @Body() updateApplicationDTO: UpdateApplicationRequestDTO, + @Param('applicantId', ParseIntPipe) applicantId: number, + @Request() req, + ): Promise { + if (req.user.status !== UserStatus.ADMIN) { + throw new UnauthorizedException( + 'Only admins can assign recruiters to applicants', + ); + } + + const newApplicant = await this.applicationsService.updateApplication( + req.application, + applicantId, + updateApplicationDTO, + ); + + return toGetApplicationResponseDTO(newApplicant); + } } diff --git a/apps/backend/src/applications/applications.service.ts b/apps/backend/src/applications/applications.service.ts index 596d62f2..029637d9 100644 --- a/apps/backend/src/applications/applications.service.ts +++ b/apps/backend/src/applications/applications.service.ts @@ -2,6 +2,7 @@ import { BadRequestException, UnauthorizedException, Injectable, + NotFoundException, } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; @@ -19,6 +20,7 @@ import { User } from '../users/user.entity'; import { Position, ApplicationStage, ApplicationStep } from './types'; import { GetAllApplicationResponseDTO } from './dto/get-all-application.response.dto'; import { stagesMap } from './applications.constants'; +import { UpdateApplicationRequestDTO } from './dto/update-application.request.dto'; @Injectable() export class ApplicationsService { @@ -237,4 +239,40 @@ export class ApplicationsService { return currentApp; } + + async findOne( + currentApplication: Application, + applicationId: number, + ): Promise { + const application = await this.applicationsRepository.findOne({ + where: { id: applicationId }, + }); + + if (!application) { + throw new NotFoundException( + `Application with ID ${applicationId} not found`, + ); + } + + return application; + } + + async updateApplication( + currentApplication: Application, + applicationId: number, + updateApplicationDTO: UpdateApplicationRequestDTO, + ): Promise { + await this.findOne(currentApplication, applicationId); + + try { + await this.applicationsRepository.update( + { id: applicationId }, + updateApplicationDTO, + ); + } catch (error) { + throw new BadRequestException('Cannot update application'); + } + + return await this.findOne(currentApplication, applicationId); + } } diff --git a/apps/backend/src/applications/dto/get-all-application.response.dto.ts b/apps/backend/src/applications/dto/get-all-application.response.dto.ts index ee6fd71c..a01ba496 100644 --- a/apps/backend/src/applications/dto/get-all-application.response.dto.ts +++ b/apps/backend/src/applications/dto/get-all-application.response.dto.ts @@ -1,5 +1,6 @@ -import { IsDate, IsEnum, IsPositive, IsString } from 'class-validator'; +import { IsArray, IsDate, IsEnum, IsPositive, IsString } from 'class-validator'; import { ApplicationStage, ApplicationStep, Position } from '../types'; +import { User } from '../../users/user.entity'; export class GetAllApplicationResponseDTO { @IsPositive() @@ -23,6 +24,9 @@ export class GetAllApplicationResponseDTO { @IsDate() createdAt: Date; + @IsArray() + recruiters: User[]; + @IsPositive() meanRatingAllReviews: number; diff --git a/apps/backend/src/applications/dto/get-application.response.dto.ts b/apps/backend/src/applications/dto/get-application.response.dto.ts index 7e595453..e35a44fe 100644 --- a/apps/backend/src/applications/dto/get-application.response.dto.ts +++ b/apps/backend/src/applications/dto/get-application.response.dto.ts @@ -1,4 +1,5 @@ import { Review } from '../../reviews/review.entity'; +import { User } from '../../users/user.entity'; import { ApplicationStage, ApplicationStep, @@ -24,6 +25,8 @@ export class GetApplicationResponseDTO { response: Response[]; + recruiters: User[]; + reviews: Review[]; numApps: number; diff --git a/apps/backend/src/applications/dto/update-application.request.dto.ts b/apps/backend/src/applications/dto/update-application.request.dto.ts new file mode 100644 index 00000000..65dc938b --- /dev/null +++ b/apps/backend/src/applications/dto/update-application.request.dto.ts @@ -0,0 +1,48 @@ +import { User } from '../../users/user.entity'; +import { Application } from '../application.entity'; +import { + Semester, + Position, + ApplicationStage, + ApplicationStep, +} from '../types'; +import { Review } from '../../reviews/review.entity'; +import { + IsArray, + IsEnum, + IsObject, + IsOptional, + IsPositive, +} from 'class-validator'; + +export class UpdateApplicationRequestDTO { + @IsOptional() + @IsEnum(Semester) + semester?: Semester; + + @IsOptional() + @IsEnum(Position) + position?: Position; + + @IsOptional() + @IsEnum(ApplicationStage) + stage: ApplicationStage; + + @IsOptional() + @IsEnum(ApplicationStep) + step: ApplicationStep; + + @IsOptional() + @IsArray() + @IsObject({ each: true }) + reviews: Review[]; + + @IsOptional() + @IsArray() + @IsObject({ each: true }) + recruiters: User[]; + + @IsOptional() + @IsPositive() + numApps: number; +} diff --git a/apps/backend/src/applications/utils.ts b/apps/backend/src/applications/utils.ts index b24a353d..351a6412 100644 --- a/apps/backend/src/applications/utils.ts +++ b/apps/backend/src/applications/utils.ts @@ -1,5 +1,6 @@ import { Application } from './application.entity'; import { Cycle } from './dto/cycle'; +import { GetApplicationResponseDTO } from './dto/get-application.response.dto'; import { Semester } from './types'; export const getCurrentSemester = (): Semester => { @@ -34,3 +35,21 @@ export const getAppForCurrentCycle = ( return null; }; + +export const toGetApplicationResponseDTO = ( + application: Application, +): GetApplicationResponseDTO => { + return { + id: application.id, + createdAt: application.createdAt, + year: application.year, + semester: application.semester, + position: application.position, + stage: application.stage, + step: application.step, + response: application.response, + recruiters: application.recruiters, + reviews: application.reviews, + numApps: application.numApps, + }; +}; diff --git a/apps/backend/src/users/dto/get-user.response.dto.ts b/apps/backend/src/users/dto/get-user.response.dto.ts index 16d77b3e..d39614aa 100644 --- a/apps/backend/src/users/dto/get-user.response.dto.ts +++ b/apps/backend/src/users/dto/get-user.response.dto.ts @@ -1,6 +1,7 @@ import { Entity } from 'typeorm'; import { Role, Team, UserStatus } from '../types'; +// TODO: Update this DTO and toGetUserResponseDto to include 'recruiters' field @Entity() export class GetUserResponseDto { id: number; diff --git a/apps/backend/src/users/users.controller.ts b/apps/backend/src/users/users.controller.ts index f5754af8..ab7880db 100644 --- a/apps/backend/src/users/users.controller.ts +++ b/apps/backend/src/users/users.controller.ts @@ -64,8 +64,6 @@ export class UsersController { return toGetUserResponseDto(user); } - // TODO: Ask David if new endpoint is even necessary; can't we just call this one with - // an updated recruiters array? @Patch('/:userId') async updateUser( @Body() updateUserDTO: UpdateUserRequestDTO, diff --git a/apps/frontend/src/components/types.ts b/apps/frontend/src/components/types.ts index 1ab4a237..8cf7f7b8 100644 --- a/apps/frontend/src/components/types.ts +++ b/apps/frontend/src/components/types.ts @@ -95,6 +95,7 @@ type Application = { response: Response[]; numApps: number; reviews: Review[]; + assignedRecruiters: User[]; }; type User = { From 266eefee614cc3cfcb691d90bbe375804e0dd1ab Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 22 Feb 2025 13:27:05 -0500 Subject: [PATCH 8/8] Update index.tsx --- .../components/ApplicationTables/index.tsx | 78 +++++++++++-------- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/apps/frontend/src/components/ApplicationTables/index.tsx b/apps/frontend/src/components/ApplicationTables/index.tsx index c01fd54b..4bae6371 100644 --- a/apps/frontend/src/components/ApplicationTables/index.tsx +++ b/apps/frontend/src/components/ApplicationTables/index.tsx @@ -51,7 +51,7 @@ export function ApplicationTable() { const [selectedUserRow, setSelectedUserRow] = useState( null, ); - const [recruitersList, setRecruitersList] = useState>([]); + const [allRecruitersList, setAllRecruitersList] = useState>([]); const [selectedApplication, setSelectedApplication] = useState(null); @@ -64,7 +64,7 @@ export function ApplicationTable() { const fetchRecruiters = async () => { const data = await apiClient.getAllRecruiters(accessToken); - setRecruitersList(data); + setAllRecruitersList(data); }; const fetchData = async () => { @@ -107,6 +107,20 @@ export function ApplicationTable() { } }, [rowSelection, data]); + const handleRecruitersChange = async ( + event: React.SyntheticEvent, + value: User[], + ) => { + event.preventDefault(); + + // TODO: This should call updateApplicant, which needs to be implemented + /* + if (selectedApplication) { + await apiClient.updateApplicant(accessToken, selectedApplication.id, value); + } + */ + }; + return ( @@ -167,39 +181,35 @@ export function ApplicationTable() { Applications: {selectedApplication.numApps} Recruiters: - - recruiter.firstName + ' ' + recruiter.lastName - } - renderOption={(props, option, { selected }) => { - const { key, ...optionProps } = - props as React.HTMLAttributes & { - key: string; - }; - return ( -
  • - - {option.firstName + ' ' + option.lastName} -
  • - ); - }} - style={{ width: 200 }} - renderInput={(params) => ( - - )} - /> + + recruiter.firstName + ' ' + recruiter.lastName + } + renderOption={(props, option, { selected }) => { + const { key, ...optionProps } = + props as React.HTMLAttributes & { + key: string; + }; + return ( +
  • + + {option.firstName + ' ' + option.lastName} +
  • + ); + }} + style={{ width: 400, marginTop: 10 }} + renderInput={(params) => ( + + )} + /> Application Responses