👍 Upvotes
Implement Reddit-style upvotes on posts
cast-vote.ts:
import { supaClient } from "./supa-client";
export async function castVote({
postId,
userId,
voteType,
onSuccess = () => {},
}: {
postId: string;
userId: string;
voteType: "up" | "down";
onSuccess?: () => void;
}) {
await supaClient.from("post_votes").upsert(
{
post_id: postId,
user_id: userId,
vote_type: voteType,
},
{ onConflict: "post_id,user_id" }
);
onSuccess();
}
use-post-score.ts
import { RealtimeChannel } from "@supabase/supabase-js";
import { useEffect, useState } from "react";
import { supaClient } from "./supa-client";
export function usePostScore(postId: string, initialScore: number | undefined) {
const [score, setScore] = useState<number | undefined>(initialScore);
const [sub, setSub] = useState<RealtimeChannel | undefined>(undefined);
useEffect(() => {
if (score === undefined && initialScore !== undefined) {
setScore(initialScore);
}
if (!sub && postId) {
setSub(
supaClient
.channel(`post_${postId}_score`)
.on(
"postgres_changes",
{
event: "*",
schema: "public",
table: "post_score",
filter: `post_id=eq.${postId}`,
},
(payload) => {
setScore((payload.new as { score: number }).score as any);
}
)
.subscribe()
);
}
return () => {
sub?.unsubscribe();
};
}, [postId]);
return score;
}