[resumes][feat] Fetch resume details from database (#322)

* [resumes][feat] Add resume details router

* [resumes][feat] Change review page to dynamic routing

* [resumes][feat] Toggle resume star button

* [resumes][refactor] Revert routers to User model
This commit is contained in:
Peirong
2022-10-07 23:33:24 +08:00
committed by GitHub
parent 5507c6a9d2
commit 2e947f5fb0
12 changed files with 371 additions and 187 deletions

View File

@ -2,6 +2,7 @@ import superjson from 'superjson';
import { createRouter } from './context';
import { protectedExampleRouter } from './protected-example-router';
import { resumesDetailsRouter } from './resumes-details-router';
import { resumesResumeUserRouter } from './resumes-resume-user-router';
import { resumeReviewsRouter } from './resumes-reviews-router';
import { resumesReviewsUserRouter } from './resumes-reviews-user-router';
@ -16,6 +17,7 @@ export const appRouter = createRouter()
.merge('auth.', protectedExampleRouter)
.merge('todos.', todosRouter)
.merge('todos.user.', todosUserRouter)
.merge('resumes.details.', resumesDetailsRouter)
.merge('resumes.resume.user.', resumesResumeUserRouter)
.merge('resumes.reviews.', resumeReviewsRouter)
.merge('resumes.reviews.user.', resumesReviewsUserRouter);

View File

@ -0,0 +1,79 @@
import { z } from 'zod';
import { createRouter } from './context';
export const resumesDetailsRouter = createRouter()
.query('find', {
input: z.object({
resumeId: z.string(),
}),
async resolve({ ctx, input }) {
const { resumeId } = input;
const userId = ctx.session?.user?.id;
// Use the resumeId to query all related information of a single resume
// from Resumesresume:
return await ctx.prisma.resumesResume.findUnique({
include: {
_count: {
select: {
stars: true,
},
},
stars: {
where: {
userId,
},
},
user: {
select: {
name: true,
},
},
},
where: {
id: resumeId,
},
});
},
})
.mutation('update_star', {
input: z.object({
resumeId: z.string(),
}),
async resolve({ ctx, input }) {
const { resumeId } = input;
// Update_star will only be called if user is logged in
const userId = ctx.session!.user!.id;
// Use the resumeId and resumeProfileId to check if star exists
const resumesStar = await ctx.prisma.resumesStar.findUnique({
select: {
id: true,
},
where: {
userId_resumeId: {
resumeId,
userId,
},
},
});
if (resumesStar === null) {
return await ctx.prisma.resumesStar.create({
data: {
resumeId,
userId,
},
});
}
return await ctx.prisma.resumesStar.delete({
where: {
userId_resumeId: {
resumeId,
userId,
},
},
});
},
});

View File

@ -15,23 +15,12 @@ export const resumesResumeUserRouter = createProtectedRouter().mutation(
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user.id;
const resumeProfile = await ctx.prisma.resumesProfile.upsert({
create: {
userId,
},
update: {},
where: {
userId,
},
});
// TODO: Store file in file storage and retrieve URL
return await ctx.prisma.resumesResume.create({
data: {
...input,
resumesProfileId: resumeProfile.id,
url: '',
userId,
},
});
},

View File

@ -7,18 +7,9 @@ export const resumeReviewsRouter = createRouter().query('list', {
resumeId: z.string(),
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id;
const { resumeId } = input;
const { resumesProfileId } =
await ctx.prisma.resumesResume.findUniqueOrThrow({
select: {
resumesProfileId: true,
},
where: {
id: resumeId,
},
});
// For this resume, we retrieve every comment's information, along with:
// The user's name and image to render
// Number of votes, and whether the user (if-any) has voted
@ -29,20 +20,16 @@ export const resumeReviewsRouter = createRouter().query('list', {
votes: true,
},
},
resumesProfile: {
include: {
user: {
select: {
image: true,
name: true,
},
},
user: {
select: {
image: true,
name: true,
},
},
votes: {
take: 1,
where: {
resumesProfileId,
userId,
},
},
},

View File

@ -6,8 +6,8 @@ import { createProtectedRouter } from './context';
type IResumeCommentInput = Readonly<{
description: string;
resumeId: string;
resumesProfileId: string;
section: ResumesSection;
userId: string;
}>;
export const resumesReviewsUserRouter = createProtectedRouter().mutation(
@ -22,19 +22,10 @@ export const resumesReviewsUserRouter = createProtectedRouter().mutation(
skills: z.string(),
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id;
const { resumeId, education, experience, general, projects, skills } =
input;
const { resumesProfileId } =
await ctx.prisma.resumesResume.findUniqueOrThrow({
select: {
resumesProfileId: true,
},
where: {
id: resumeId,
},
});
// For each section, convert them into ResumesComment model if provided
const comments: Array<IResumeCommentInput> = [
{ description: education, section: ResumesSection.EDUCATION },
@ -50,8 +41,8 @@ export const resumesReviewsUserRouter = createProtectedRouter().mutation(
return {
description,
resumeId,
resumesProfileId,
section,
userId,
};
});