mirror of
https://github.com/yangshun/tech-interview-handbook.git
synced 2025-07-28 20:52:00 +08:00
[resumes][feat] add padding and hide scrollbar for comments (#404)
* [resumes][feat] add padding and hide scrollbar for comments * [resumes][feat] add findUserTopUpvotedCommentCount query
This commit is contained in:
@ -17,12 +17,15 @@ export default function ResumeUserBadges({ userId }: Props) {
|
|||||||
'resumes.resume.findUserMaxResumeUpvoteCount',
|
'resumes.resume.findUserMaxResumeUpvoteCount',
|
||||||
{ userId },
|
{ userId },
|
||||||
]);
|
]);
|
||||||
|
const userTopUpvotedCommentCountQuery = trpc.useQuery([
|
||||||
|
'resumes.resume.findUserTopUpvotedCommentCount',
|
||||||
|
{ userId },
|
||||||
|
]);
|
||||||
|
|
||||||
// TODO: Add other badges in
|
|
||||||
const payload: BadgePayload = {
|
const payload: BadgePayload = {
|
||||||
maxResumeUpvoteCount: userMaxResumeUpvoteCountQuery.data ?? 0,
|
maxResumeUpvoteCount: userMaxResumeUpvoteCountQuery.data ?? 0,
|
||||||
reviewedResumesCount: userReviewedResumeCountQuery.data ?? 0,
|
reviewedResumesCount: userReviewedResumeCountQuery.data ?? 0,
|
||||||
topUpvotedCommentCount: 20,
|
topUpvotedCommentCount: userTopUpvotedCommentCountQuery.data ?? 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -56,6 +56,7 @@ export default function ResumeCommentsList({
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
|
className="-mb-2"
|
||||||
display="block"
|
display="block"
|
||||||
label="Add your review"
|
label="Add your review"
|
||||||
variant="tertiary"
|
variant="tertiary"
|
||||||
@ -73,7 +74,7 @@ export default function ResumeCommentsList({
|
|||||||
<Spinner display="block" size="lg" />
|
<Spinner display="block" size="lg" />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="m-2 flow-root h-[calc(100vh-20rem)] w-full flex-col space-y-4 overflow-y-auto overflow-x-hidden">
|
<div className="scrollbar-hide m-2 flow-root h-[calc(100vh-20rem)] w-full flex-col space-y-4 overflow-y-auto overflow-x-hidden pt-14 pb-6">
|
||||||
{RESUME_COMMENTS_SECTIONS.map(({ label, value }) => {
|
{RESUME_COMMENTS_SECTIONS.map(({ label, value }) => {
|
||||||
const comments = commentsQuery.data
|
const comments = commentsQuery.data
|
||||||
? commentsQuery.data.filter((comment: ResumeComment) => {
|
? commentsQuery.data.filter((comment: ResumeComment) => {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
import { Vote } from '@prisma/client';
|
||||||
|
|
||||||
import { createRouter } from '../context';
|
import { createRouter } from '../context';
|
||||||
|
|
||||||
@ -149,11 +150,16 @@ export const resumesRouter = createRouter()
|
|||||||
async resolve({ ctx, input }) {
|
async resolve({ ctx, input }) {
|
||||||
return await ctx.prisma.resumesResume.count({
|
return await ctx.prisma.resumesResume.count({
|
||||||
where: {
|
where: {
|
||||||
|
// User has commented on this resume
|
||||||
comments: {
|
comments: {
|
||||||
some: {
|
some: {
|
||||||
userId: input.userId,
|
userId: input.userId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// Not user's own resume
|
||||||
|
userId: {
|
||||||
|
not: input.userId,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -164,18 +170,18 @@ export const resumesRouter = createRouter()
|
|||||||
}),
|
}),
|
||||||
async resolve({ ctx, input }) {
|
async resolve({ ctx, input }) {
|
||||||
const highestUpvotedResume = await ctx.prisma.resumesResume.findFirst({
|
const highestUpvotedResume = await ctx.prisma.resumesResume.findFirst({
|
||||||
include: {
|
orderBy: {
|
||||||
|
stars: {
|
||||||
|
_count: 'desc',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
_count: {
|
_count: {
|
||||||
select: {
|
select: {
|
||||||
stars: true,
|
stars: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
orderBy: {
|
|
||||||
stars: {
|
|
||||||
_count: 'desc',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
where: {
|
where: {
|
||||||
userId: input.userId,
|
userId: input.userId,
|
||||||
},
|
},
|
||||||
@ -183,14 +189,61 @@ export const resumesRouter = createRouter()
|
|||||||
|
|
||||||
return highestUpvotedResume?._count?.stars ?? 0;
|
return highestUpvotedResume?._count?.stars ?? 0;
|
||||||
},
|
},
|
||||||
|
})
|
||||||
|
.query('findUserTopUpvotedCommentCount', {
|
||||||
|
input: z.object({
|
||||||
|
userId: z.string(),
|
||||||
|
}),
|
||||||
|
async resolve({ ctx, input }) {
|
||||||
|
const resumes = await ctx.prisma.resumesResume.findMany({
|
||||||
|
select: {
|
||||||
|
comments: {
|
||||||
|
select: {
|
||||||
|
userId: true,
|
||||||
|
votes: {
|
||||||
|
select: {
|
||||||
|
value: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let topUpvotedCommentCount = 0;
|
||||||
|
|
||||||
|
for (const resume of resumes) {
|
||||||
|
let highestVoteCount = 1;
|
||||||
|
|
||||||
|
// Get Map of {userId, voteCount} for each comment
|
||||||
|
const commentUpvotePairs = [];
|
||||||
|
for (const comment of resume.comments) {
|
||||||
|
const { userId, votes } = comment;
|
||||||
|
let voteCount = 0;
|
||||||
|
for (const vote of votes) {
|
||||||
|
if (vote.value === Vote.UPVOTE) {
|
||||||
|
voteCount++;
|
||||||
|
} else {
|
||||||
|
voteCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (voteCount >= highestVoteCount) {
|
||||||
|
highestVoteCount = voteCount;
|
||||||
|
commentUpvotePairs.push({ userId, voteCount });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter to get the userIds with the highest vote counts
|
||||||
|
const userIds = commentUpvotePairs
|
||||||
|
.filter((pair) => pair.voteCount === highestVoteCount)
|
||||||
|
.map((pair) => pair.userId);
|
||||||
|
|
||||||
|
// Increment if input userId is the highest voted comment
|
||||||
|
if (userIds.includes(input.userId)) {
|
||||||
|
topUpvotedCommentCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return topUpvotedCommentCount;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
// .query('findUserTopUpvotedCommentCount', {
|
|
||||||
// input: z.object({
|
|
||||||
// userId: z.string(),
|
|
||||||
// }),
|
|
||||||
// async resolve({ ctx, input }) {
|
|
||||||
// const highestUpvotedResume = await ctx.prisma.resumesComment.groupBy({
|
|
||||||
// by: ['resumeId'],
|
|
||||||
// })
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
"@tailwindcss/forms": "^0.5.3",
|
"@tailwindcss/forms": "^0.5.3",
|
||||||
"@tailwindcss/line-clamp": "^0.4.2",
|
"@tailwindcss/line-clamp": "^0.4.2",
|
||||||
"@tailwindcss/typography": "^0.5.7",
|
"@tailwindcss/typography": "^0.5.7",
|
||||||
|
"tailwind-scrollbar-hide": "^1.1.7",
|
||||||
"tailwindcss": "^3.1.8"
|
"tailwindcss": "^3.1.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,5 +23,6 @@ module.exports = {
|
|||||||
require('@tailwindcss/forms'),
|
require('@tailwindcss/forms'),
|
||||||
require('@tailwindcss/line-clamp'),
|
require('@tailwindcss/line-clamp'),
|
||||||
require('@tailwindcss/typography'),
|
require('@tailwindcss/typography'),
|
||||||
|
require('tailwind-scrollbar-hide'),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
@ -13791,6 +13791,11 @@ synchronous-promise@^2.0.15:
|
|||||||
resolved "https://registry.npmjs.org/synchronous-promise/-/synchronous-promise-2.0.16.tgz"
|
resolved "https://registry.npmjs.org/synchronous-promise/-/synchronous-promise-2.0.16.tgz"
|
||||||
integrity sha512-qImOD23aDfnIDNqlG1NOehdB9IYsn1V9oByPjKY1nakv2MQYCEMyX033/q+aEtYCpmYK1cv2+NTmlH+ra6GA5A==
|
integrity sha512-qImOD23aDfnIDNqlG1NOehdB9IYsn1V9oByPjKY1nakv2MQYCEMyX033/q+aEtYCpmYK1cv2+NTmlH+ra6GA5A==
|
||||||
|
|
||||||
|
tailwind-scrollbar-hide@^1.1.7:
|
||||||
|
version "1.1.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/tailwind-scrollbar-hide/-/tailwind-scrollbar-hide-1.1.7.tgz#90b481fb2e204030e3919427416650c54f56f847"
|
||||||
|
integrity sha512-X324n9OtpTmOMqEgDUEA/RgLrNfBF/jwJdctaPZDzB3mppxJk7TLIDmOreEDm1Bq4R9LSPu4Epf8VSdovNU+iA==
|
||||||
|
|
||||||
tailwindcss@^3.1.8:
|
tailwindcss@^3.1.8:
|
||||||
version "3.1.8"
|
version "3.1.8"
|
||||||
resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.8.tgz"
|
resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.8.tgz"
|
||||||
|
Reference in New Issue
Block a user