Newer
Older
taehui / taehui-fe / src / forum / CommentView.tsx
@Taehui Taehui on 8 Mar 3 KB 2024-03-08 오후 10:04
import { ReactNode, useMemo, useState } from "react";
import { observer } from "mobx-react-lite";
import { useParams } from "react-router-dom";
import { toast } from "react-toastify";
import { Badge, Button, Col, Row } from "reactstrap";
import { useTranslation } from "react-i18next";
import ReactTextareaAutosize from "react-textarea-autosize";
import { sprintf } from "sprintf-js";
import { getMillis } from "taehui-ts/date";

import { useAvatarStore } from "src/Stores";
import { wwwAXIOS } from "src/Www";
import CommentItem from "src/forum/CommentItem";
import AvatarTitle from "src/AvatarTitle";
import { CommentAPIComment } from "src/wwwAPI";
import useGetComment from "./useGetComment";

const CommentView = observer(() => {
  const { t } = useTranslation();
  const { totem, taehuiAvatarID, taehuiAvatarName, taehuiLevel } =
    useAvatarStore();
  const [inputText, setInputText] = useState("");

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

  const { data: comments } = useGetComment(essayID);

  const commentComponents = useMemo(() => {
    const commentComponents: ReactNode[] = [];

    const setCommentComponents =
      (level: number) =>
      ({
        commentID,
        avatarID,
        avatarName,
        date,
        text,
        comments,
      }: CommentAPIComment) => {
        commentComponents.push(
          <CommentItem
            commentID={commentID}
            avatarID={avatarID}
            avatarName={avatarName}
            date={date}
            text={text}
            level={level}
          />,
        );

        comments.forEach(setCommentComponents(level + 1));
      };

    comments.forEach((comment) => {
      setCommentComponents(0)(comment);
    });

    return commentComponents;
  }, [comments]);

  return (
    <>
      <Row className="g-0">
        <Col className="m-1">
          <Badge>{sprintf(t("commentCount"), commentComponents.length)}</Badge>
        </Col>
      </Row>
      {commentComponents}
      {taehuiLevel >= 1 && (
        <Row className="g-0">
          <AvatarTitle avatarID={taehuiAvatarID} avatarName={taehuiAvatarName}>
            <Row className="g-0">
              <Col className="m-1">
                <ReactTextareaAutosize
                  className="form-control"
                  placeholder={t("text")}
                  value={inputText}
                  onChange={({ target: { value } }) => {
                    setInputText(value);
                  }}
                />
              </Col>
              <Col className="m-1" xs="auto">
                <Button
                  color="success"
                  onClick={async () => {
                    if (inputText) {
                      const { status } = await wwwAXIOS.post(
                        `/comment/${essayID}`,
                        { targetCommentID: -1, text: inputText },
                        {
                          headers: {
                            millis: getMillis(),
                            totem,
                          },
                        },
                      );
                      if (status === 201) {
                        window.location.reload();
                      }
                    } else {
                      toast.error(t("failedValidation"));
                    }
                  }}
                >
                  {t("postComment")}
                </Button>
              </Col>
            </Row>
          </AvatarTitle>
        </Row>
      )}
    </>
  );
});

export default CommentView;