Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 613 | Rev 735 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

import React, { useEffect, useState } from "react";
import { axios } from "../../utils";
import { useLocation } from "react-router-dom";
import { getBackendVars } from "../../services/backendVars";
import { addNotification } from "../../redux/notification/notification.actions";
import { Col, Container, Row } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import parse from "html-react-parser";

import TungstenIcon from "@mui/icons-material/Tungsten";
import RecommendIcon from "@mui/icons-material/Recommend";
import FavoriteIcon from "@mui/icons-material/FavoriteTwoTone";
import SendOutlinedIcon from "@mui/icons-material/SendOutlined";
import ChatOutlinedIcon from "@mui/icons-material/ChatOutlined";
import EmojiEmotionsIcon from "@mui/icons-material/EmojiEmotions";
import VolunteerActivismIcon from "@mui/icons-material/VolunteerActivism";

import {
  CommentForm,
  CommentsList,
} from "../../components/feed/CommentSection";
import HomeNews from "../../components/widgets/default/HomeNews";
import InputOption from "../../components/dashboard/linkedin/action-button/InputOption";
import withExternalShare from "../../components/dashboard/linkedin/withExternalShare";
import Paraphrase from "../../components/UI/Paraphrase";
import StyledContainer from "../../components/widgets/WidgetLayout";
import withReactions from "../../hocs/withReaction";
import MobileShare from "../../components/dashboard/linkedin/mobile-share/MobileShare";

const PostViewPage = () => {
  const [post, setPost] = useState({});
  const [totalSends, setTotalSends] = useState(0);
  const [reactions, setReactions] = useState([]);
  const [myReaction, setMyReaction] = useState("");
  const [totalReactions, setTotalReactions] = useState(0);
  const [isMobile, setIsMobile] = useState(false);
  const [comments, setComments] = useState([]);
  const [showComments, setShowComments] = useState(false);
  const labels = useSelector(({ intl }) => intl.labels);
  const dispatch = useDispatch();
  const { pathname } = useLocation();

  const reactionsOptions = [
    {
      type: "r",
      icon: <RecommendIcon style={{ color: "#7405f9" }} />,
    },
    {
      type: "s",
      icon: <VolunteerActivismIcon style={{ color: "#6495ED" }} />,
    },
    {
      type: "l",
      icon: <FavoriteIcon style={{ color: "#DF704D" }} />,
    },
    {
      type: "i",
      icon: (
        <TungstenIcon
          style={{ color: "#F5BB5C", transform: "rotate(180deg)" }}
        />
      ),
    },
    {
      type: "f",
      icon: <EmojiEmotionsIcon style={{ color: "#FF7F50" }} />,
    },
  ];

  const displayCommentSection = () => {
    setShowComments(!showComments);
  };

  const getComments = () => {
    axios.get(post.comments_url).then((response) => {
      const { data, success } = response.data;

      if (!success) {
        const errorMessage =
          typeof data === "string" ? data : "Error interno. Intente más tarde.";

        dispatch(addNotification({ style: "danger", msg: errorMessage }));
        return;
      }

      setComments(data);
    });
  };

  const handleExternalShare = (value) => {
    setTotalSends(value);
  };

  const ExternalShareButton = withExternalShare(
    InputOption,
    post.share_external_url
  );

  const ReactionButton = withReactions(InputOption, {
    saveUrl: post.save_reaction_url,
    deleteUrl: post.delete_reaction_url,
    currentReaction: myReaction,
    onSelect: (reactions) => setReactions(reactions),
  });

  const addComment = ({ comment }) => {
    const formData = new FormData();
    formData.append("comment", comment);

    axios.post(post.comments_add_url, formData).then((response) => {
      const { success, data } = response.data;

      if (!success) {
        const errorMessage =
          typeof data === "string" ? data : "Error interno. Intente más tarde.";

        dispatch(addNotification({ style: "danger", msg: errorMessage }));
        return;
      }

      setComments((prevMessages) => [...prevMessages, data]);
    });
  };

  const deleteComment = (commentUnique, deleteCommentUrl) => {
    axios
      .post(deleteCommentUrl)
      .then((response) => {
        const { success, data } = response.data;

        if (!success) {
          const errorMessage =
            typeof data === "string"
              ? data
              : "Error interno. Intente más tarde.";

          dispatch(addNotification({ style: "danger", msg: errorMessage }));
          return;
        }

        setComments((prevComments) =>
          prevComments.filter((comment) => comment.unique !== commentUnique)
        );
        dispatch(addNotification({ style: "success", msg: data }));
      })
      .catch((error) => {
        dispatch(addNotification({ style: "danger", msg: error }));
        throw new Error(error);
      });
  };

  useEffect(() => {
    getBackendVars(pathname)
      .then((post) => {
        setMyReaction(post.my_reaction);
        setTotalSends(post.total_share_external);
        setPost(post);
      })
      .catch(() => {
        dispatch(
          addNotification({
            style: "danger",
            message: "Error interno. Por favor, inténtelo de nuevo más tarde.",
          })
        );
      });
  }, [pathname]);

  useEffect(() => {
    if (showComments && !comments.length) {
      getComments();
    }
  }, [showComments]);

  useEffect(() => {
    const feedReactions = reactions.reduce(
      (acc, reaction) => acc + Number(reaction.total),
      0
    );

    setTotalReactions(feedReactions);
  }, [reactions]);

  useEffect(() => {
    const ua = navigator.userAgent.toLowerCase();
    const isAndroid = ua.includes("android");

    if (isAndroid) {
      setIsMobile(true);
    }
  }, []);

  return (
    <Container>
      <Row>
        <Col md="8">
          <StyledContainer>
            <img src={post.image} />
            <StyledContainer.Header title={post.title} />
            <StyledContainer.Body>
              <Paraphrase>{post.description}</Paraphrase>
              {post.file && (
                <a href={post.file} download>
                  <img src="/images/extension/pdf.png" alt="pdf" />
                </a>
              )}
            </StyledContainer.Body>
            <div className="d-flex justify-content-between align-items-center px-3">
              <div className="reactions-counter">
                {reactionsOptions
                  .filter((option) =>
                    reactions.find(({ reaction }) => reaction === option.type)
                  )
                  .map((reaction) => reaction.icon)}
                <span>{totalReactions} reacciones</span>
              </div>
              {!!totalSends && (
                <span>{`${totalSends} ${labels.sends?.toLowerCase()}`}</span>
              )}
            </div>
            <StyledContainer.Actions>
              <ReactionButton />
              <InputOption
                icon={ChatOutlinedIcon}
                iconColor="gray"
                label={labels.comment}
                onClick={displayCommentSection}
              />
              {!isMobile ? (
                <ExternalShareButton
                  icon={SendOutlinedIcon}
                  iconColor="gray"
                  label={labels.send}
                  shareUrl={post.increment_external_counter_url}
                  setValue={handleExternalShare}
                />
              ) : (
                <MobileShare
                  shareData={{
                    title: "Leaders Linked",
                    text: parse(post.description),
                    url: post.share_external_url,
                  }}
                >
                  <SendOutlinedIcon />
                  {labels.send}
                </MobileShare>
              )}
            </StyledContainer.Actions>
            {showComments && (
              <>
                <CommentForm onSubmit={addComment} />
                <CommentsList comments={comments} onDelete={deleteComment} />
              </>
            )}
          </StyledContainer>
        </Col>
        <Col md="4">
          <HomeNews currentPost={post.uuid} />
        </Col>
      </Row>
    </Container>
  );
};

export default PostViewPage;