Skip to content

Commit 273ce76

Browse files
committed
#4001 guest definition hooks
1 parent 2784ce6 commit 273ce76

10 files changed

Lines changed: 150 additions & 15 deletions

File tree

src/backend/src/controllers/recruitment.controllers.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,14 @@ export default class RecruitmentController {
9999

100100
static async createGuestDefinition(req: Request, res: Response, next: NextFunction) {
101101
try {
102-
const { term, description, order, icon, buttonText, buttonLink } = req.body;
102+
const { term, description, order, icon, type, buttonText, buttonLink } = req.body;
103103
const definition = await RecruitmentServices.createGuestDefinition(
104104
req.currentUser,
105105
req.organization,
106106
term,
107107
description,
108108
order,
109+
type,
109110
icon,
110111
buttonText,
111112
buttonLink
@@ -119,7 +120,7 @@ export default class RecruitmentController {
119120
static async editGuestDefinition(req: Request, res: Response, next: NextFunction) {
120121
try {
121122
const { definitionId } = req.params as Record<string, string>;
122-
const { term, description, order, icon, buttonText, buttonLink } = req.body;
123+
const { term, description, order, type, icon, buttonText, buttonLink } = req.body;
123124

124125
const definition = await RecruitmentServices.editGuestDefinition(
125126
req.currentUser,
@@ -128,6 +129,7 @@ export default class RecruitmentController {
128129
description,
129130
definitionId,
130131
order,
132+
type,
131133
icon,
132134
buttonText,
133135
buttonLink
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- CreateEnum
2+
CREATE TYPE "Guest_Definition_Type" AS ENUM ('PROJECT_MANAGEMENT', 'INFO_PAGE');
3+
4+
-- AlterTable
5+
ALTER TABLE "Guest_Definition" ADD COLUMN "type" "Guest_Definition_Type" NOT NULL DEFAULT 'INFO_PAGE';

src/backend/src/prisma/schema.prisma

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1787,21 +1787,27 @@ model Reimbursement_Request_Comment {
17871787
@@index([reimbursementRequestId])
17881788
}
17891789

1790+
enum Guest_Definition_Type {
1791+
PROJECT_MANAGEMENT
1792+
INFO_PAGE
1793+
}
1794+
17901795
model Guest_Definition {
1791-
definitionId String @id @default(uuid())
1796+
definitionId String @id @default(uuid())
17921797
term String
17931798
description String
17941799
order Int
1800+
type Guest_Definition_Type @default(INFO_PAGE)
17951801
buttonText String?
17961802
buttonLink String?
17971803
icon String?
1798-
dateCreated DateTime @default(now())
1804+
dateCreated DateTime @default(now())
17991805
dateDeleted DateTime?
1800-
userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "guestDefinitionDeleter")
1806+
userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "guestDefinitionDeleter")
18011807
userDeletedId String?
1802-
userCreated User @relation(fields: [userCreatedId], references: [userId], name: "guestDefinitionCreator")
1808+
userCreated User @relation(fields: [userCreatedId], references: [userId], name: "guestDefinitionCreator")
18031809
userCreatedId String
1804-
organization Organization @relation(fields: [organizationId], references: [organizationId])
1810+
organization Organization @relation(fields: [organizationId], references: [organizationId])
18051811
organizationId String
18061812
18071813
@@index([organizationId])

src/backend/src/routes/recruitment.routes.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ recruitmentRouter.post(
5757
nonEmptyString(body('term')),
5858
nonEmptyString(body('description')),
5959
body('order').isInt(),
60+
nonEmptyString(body('type')).optional(),
6061
nonEmptyString(body('icon')).optional(),
6162
nonEmptyString(body('buttonText')).optional(),
6263
nonEmptyString(body('buttonLink')).optional(),
@@ -65,10 +66,11 @@ recruitmentRouter.post(
6566
);
6667

6768
recruitmentRouter.post(
68-
'/guestDefinition/:guestId/edit',
69+
'/guestdefinition/:definitionId/edit',
6970
nonEmptyString(body('term')),
7071
nonEmptyString(body('description')),
7172
body('order').isInt(),
73+
nonEmptyString(body('type')).optional(),
7274
nonEmptyString(body('icon')).optional(),
7375
nonEmptyString(body('buttonText')).optional(),
7476
nonEmptyString(body('buttonLink')).optional(),

src/backend/src/services/recruitment.services.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Organization } from '@prisma/client';
2-
import { isAdmin, User } from 'shared';
2+
import { GuestDefinitionType, isAdmin, User } from 'shared';
33
import prisma from '../prisma/prisma.js';
44
import { AccessDeniedAdminOnlyException, DeletedException, NotFoundException } from '../utils/errors.utils.js';
55
import { userHasPermission } from '../utils/users.utils.js';
@@ -221,6 +221,7 @@ export default class RecruitmentServices {
221221
* @param description the definition of the term
222222
* @param order the order the term appears on the page
223223
* @param icon the icon associated with the term
224+
* @param type the type of the guest definition
224225
* @param buttonText the text displayed on the terms button
225226
* @param buttonLink where the terms button links to
226227
* @returns
@@ -231,6 +232,7 @@ export default class RecruitmentServices {
231232
term: string,
232233
description: string,
233234
order: number,
235+
type?: GuestDefinitionType,
234236
icon?: string,
235237
buttonText?: string,
236238
buttonLink?: string
@@ -243,6 +245,7 @@ export default class RecruitmentServices {
243245
term,
244246
description,
245247
order,
248+
type,
246249
userCreatedId: creator.userId,
247250
organizationId: organization.organizationId,
248251
buttonText,
@@ -291,6 +294,7 @@ export default class RecruitmentServices {
291294
* @param description the definition of the term
292295
* @param order the order the term appears on the page
293296
* @param icon the icon associated with the term
297+
* @param type the type of the guest definition
294298
* @param buttonText the text displayed on the terms button
295299
* @param buttonLink where the terms button links to
296300
* @returns
@@ -302,6 +306,7 @@ export default class RecruitmentServices {
302306
description: string,
303307
definitionId: string,
304308
order: number,
309+
type?: GuestDefinitionType,
305310
icon?: string,
306311
buttonText?: string,
307312
buttonLink?: string
@@ -332,6 +337,7 @@ export default class RecruitmentServices {
332337
description,
333338
order,
334339
icon,
340+
type,
335341
buttonText,
336342
buttonLink
337343
}

src/backend/src/transformers/recruitment-transformer.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Prisma } from '@prisma/client';
2-
import { FrequentlyAskedQuestion, GuestDefinition } from 'shared';
1+
import { Prisma, Guest_Definition_Type as PrismaGuestDefinitionType } from '@prisma/client';
2+
import { FrequentlyAskedQuestion, GuestDefinition, GuestDefinitionType } from 'shared';
33
import { FaqQueryArgs } from '../prisma-query-args/faq.query-args.js';
44
import { userTransformer } from './user.transformer.js';
55

@@ -12,12 +12,21 @@ export const faqTransformer = (faq: Prisma.FrequentlyAskedQuestionGetPayload<Faq
1212
dateDeleted: faq.dateDeleted ?? undefined
1313
});
1414

15+
export const definitionTypeTransformer = (type: PrismaGuestDefinitionType): GuestDefinitionType => {
16+
const mapping: Record<PrismaGuestDefinitionType, GuestDefinitionType> = {
17+
PROJECT_MANAGEMENT: GuestDefinitionType.PROJECT_MANAGEMENT,
18+
INFO_PAGE: GuestDefinitionType.INFO_PAGE
19+
};
20+
return mapping[type];
21+
};
22+
1523
export const guestDefinitionTransformer = (guestDefinition: Prisma.Guest_DefinitionGetPayload<{}>): GuestDefinition => ({
1624
definitionId: guestDefinition.definitionId,
1725
term: guestDefinition.term,
1826
description: guestDefinition.description,
1927
order: guestDefinition.order,
2028
buttonText: guestDefinition.buttonText ?? undefined,
2129
buttonLink: guestDefinition.buttonLink ?? undefined,
22-
icon: guestDefinition.icon ?? undefined
30+
icon: guestDefinition.icon ?? undefined,
31+
type: definitionTypeTransformer(guestDefinition.type) ?? GuestDefinitionType.INFO_PAGE
2332
});

src/frontend/src/apis/recruitment.api.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import axios from '../utils/axios';
2-
import { MilestonePayload, FaqPayload } from '../hooks/recruitment.hooks';
2+
import { MilestonePayload, FaqPayload, GuestDefinitionPayload } from '../hooks/recruitment.hooks';
33
import { apiUrls } from '../utils/urls';
4-
import { dateToMidnightUTC, Milestone } from 'shared';
4+
import { dateToMidnightUTC, GuestDefinition, Milestone } from 'shared';
55
import { FrequentlyAskedQuestion } from 'shared';
66

77
export const getAllMilestones = () => {
@@ -49,3 +49,25 @@ export const editFaq = (payload: FaqPayload, id: string) => {
4949
export const deleteFaq = (faqId: string) => {
5050
return axios.delete<{ message: string }>(apiUrls.faqDelete(faqId));
5151
};
52+
53+
export const getAllGuestDefinitions = () => {
54+
return axios.get<GuestDefinition[]>(apiUrls.allGuestDefinitions(), {
55+
transformResponse: (data) => JSON.parse(data)
56+
});
57+
};
58+
59+
export const deleteGuestDefinition = (definitionId: string) => {
60+
return axios.delete<{ message: string }>(apiUrls.guestDefinitionDelete(definitionId));
61+
};
62+
63+
export const createGuestDefinition = (payload: GuestDefinitionPayload) => {
64+
return axios.post(apiUrls.guestDefinitionCreate(), {
65+
...payload
66+
});
67+
};
68+
69+
export const editGuestDefinition = (payload: GuestDefinitionPayload, id: string) => {
70+
return axios.post(apiUrls.guestDefintionEdit(id), {
71+
...payload
72+
});
73+
};

src/frontend/src/hooks/recruitment.hooks.ts

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import { useMutation, useQuery, useQueryClient } from 'react-query';
2-
import { Milestone, FrequentlyAskedQuestion } from 'shared';
2+
import { Milestone, FrequentlyAskedQuestion, GuestDefinition, GuestDefinitionType } from 'shared';
33
import {
44
createFaq,
5+
createGuestDefinition,
56
createMilestone,
67
deleteFaq,
8+
deleteGuestDefinition,
79
deleteMilestone,
810
editFaq,
11+
editGuestDefinition,
912
editMilestone,
1013
getAllFaqs,
14+
getAllGuestDefinitions,
1115
getAllMilestones
1216
} from '../apis/recruitment.api';
1317

@@ -22,6 +26,16 @@ export interface FaqPayload {
2226
answer: string;
2327
}
2428

29+
export interface GuestDefinitionPayload {
30+
term: string;
31+
description: string;
32+
order: number;
33+
type: GuestDefinitionType;
34+
icon?: string;
35+
buttonText?: string;
36+
buttonLink?: string;
37+
}
38+
2539
export const useAllMilestones = () => {
2640
return useQuery<Milestone[], Error>(['milestones'], async () => {
2741
const { data } = await getAllMilestones();
@@ -131,3 +145,58 @@ export const useDeleteFAQ = () => {
131145
}
132146
);
133147
};
148+
149+
export const useAllGuestDefinitions = () => {
150+
return useQuery<GuestDefinition[], Error>(['guestdefinitions'], async () => {
151+
const { data } = await getAllGuestDefinitions();
152+
return data;
153+
});
154+
};
155+
156+
export const useDeleteGuestDefinition = () => {
157+
const queryClient = useQueryClient();
158+
return useMutation<{ message: string }, Error, any>(
159+
['guestdefinitions', 'delete'],
160+
async (definitionId: string) => {
161+
const { data } = await deleteGuestDefinition(definitionId);
162+
return data;
163+
},
164+
{
165+
onSuccess: () => {
166+
queryClient.invalidateQueries(['guestdefinitions']);
167+
}
168+
}
169+
);
170+
};
171+
172+
export const useCreateGuestDefinition = () => {
173+
const queryClient = useQueryClient();
174+
return useMutation<GuestDefinition, Error, GuestDefinitionPayload>(
175+
['guestdefinitions', 'create'],
176+
async (payload) => {
177+
const { data } = await createGuestDefinition(payload);
178+
return data;
179+
},
180+
{
181+
onSuccess: () => {
182+
queryClient.invalidateQueries(['guestdefinitions']);
183+
}
184+
}
185+
);
186+
};
187+
188+
export const useEditGuestDefinitions = (id: string) => {
189+
const queryClient = useQueryClient();
190+
return useMutation<GuestDefinition, Error, GuestDefinitionPayload>(
191+
['guestdefinitions', 'edit'],
192+
async (payload) => {
193+
const { data } = await editGuestDefinition(payload, id);
194+
return data;
195+
},
196+
{
197+
onSuccess: () => {
198+
queryClient.invalidateQueries(['guestdefinitions']);
199+
}
200+
}
201+
);
202+
};

src/frontend/src/utils/urls.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,10 @@ const allFaqs = () => `${recruitment()}/faqs`;
395395
const faqCreate = () => `${recruitment()}/faq/create`;
396396
const faqEdit = (id: string) => `${recruitment()}/faq/${id}/edit`;
397397
const faqDelete = (id: string) => `${recruitment()}/faq/${id}/delete`;
398+
const allGuestDefinitions = () => `${recruitment()}/guestdefinitions`;
399+
const guestDefinitionDelete = (id: string) => `${recruitment()}/guestdefinition/${id}/delete`;
400+
const guestDefinitionCreate = () => `${recruitment()}/guestdefinition/create`;
401+
const guestDefintionEdit = (id: string) => `${recruitment()}/guestdefinition/${id}/edit`;
398402

399403
/************** Onboarding Endpoints ***************/
400404
const onboarding = () => `${API_URL}/onboarding`;
@@ -782,6 +786,10 @@ export const apiUrls = {
782786
imageById,
783787
reorderTasks,
784788
reorderChecklistItems,
789+
allGuestDefinitions,
790+
guestDefinitionDelete,
791+
guestDefinitionCreate,
792+
guestDefintionEdit,
785793

786794
popUps,
787795
popUpsCurrentUser,

src/shared/src/types/recruitment-types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,17 @@ export interface FrequentlyAskedQuestion {
1515
dateDeleted?: Date;
1616
}
1717

18+
export enum GuestDefinitionType {
19+
PROJECT_MANAGEMENT = 'PROJECT_MANAGEMENT',
20+
INFO_PAGE = 'INFO_PAGE'
21+
}
22+
1823
export interface GuestDefinition {
1924
definitionId: string;
2025
term: string;
2126
description: string;
2227
order: number;
28+
type: GuestDefinitionType;
2329
buttonText?: string;
2430
buttonLink?: string;
2531
icon?: string;

0 commit comments

Comments
 (0)