v3: added comment likes, added votes/likes list view, added db migrations mechanism, updated project dependencies
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 42s

This commit is contained in:
khannurien
2026-06-21 14:17:56 +00:00
parent 888aae45cf
commit 7afb5d3f07
25 changed files with 1475 additions and 840 deletions

View File

@@ -1,3 +1,7 @@
import { useRef, useState } from "react";
import { API_URL } from "../config/api.ts";
import { UserListPopover } from "./UserListPopover.tsx";
interface VoteButtonProps {
dumpId: string;
count: number;
@@ -10,16 +14,42 @@ interface VoteButtonProps {
export function VoteButton(
{ dumpId, count, voted, disabled, onCast, onRemove }: VoteButtonProps,
) {
const [popoverOpen, setPopoverOpen] = useState(false);
const countRef = useRef<HTMLSpanElement>(null);
return (
<button
type="button"
className={`vote-btn${voted ? " vote-btn--active" : ""}`}
onClick={() => voted ? onRemove(dumpId) : onCast(dumpId)}
disabled={disabled}
aria-label={voted ? "Remove vote" : "Upvote"}
title={disabled ? "Log in to vote" : undefined}
>
{count}
</button>
<>
<button
type="button"
className={`vote-btn${voted ? " vote-btn--active" : ""}`}
onClick={() => voted ? onRemove(dumpId) : onCast(dumpId)}
disabled={disabled}
aria-label={voted ? "Remove vote" : "Upvote"}
title={disabled ? "Log in to vote" : undefined}
>
{" "}
{count > 0
? (
<span
ref={countRef}
className="vote-count-clickable"
onClick={(e) => {
e.stopPropagation();
setPopoverOpen((o) => !o);
}}
>
{count}
</span>
)
: count}
</button>
{popoverOpen && (
<UserListPopover
anchorRef={countRef}
onClose={() => setPopoverOpen(false)}
fetchUrl={`${API_URL}/api/dumps/${dumpId}/voters`}
/>
)}
</>
);
}