Skip to content

Commit

Permalink
fix(upvote): 🐛 fix showing wrong upvote count
Browse files Browse the repository at this point in the history
  • Loading branch information
mcnaveen committed Sep 27, 2024
1 parent bccbc3a commit df5f0b5
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 21 deletions.
30 changes: 22 additions & 8 deletions app/api/upvote/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,45 @@ export async function POST(request: NextRequest): Promise<NextResponse> {
},
});

let upvote;

if (existingUpvote) {
upvote = await db.upvote.update({
await db.upvote.delete({
where: {
postId_userId: {
postId: postId,
userId: user.id,
},
},
data: {
isActive: !existingUpvote.isActive,
});

const upvoteCount = await db.upvote.count({
where: {
postId: postId,
isActive: true,
},
});

return NextResponse.json({ message: "Upvote removed", upvoteCount });
} else {
upvote = await db.upvote.create({
await db.upvote.create({
data: {
postId: postId,
userId: user.id,
isActive: true,
},
});
}

return NextResponse.json({ message: "Upvote toggled", upvote });
const upvoteCount = await db.upvote.count({
where: {
postId: postId,
isActive: true,
},
});

return NextResponse.json({
message: "Upvote added",
upvoteCount,
});
}
} catch (error) {
if (error instanceof Error) {
return NextResponse.json({ message: error.message }, { status: 403 });
Expand Down
2 changes: 2 additions & 0 deletions components/posts/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const PostsCard: React.FC<PostsCardProps> = ({
isUpvoted={isUpvoted}
postId={post?.id}
upvoteCount={upvoteCount}
userId={currentUserId}
/>
</div>
<div className="min-w-0 flex-grow">
Expand Down Expand Up @@ -130,6 +131,7 @@ export const PostsCard: React.FC<PostsCardProps> = ({
isUpvoted={isUpvoted}
postId={post.id}
upvoteCount={upvoteCount}
userId={currentUserId}
/>
<Avatar className="h-6 w-6">
<AvatarImage
Expand Down
45 changes: 33 additions & 12 deletions components/posts/upvote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { ChevronUp } from "lucide-react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { useSession } from "next-auth/react";
import { useContext } from "react";
import { useContext, useState } from "react";
import { numify } from "numify";

import { LoginDialogContext } from "@/app/provider";

Expand All @@ -15,11 +16,15 @@ export const UpvoteButton = ({
isUpvoted,
postId,
upvoteCount,
userId,
}: {
isUpvoted: boolean;
postId: string;
upvoteCount: number;
userId: string;
}) => {
const [isActive, setIsActive] = useState(isUpvoted);
const [count, setCount] = useState(upvoteCount);
const queryClient = useQueryClient();

const session = useSession();
Expand All @@ -39,14 +44,21 @@ export const UpvoteButton = ({
return response.json();
},
onSuccess: (newData) => {
queryClient.setQueryData(["post", postId], (oldData: any) => ({
...oldData,
upvoteCount: isUpvoted ? upvoteCount - 1 : upvoteCount + 1,
upvotes: oldData.upvotes.map((upvote: any) =>
upvote.userId === newData.upvote.userId ? newData.upvote : upvote,
),
}));
toast.success(isUpvoted ? "Upvote removed!" : "Upvoted!");
setIsActive(!isActive);
setCount(newData.upvoteCount);
queryClient.setQueryData(["post", postId], (oldData: any) => {
if (!oldData) return oldData;

return {
...oldData,
upvoteCount: newData.upvoteCount,
upvotes: isActive
? oldData.upvotes.filter((upvote: any) => upvote.userId !== userId)
: [...(oldData.upvotes || []), { userId, postId }],
};
});
queryClient.invalidateQueries({ queryKey: ["post", postId] });
toast.success(newData.message);
},
onError: (err) => {
toast.error(err.message);
Expand All @@ -68,14 +80,23 @@ export const UpvoteButton = ({
return (
<>
<Button
className={`rounded-full ${isUpvoted ? "bg-blue-500 text-white" : ""}`}
className={`h-12 w-12 rounded-xl ${isActive ? "border-blue-200 bg-blue-100" : ""}`}
size="icon"
variant="outline"
variant={"outline"}
onClick={
session.status === "authenticated" ? handleUpvote : handleLoginDialog
}
>
<ChevronUp className="h-4 w-4" />
<span className="flex flex-col items-center">
<ChevronUp
className={`h-4 w-4 ${isActive ? "font-bold text-blue-500" : ""}`}
/>
<span
className={`text-xs ${isActive ? "font-bold text-blue-500" : ""}`}
>
{count ? numify(count) : null}
</span>
</span>
</Button>
<LoginDialog open={showLoginDialog} onOpenChange={setShowLoginDialog} />
</>
Expand Down
1 change: 0 additions & 1 deletion prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,6 @@ model Upvote {
userId String
boardId String?
projectId String?
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Expand Down

0 comments on commit df5f0b5

Please sign in to comment.