Add your review
Please fill in at least one section to submit your review
diff --git a/apps/portal/src/pages/resumes/[resumeId].tsx b/apps/portal/src/pages/resumes/[resumeId].tsx
index 52d4f3b7..012e80ca 100644
--- a/apps/portal/src/pages/resumes/[resumeId].tsx
+++ b/apps/portal/src/pages/resumes/[resumeId].tsx
@@ -4,7 +4,7 @@ import Error from 'next/error';
import Head from 'next/head';
import { useRouter } from 'next/router';
import { useSession } from 'next-auth/react';
-import { useEffect } from 'react';
+import { useEffect, useState } from 'react';
import {
AcademicCapIcon,
BriefcaseIcon,
@@ -22,12 +22,11 @@ import { trpc } from '~/utils/trpc';
export default function ResumeReviewPage() {
const ErrorPage = (
-
+
);
const { data: session } = useSession();
const router = useRouter();
const { resumeId } = router.query;
- const trpcContext = trpc.useContext();
// Safe to assert resumeId type as string because query is only sent if so
const detailsQuery = trpc.useQuery(
['resumes.resume.findOne', { resumeId: resumeId as string }],
@@ -35,31 +34,59 @@ export default function ResumeReviewPage() {
enabled: typeof resumeId === 'string',
},
);
- const starMutation = trpc.useMutation('resumes.star.user.create_or_delete', {
- onSuccess() {
- trpcContext.invalidateQueries(['resumes.resume.findOne']);
+ const starMutation = trpc.useMutation('resumes.resume.star', {
+ onError() {
+ setStarDetails({
+ isStarred: false,
+ numStars: starDetails.numStars - 1,
+ });
},
});
+ const unstarMutation = trpc.useMutation('resumes.resume.unstar', {
+ onError() {
+ setStarDetails({
+ isStarred: true,
+ numStars: starDetails.numStars + 1,
+ });
+ },
+ });
+ const [starDetails, setStarDetails] = useState({
+ isStarred: false,
+ numStars: 0,
+ });
useEffect(() => {
- if (detailsQuery.data?.stars.length) {
- document.getElementById('star-button')?.focus();
- } else {
- document.getElementById('star-button')?.blur();
+ if (detailsQuery?.data !== undefined) {
+ setStarDetails({
+ isStarred: !!detailsQuery.data?.stars.length,
+ numStars: detailsQuery.data?._count.stars ?? 0,
+ });
}
- }, [detailsQuery.data?.stars]);
+ }, [detailsQuery.data]);
const onStarButtonClick = () => {
+ setStarDetails({
+ isStarred: !starDetails.isStarred,
+ numStars: starDetails.isStarred
+ ? starDetails.numStars - 1
+ : starDetails.numStars + 1,
+ });
// Star button only rendered if resume exists
// Star button only clickable if user exists
- starMutation.mutate({
- resumeId: resumeId as string,
- });
+ if (starDetails.isStarred) {
+ unstarMutation.mutate({
+ resumeId: resumeId as string,
+ });
+ } else {
+ starMutation.mutate({
+ resumeId: resumeId as string,
+ });
+ }
};
return (
<>
- {detailsQuery.isError && ErrorPage}
+ {(detailsQuery.isError || detailsQuery.data === null) && ErrorPage}
{detailsQuery.isLoading && (
{' '}
@@ -71,14 +98,19 @@ export default function ResumeReviewPage() {
{detailsQuery.data.title}
-
+
{detailsQuery.data.title}
diff --git a/apps/portal/src/server/router/index.ts b/apps/portal/src/server/router/index.ts
index c018c3f7..8dd5e08c 100644
--- a/apps/portal/src/server/router/index.ts
+++ b/apps/portal/src/server/router/index.ts
@@ -28,7 +28,7 @@ export const appRouter = createRouter()
.merge('companies.', companiesRouter)
.merge('resumes.resume.', resumesRouter)
.merge('resumes.resume.user.', resumesResumeUserRouter)
- .merge('resumes.star.user.', resumesStarUserRouter)
+ .merge('resumes.resume.', resumesStarUserRouter)
.merge('resumes.reviews.', resumeReviewsRouter)
.merge('resumes.reviews.user.', resumesReviewsUserRouter)
.merge('questions.answers.comments.', questionsAnswerCommentRouter)
diff --git a/apps/portal/src/server/router/resumes/resumes-resume-router.ts b/apps/portal/src/server/router/resumes/resumes-resume-router.ts
index 177b076e..34d7d6f0 100644
--- a/apps/portal/src/server/router/resumes/resumes-resume-router.ts
+++ b/apps/portal/src/server/router/resumes/resumes-resume-router.ts
@@ -62,7 +62,9 @@ export const resumesRouter = createRouter()
},
stars: {
where: {
- userId,
+ OR: {
+ userId,
+ },
},
},
user: {
diff --git a/apps/portal/src/server/router/resumes/resumes-star-user-router.ts b/apps/portal/src/server/router/resumes/resumes-star-user-router.ts
index 40daea7d..9e780858 100644
--- a/apps/portal/src/server/router/resumes/resumes-star-user-router.ts
+++ b/apps/portal/src/server/router/resumes/resumes-star-user-router.ts
@@ -2,38 +2,14 @@ import { z } from 'zod';
import { createProtectedRouter } from '../context';
-export const resumesStarUserRouter = createProtectedRouter().mutation(
- 'create_or_delete',
- {
+export const resumesStarUserRouter = createProtectedRouter()
+ .mutation('unstar', {
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,
- },
- });
- }
+ const userId = ctx.session.user.id;
return await ctx.prisma.resumesStar.delete({
where: {
userId_resumeId: {
@@ -43,5 +19,19 @@ export const resumesStarUserRouter = createProtectedRouter().mutation(
},
});
},
- },
-);
+ })
+ .mutation('star', {
+ input: z.object({
+ resumeId: z.string(),
+ }),
+ async resolve({ ctx, input }) {
+ const { resumeId } = input;
+ const userId = ctx.session.user.id;
+ return await ctx.prisma.resumesStar.create({
+ data: {
+ resumeId,
+ userId,
+ },
+ });
+ },
+ });