[resumes][feat] add isStarredByUser field to Resumes ()

pull/385/head
Keane Chan 2 years ago committed by GitHub
parent 495cc8360c
commit 0666c99151
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,17 +1,14 @@
import formatDistanceToNow from 'date-fns/formatDistanceToNow'; import formatDistanceToNow from 'date-fns/formatDistanceToNow';
import Link from 'next/link'; import Link from 'next/link';
import { useSession } from 'next-auth/react';
import type { UrlObject } from 'url'; import type { UrlObject } from 'url';
import { ChevronRightIcon } from '@heroicons/react/20/solid';
import { import {
AcademicCapIcon, AcademicCapIcon,
BriefcaseIcon, BriefcaseIcon,
ChevronRightIcon,
StarIcon as ColouredStarIcon, StarIcon as ColouredStarIcon,
} from '@heroicons/react/20/solid'; } from '@heroicons/react/20/solid';
import { ChatBubbleLeftIcon, StarIcon } from '@heroicons/react/24/outline'; import { ChatBubbleLeftIcon, StarIcon } from '@heroicons/react/24/outline';
import { trpc } from '~/utils/trpc';
import type { Resume } from '~/types/resume'; import type { Resume } from '~/types/resume';
type Props = Readonly<{ type Props = Readonly<{
@ -19,16 +16,7 @@ type Props = Readonly<{
resumeInfo: Resume; resumeInfo: Resume;
}>; }>;
export default function BrowseListItem({ href, resumeInfo }: Props) { export default function ResumeListItem({ href, resumeInfo }: Props) {
const { data: sessionData } = useSession();
// Find out if user has starred this particular resume
const resumeId = resumeInfo.id;
const isStarredQuery = trpc.useQuery([
'resumes.resume.user.isResumeStarred',
{ resumeId },
]);
return ( return (
<Link href={href}> <Link href={href}>
<div className="grid grid-cols-8 gap-4 border-b border-slate-200 p-4 hover:bg-slate-100"> <div className="grid grid-cols-8 gap-4 border-b border-slate-200 p-4 hover:bg-slate-100">
@ -56,7 +44,7 @@ export default function BrowseListItem({ href, resumeInfo }: Props) {
{resumeInfo.numComments} comments {resumeInfo.numComments} comments
</div> </div>
<div className="flex gap-2"> <div className="flex gap-2">
{isStarredQuery.data && sessionData?.user ? ( {resumeInfo.isStarredByUser ? (
<ColouredStarIcon className="w-4 text-yellow-400" /> <ColouredStarIcon className="w-4 text-yellow-400" />
) : ( ) : (
<StarIcon className="w-4" /> <StarIcon className="w-4" />

@ -1,6 +1,6 @@
import { Spinner } from '@tih/ui'; import { Spinner } from '@tih/ui';
import ResumseListItem from './ResumeListItem'; import ResumeListItem from './ResumeListItem';
import type { Resume } from '~/types/resume'; import type { Resume } from '~/types/resume';
@ -22,7 +22,7 @@ export default function ResumeListItems({ isLoading, resumes }: Props) {
<ul role="list"> <ul role="list">
{resumes.map((resumeObj: Resume) => ( {resumes.map((resumeObj: Resume) => (
<li key={resumeObj.id}> <li key={resumeObj.id}>
<ResumseListItem <ResumeListItem
href={`/resumes/${resumeObj.id}`} href={`/resumes/${resumeObj.id}`}
resumeInfo={resumeObj} resumeInfo={resumeObj}
/> />

@ -49,7 +49,6 @@ export default function ResumeReviewPage() {
utils.invalidateQueries(['resumes.resume.findOne']); utils.invalidateQueries(['resumes.resume.findOne']);
}, },
}); });
const userIsOwner = const userIsOwner =
session?.user?.id != null && session.user.id === detailsQuery.data?.userId; session?.user?.id != null && session.user.id === detailsQuery.data?.userId;
@ -61,8 +60,6 @@ export default function ResumeReviewPage() {
return; return;
} }
// Star button only rendered if resume exists
// Star button only clickable if user exists
if (detailsQuery.data?.stars.length) { if (detailsQuery.data?.stars.length) {
unstarMutation.mutate({ unstarMutation.mutate({
resumeId: resumeId as string, resumeId: resumeId as string,

@ -22,7 +22,7 @@ export const resumesCommentsUserRouter = createProtectedRouter().mutation(
skills: z.string(), skills: z.string(),
}), }),
async resolve({ ctx, input }) { async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id; const userId = ctx.session.user.id;
const { resumeId, education, experience, general, projects, skills } = const { resumeId, education, experience, general, projects, skills } =
input; input;

@ -7,6 +7,7 @@ import type { Resume } from '~/types/resume';
export const resumesRouter = createRouter() export const resumesRouter = createRouter()
.query('findAll', { .query('findAll', {
async resolve({ ctx }) { async resolve({ ctx }) {
const userId = ctx.session?.user?.id;
const resumesData = await ctx.prisma.resumesResume.findMany({ const resumesData = await ctx.prisma.resumesResume.findMany({
include: { include: {
_count: { _count: {
@ -15,6 +16,13 @@ export const resumesRouter = createRouter()
stars: true, stars: true,
}, },
}, },
stars: {
where: {
OR: {
userId,
},
},
},
user: { user: {
select: { select: {
name: true, name: true,
@ -31,6 +39,7 @@ export const resumesRouter = createRouter()
createdAt: r.createdAt, createdAt: r.createdAt,
experience: r.experience, experience: r.experience,
id: r.id, id: r.id,
isStarredByUser: r.stars.length > 0,
location: r.location, location: r.location,
numComments: r._count.comments, numComments: r._count.comments,
numStars: r._count.stars, numStars: r._count.stars,

@ -17,7 +17,7 @@ export const resumesResumeUserRouter = createProtectedRouter()
url: z.string(), url: z.string(),
}), }),
async resolve({ ctx, input }) { async resolve({ ctx, input }) {
const userId = ctx.session?.user.id; const userId = ctx.session.user.id;
return await ctx.prisma.resumesResume.upsert({ return await ctx.prisma.resumesResume.upsert({
create: { create: {
@ -46,7 +46,7 @@ export const resumesResumeUserRouter = createProtectedRouter()
}) })
.query('findUserStarred', { .query('findUserStarred', {
async resolve({ ctx }) { async resolve({ ctx }) {
const userId = ctx.session?.user?.id; const userId = ctx.session.user.id;
const resumeStarsData = await ctx.prisma.resumesStar.findMany({ const resumeStarsData = await ctx.prisma.resumesStar.findMany({
include: { include: {
resume: { resume: {
@ -78,6 +78,7 @@ export const resumesResumeUserRouter = createProtectedRouter()
createdAt: rs.resume.createdAt, createdAt: rs.resume.createdAt,
experience: rs.resume.experience, experience: rs.resume.experience,
id: rs.resume.id, id: rs.resume.id,
isStarredByUser: true,
location: rs.resume.location, location: rs.resume.location,
numComments: rs.resume._count.comments, numComments: rs.resume._count.comments,
numStars: rs.resume._count.stars, numStars: rs.resume._count.stars,
@ -92,7 +93,7 @@ export const resumesResumeUserRouter = createProtectedRouter()
}) })
.query('findUserCreated', { .query('findUserCreated', {
async resolve({ ctx }) { async resolve({ ctx }) {
const userId = ctx.session?.user?.id; const userId = ctx.session.user.id;
const resumesData = await ctx.prisma.resumesResume.findMany({ const resumesData = await ctx.prisma.resumesResume.findMany({
include: { include: {
_count: { _count: {
@ -101,6 +102,11 @@ export const resumesResumeUserRouter = createProtectedRouter()
stars: true, stars: true,
}, },
}, },
stars: {
where: {
userId,
},
},
user: { user: {
select: { select: {
name: true, name: true,
@ -120,6 +126,7 @@ export const resumesResumeUserRouter = createProtectedRouter()
createdAt: r.createdAt, createdAt: r.createdAt,
experience: r.experience, experience: r.experience,
id: r.id, id: r.id,
isStarredByUser: r.stars.length > 0,
location: r.location, location: r.location,
numComments: r._count.comments, numComments: r._count.comments,
numStars: r._count.stars, numStars: r._count.stars,
@ -131,18 +138,4 @@ export const resumesResumeUserRouter = createProtectedRouter()
return resume; return resume;
}); });
}, },
})
.query('isResumeStarred', {
input: z.object({
resumeId: z.string(),
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id;
const { resumeId } = input;
return await ctx.prisma.resumesStar.findUnique({
where: {
userId_resumeId: { resumeId, userId },
},
});
},
}); });

@ -3,6 +3,7 @@ export type Resume = {
createdAt: Date; createdAt: Date;
experience: string; experience: string;
id: string; id: string;
isStarredByUser: boolean;
location: string; location: string;
numComments: number; numComments: number;
numStars: number; numStars: number;

Loading…
Cancel
Save