Newer
Older
taehui / taehui-fe / src / app / [language] / forum / components / CommentItem.tsx
@Taehui Taehui on 3 Jun 7 KB v1.0.0
import usePostComment from "@/app/[language]/forum/query/usePostComment";
import usePutComment from "@/app/[language]/forum/query/usePutComment";
import useWipeComment from "@/app/[language]/forum/query/useWipeComment";
import AvatarDrawing from "@/components/AvatarDrawing";
import { useTaehuiStore } from "@/state/Stores";
import { observer } from "mobx-react-lite";
import { useTranslations } from "next-intl";
import { useParams } from "next/navigation";
import { useState } from "react";
import { Back, EraserFill, PencilFill, ReplyFill } from "react-bootstrap-icons";
import Button from "react-bootstrap/Button";
import ButtonGroup from "react-bootstrap/ButtonGroup";
import Col from "react-bootstrap/Col";
import Collapse from "react-bootstrap/Collapse";
import FormControl from "react-bootstrap/FormControl";
import InputGroup from "react-bootstrap/InputGroup";
import Row from "react-bootstrap/Row";
import Stack from "react-bootstrap/Stack";
import ReactTextareaAutosize from "react-textarea-autosize";
import { toast } from "react-toastify";
import Swal from "sweetalert2";
import { getDatetime } from "taehui-lib/date";

export default observer(
  ({
    commentID,
    text,
    avatarID,
    avatarName,
    date,
    level,
  }: {
    commentID: number;
    text: string;
    date: string;
    avatarID: string;
    avatarName: string;
    level: number;
  }) => {
    const t = useTranslations();
    const { totem, taehuiAvatarID, taehuiAvatarName, isSU } = useTaehuiStore();

    const { essayID } = useParams<{ essayID: string }>();

    const [inputModify, setInputModify] = useState("");
    const [inputPost, setInputPost] = useState("");
    const [isPostOpened, setPostOpened] = useState(false);
    const [isModifyOpened, setModifyOpened] = useState(false);

    const { mutateAsync: wipeComment } = useWipeComment();
    const { mutateAsync: putComment } = usePutComment();
    const { mutateAsync: postComment } = usePostComment();

    const isAllowModify = isSU || taehuiAvatarID === avatarID;

    return (
      <>
        <Row style={{ marginLeft: -9 + 48 * level }} className="flex-nowrap">
          {isModifyOpened ? (
            <>
              <Col xs="auto">
                <AvatarDrawing avatarID={avatarID} />
              </Col>
              <Col className="cc">
                {avatarName}
                <InputGroup>
                  <FormControl
                    as={ReactTextareaAutosize}
                    placeholder={t("text")}
                    value={inputModify}
                    onChange={({ target: { value } }) => {
                      setInputModify(value);
                    }}
                  />
                  <Button
                    variant="success"
                    onClick={async () => {
                      if (inputModify) {
                        await putComment({ commentID, text: inputModify });
                        setModifyOpened(false);
                      } else {
                        toast.error(t("failedValidation"));
                      }
                    }}
                  >
                    <PencilFill />
                  </Button>
                  <Button
                    variant="secondary"
                    onClick={() => {
                      setModifyOpened(false);
                    }}
                  >
                    <Back />
                  </Button>
                </InputGroup>
              </Col>
            </>
          ) : (
            <>
              <Col xs="auto">
                <AvatarDrawing avatarID={avatarID} />
              </Col>
              <Col className="cc">
                <Stack gap={2}>
                  <span>{avatarName}</span>
                  <span style={{ whiteSpace: "break-spaces" }}>{text}</span>
                </Stack>
              </Col>
              <Col xs="auto">
                <Stack gap={2}>
                  {getDatetime(date)}
                  {(totem || isAllowModify) && (
                    <ButtonGroup>
                      {totem && (
                        <Button
                          onClick={() => {
                            if (totem) {
                              setPostOpened(!isPostOpened);
                            }
                          }}
                        >
                          <ReplyFill />
                        </Button>
                      )}
                      {isAllowModify && (
                        <Button
                          variant="warning"
                          onClick={() => {
                            if (totem) {
                              setInputModify(text);
                              setModifyOpened(true);
                            }
                          }}
                        >
                          <PencilFill />
                        </Button>
                      )}
                      {isAllowModify && (
                        <Button
                          variant="danger"
                          onClick={async () => {
                            if (
                              (
                                await Swal.fire({
                                  title: "Taehui",
                                  text: t("wipeCommentText"),
                                  icon: "question",
                                  showDenyButton: true,
                                })
                              ).isConfirmed
                            ) {
                              await wipeComment({ commentID, totem });
                            }
                          }}
                        >
                          <EraserFill />
                        </Button>
                      )}
                    </ButtonGroup>
                  )}
                </Stack>
              </Col>
            </>
          )}
        </Row>
        <Collapse in={isPostOpened}>
          <Row style={{ marginLeft: -9 + 48 * (level + 1) }}>
            <Col xs="auto">
              <AvatarDrawing avatarID={taehuiAvatarID} />
            </Col>
            <Col>
              {taehuiAvatarName}
              <InputGroup>
                <FormControl
                  as={ReactTextareaAutosize}
                  value={inputPost}
                  onChange={({ target: { value } }) => {
                    setInputPost(value);
                  }}
                />
                <Button
                  variant="success"
                  onClick={async () => {
                    if (inputPost) {
                      await postComment({
                        essayID,
                        targetCommentID: commentID,
                        text: inputPost,
                      });
                      setPostOpened(false);
                      setInputPost("");
                    } else {
                      toast.error(t("failedValidation"));
                    }
                  }}
                >
                  <PencilFill />
                </Button>
              </InputGroup>
            </Col>
          </Row>
        </Collapse>
      </>
    );
  },
);