Files
gerbeur/src/components/VoteButton.tsx
khannurien 26f5abfa4e
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 41s
v3: fixed linter error, code format
2026-06-22 17:31:21 +00:00

56 lines
1.5 KiB
TypeScript

import { useRef, useState } from "react";
import { t } from "@lingui/core/macro";
import { API_URL } from "../config/api.ts";
import { UserListPopover } from "./UserListPopover.tsx";
interface VoteButtonProps {
dumpId: string;
count: number;
voted: boolean;
disabled?: boolean;
onCast: (dumpId: string) => void;
onRemove: (dumpId: string) => void;
}
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 ? t`Remove vote` : t`Upvote`}
title={disabled ? t`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`}
/>
)}
</>
);
}