JFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr{ gilour

File "thumb-buttons.tsx"

Full Path: /home/markqprx/iniasli.pro/resources/client/votes/thumb-buttons.tsx
File size: 2.2 KB
MIME-type: text/plain
Charset: utf-8

import {ThumbUpIcon} from '@common/icons/material/ThumbUp';
import {ThumbDownIcon} from '@common/icons/material/ThumbDown';
import {VotableModel} from '@common/votes/votable-model';
import {Button} from '@common/ui/buttons/button';
import {useStoreVote} from '@common/votes/requests/use-store-vote';
import {useState} from 'react';
import {FormattedNumber} from '@common/i18n/formatted-number';
import clsx from 'clsx';

interface Props {
  model: VotableModel;
  className?: string;
  showUpvotesOnly?: boolean;
}
export function ThumbButtons({model, className, showUpvotesOnly}: Props) {
  const changeVote = useStoreVote(model);

  const [upvotes, setUpvotes] = useState(model.upvotes || 0);
  const [downvotes, setDownvotes] = useState(model.downvotes || 0);
  const [currentVote, setCurrentVote] = useState(model.current_vote);

  const syncLocalState = (model: VotableModel) => {
    setUpvotes(model.upvotes);
    setDownvotes(model.downvotes);
    setCurrentVote(model.current_vote);
  };

  return (
    <div className={clsx(className, 'whitespace-nowrap')}>
      <Button
        className="gap-6"
        sizeClassName="px-8 py-4"
        color={currentVote === 'upvote' ? 'primary' : undefined}
        disabled={changeVote.isPending}
        aria-label="Upvote"
        onClick={() => {
          changeVote.mutate(
            {voteType: 'upvote'},
            {
              onSuccess: response => syncLocalState(response.model),
            },
          );
        }}
      >
        <ThumbUpIcon />
        <div>
          <FormattedNumber value={upvotes} />
        </div>
      </Button>
      {!showUpvotesOnly && (
        <Button
          className="gap-6"
          sizeClassName="px-8 py-4"
          color={currentVote === 'downvote' ? 'primary' : undefined}
          disabled={changeVote.isPending}
          aria-label="Downvote"
          onClick={() => {
            changeVote.mutate(
              {voteType: 'downvote'},
              {
                onSuccess: response => syncLocalState(response.model),
              },
            );
          }}
        >
          <ThumbDownIcon />
          <div>
            <FormattedNumber value={downvotes} />
          </div>
        </Button>
      )}
    </div>
  );
}