diff --git a/apps/portal/src/components/resumes/browse/ResumeListItem.tsx b/apps/portal/src/components/resumes/browse/ResumeListItem.tsx index c7f7677a..0d0a2756 100644 --- a/apps/portal/src/components/resumes/browse/ResumeListItem.tsx +++ b/apps/portal/src/components/resumes/browse/ResumeListItem.tsx @@ -1,9 +1,17 @@ import formatDistanceToNow from 'date-fns/formatDistanceToNow'; import Link from 'next/link'; +import { useSession } from 'next-auth/react'; import type { UrlObject } from 'url'; import { ChevronRightIcon } from '@heroicons/react/20/solid'; +import { + AcademicCapIcon, + BriefcaseIcon, + StarIcon as ColouredStarIcon, +} from '@heroicons/react/20/solid'; import { ChatBubbleLeftIcon, StarIcon } from '@heroicons/react/24/outline'; +import { trpc } from '~/utils/trpc'; + import type { Resume } from '~/types/resume'; type Props = Readonly<{ @@ -12,24 +20,47 @@ type Props = Readonly<{ }>; export default function BrowseListItem({ 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 ( <Link href={href}> - <div className="grid grid-cols-8 gap-4 border-b border-slate-200 p-4"> + <div className="grid grid-cols-8 gap-4 border-b border-slate-200 p-4 hover:bg-slate-100"> <div className="col-span-4"> {resumeInfo.title} <div className="mt-2 flex items-center justify-start text-xs text-indigo-500"> - {resumeInfo.role} - <div className="ml-6 rounded-md border border-indigo-500 p-1"> + <div className="flex"> + <BriefcaseIcon + aria-hidden="true" + className="mr-1.5 h-4 w-4 flex-shrink-0" + /> + {resumeInfo.role} + </div> + <div className="ml-4 flex"> + <AcademicCapIcon + aria-hidden="true" + className="mr-1.5 h-4 w-4 flex-shrink-0" + /> {resumeInfo.experience} </div> </div> - <div className="mt-2 flex justify-start text-xs text-slate-500"> - <div className="flex gap-2 pr-8"> + <div className="mt-4 flex justify-start text-xs text-slate-500"> + <div className="flex gap-2 pr-4"> <ChatBubbleLeftIcon className="w-4" /> {resumeInfo.numComments} comments </div> <div className="flex gap-2"> - <StarIcon className="w-4" /> + {isStarredQuery.data && sessionData?.user ? ( + <ColouredStarIcon className="w-4 text-yellow-400" /> + ) : ( + <StarIcon className="w-4" /> + )} {resumeInfo.numStars} stars </div> </div> diff --git a/apps/portal/src/components/resumes/browse/resumeConstants.ts b/apps/portal/src/components/resumes/browse/resumeConstants.ts index 42d79249..9f0a2058 100644 --- a/apps/portal/src/components/resumes/browse/resumeConstants.ts +++ b/apps/portal/src/components/resumes/browse/resumeConstants.ts @@ -46,16 +46,16 @@ export const EXPERIENCE: Array<FilterOption> = [ { label: 'Junior', value: 'Junior' }, { label: 'Senior', value: 'Senior' }, { - label: 'Fresh Grad (0-1 years)', - value: 'Fresh Grad (0-1 years)', + label: 'Entry Level (0 - 2 years)', + value: 'Entry Level (0 - 2 years)', }, { - label: 'Mid-level (2 - 5 years)', - value: 'Mid-level (2 - 5 years)', + label: 'Mid Level (3 - 5 years)', + value: 'Mid Level (3 - 5 years)', }, { - label: 'Senior (5+ years)', - value: 'Senior (5+ years)', + label: 'Senior Level (5+ years)', + value: 'Senior Level (5+ years)', }, ]; diff --git a/apps/portal/src/pages/resumes/browse.tsx b/apps/portal/src/pages/resumes/browse.tsx index d6631f4d..0331c720 100644 --- a/apps/portal/src/pages/resumes/browse.tsx +++ b/apps/portal/src/pages/resumes/browse.tsx @@ -144,7 +144,7 @@ export default function ResumeHomePage() { }, ); - const onClickNew = () => { + const onSubmitResume = () => { if (sessionData?.user?.id) { router.push('/resumes/submit'); } else { @@ -185,7 +185,9 @@ export default function ResumeHomePage() { <div className="w-screen sm:px-4 md:px-8"> <div className="grid grid-cols-12"> <div className="col-span-2 self-end"> - <h1 className="mb-4 tracking-tight text-gray-900">Filters</h1> + <h3 className="text-md mb-4 font-medium tracking-tight text-gray-900"> + Shortcuts: + </h3> </div> <div className="col-span-10"> <div className="border-grey-200 grid grid-cols-12 items-center gap-4 border-b pb-2"> @@ -240,8 +242,8 @@ export default function ResumeHomePage() { <button className="rounded-md bg-indigo-500 py-1 px-3 text-sm text-white" type="button" - onClick={onClickNew}> - New + onClick={onSubmitResume}> + Submit </button> </div> </div> @@ -252,7 +254,7 @@ export default function ResumeHomePage() { <div className="col-span-2"> <div className="w-100 pt-4 sm:pr-0 md:pr-4"> <form> - <h3 className="sr-only">Categories</h3> + <h3 className="sr-only">Shortcuts</h3> <ul className="flex flex-wrap justify-start gap-4 pb-6 text-sm font-medium text-gray-900" role="list"> @@ -266,7 +268,9 @@ export default function ResumeHomePage() { </li> ))} </ul> - + <h3 className="text-md my-4 font-medium tracking-tight text-gray-900"> + Explore these filters: + </h3> {filters.map((section) => ( <Disclosure key={section.id} @@ -328,7 +332,7 @@ export default function ResumeHomePage() { </form> </div> </div> - <div className="col-span-10 pr-8"> + <div className="col-span-10 mb-6"> {renderSignInButton && ( <ResumeSignInButton text={signInButtonText} /> )} diff --git a/apps/portal/src/server/router/resumes/resumes-resume-user-router.ts b/apps/portal/src/server/router/resumes/resumes-resume-user-router.ts index 3b0b5a0b..b443c3e2 100644 --- a/apps/portal/src/server/router/resumes/resumes-resume-user-router.ts +++ b/apps/portal/src/server/router/resumes/resumes-resume-user-router.ts @@ -112,4 +112,18 @@ export const resumesResumeUserRouter = createProtectedRouter() 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 }, + }, + }); + }, });