50 lines · 1.7 KB
import { useState } from "react";
import { addComment, setIssueOpenState } from "~/fns/issues";
import { useAction } from "~/hooks/use-action";
import { MarkdownEditor } from "./MarkdownEditor";
import { Button } from "./ui/Button";
import { ErrorBanner } from "./ui/Field";

type Props = {
  owner: string;
  repo: string;
  number: number;
  state: "open" | "closed";
  canToggle: boolean;
  merged?: boolean;
};

export function CommentComposer({ owner, repo, number, state, canToggle, merged = false }: Props) {
  const [body, setBody] = useState("");
  const comment = useAction(addComment);
  const toggle = useAction(setIssueOpenState);

  async function submit() {
    if (await comment.run({ data: { owner, repo, number, body, closeAfter: false } })) setBody("");
  }

  return (
    <div className="space-y-2">
      <ErrorBanner message={comment.error ?? toggle.error} />
      <MarkdownEditor value={body} onChange={setBody} owner={owner} repo={repo} />
      <div className="flex justify-end gap-2">
        {canToggle && !merged && (
          <Button
            pending={toggle.pending}
            onClick={async () => {
              if (body.trim()) await comment.run({ data: { owner, repo, number, body, closeAfter: false } });
              await toggle.run({ data: { owner, repo, number, state: state === "open" ? "closed" : "open" } });
              setBody("");
            }}
          >
            {state === "open" ? (body.trim() ? "Comment and close" : "Close") : "Reopen"}