Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

/* eslint-disable react/prop-types */
import React, { useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import { useForm } from "react-hook-form";
import FormErrorFeedback from "../../../shared/form-error-feedback/FormErrorFeedback";
import FeedCommentTemplate from "./feed-comment/FeedCommentTemplate";
import { shareModalTypes } from "../../../redux/share-modal/shareModal.types";
import { axios } from "../../../utils";
import { feedTypes } from "../../../redux/feed/feed.types";
import { BsHeart, BsHeartFill } from 'react-icons/bs'
import { RiShareForwardLine } from 'react-icons/ri'
import { TbSend } from "react-icons/tb";
import { BiMessage, BiShareAlt } from "react-icons/bi";
import { EmailIcon, EmailShareButton, FacebookIcon, FacebookShareButton, RedditIcon, RedditShareButton, TelegramIcon, TelegramShareButton, TwitterIcon, TwitterShareButton, WhatsappIcon, WhatsappShareButton } from "react-share";

// Redux actions
import { openShareModal } from "../../../redux/share-modal/shareModal.actions";
import { addNotification } from "../../../redux/notification/notification.actions";
import { useRef } from "react";
import FeedModal from "./FeedModal";
import FeedHeader from "./FeedHeader";

const FeedTemplate = ({ feed, owner_shared, image, children }) => {

  // Destructuring feed data
  const {
    feed_unique,
    owner_name,
    owner_url,
    owner_image,
    owner_time_elapse,
    owner_file_image,
    owner_file_video,
    owner_file_document,
    feed_likes,
    feed_like_url,
    feed_unlike_url,
    feed_is_liked,
    feed_highlighted,
    feed_share_url,
    feed_delete_url,
    comments,
    comment_add_url,
    feed_share_external_url
  } = feed;

  // react hook form
  const { register, handleSubmit, errors } = useForm();

  const dispatch = useDispatch()

  const [totalComments, setTotalComments] = useState(comments.length || 0);
  const [feedIsLiked, setFeedIsLiked] = useState(feed_is_liked);
  const [commentsState, setCommentsState] = useState(comments);
  const [sharedState, setSharedState] = useState(owner_shared);
  const [likesState, setLikesState] = useState(feed_likes);

  const [shareOptions, setShareOptions] = useState(false)
  const [show, setShow] = useState(false);


  const shareContainer = useRef(null);

  useEffect(() => setSharedState(owner_shared), [owner_shared]);

  useEffect(() => {
    const handleClickOutside = (event) => {
      if (shareContainer.current && !shareContainer.current.contains(event.target)) {
        setShareOptions(false)
      }
    }
    document.addEventListener("mousedown", handleClickOutside);

    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, [shareContainer]);

  const likeHandler = (likeUrl) => {
    axios.post(likeUrl)
      .then((res) => {
        const { success, data } = res.data;
        if (!success) {
          setFeedIsLiked((previousState) => !previousState);
          dispatch(addNotification({
            style: "danger",
            msg: data,
          }));
        } else {
          setLikesState(data.likes)
          setFeedIsLiked(!feedIsLiked);
        }
      });
  };

  const submitCommentHandler = (data, e) => {
    const currentFormData = new FormData();
    for (let input in data) {
      currentFormData.append(input, data[input]);
    }
    axios.post(comment_add_url, currentFormData).then((res) => {
      const resData = res.data;
      const { data, success, total_comments } = resData;
      if (success) {
        const newComment = data;
        setTotalComments(total_comments);
        setCommentsState([newComment, ...commentsState]);
        e.target.reset();
      } else {
        dispatch(addNotification({
          style: "danger",
          msg: data,
        }));
      }
    });
  };

  const deleteCommentHandler = (commentUnique, deleteCommentUrl) => {
    axios.post(deleteCommentUrl)
      .then((res) => {
        const { success, data, total_comments } = res.data;
        if (!success) {
          dispatch(addNotification({
            style: "danger",
            msg: data,
          }));
        }
        setCommentsState(prevComments => prevComments.filter((comment) => comment.unique !== commentUnique));
        setTotalComments(total_comments);
        dispatch(addNotification({ style: "success", msg: data }));
      })
      .catch((error) =>
        dispatch(addNotification({ style: "danger", msg: error.message }))
      );
  };

  const btnShareHandler = () => dispatch(openShareModal(feed_share_url, shareModalTypes.SHARE, feedTypes.DASHBOARD, feed_unique))

  let commentsRender = null;
  if (commentsState.length) {
    commentsRender = (
      <div className='commentSection'>
        <div className={`comment-sec comment-sec-${feed_unique}`}>
          <ul>
            {[...commentsState].reverse().map((commentData) => {
              const { unique } = commentData;
              return (
                <FeedCommentTemplate
                  commentData={commentData}
                  onDeleteHandler={deleteCommentHandler}
                  key={unique}
                />
              );
            })}
          </ul>
        </div>
      </div>
    );
  }

  return (
    <React.Fragment>
      <FeedModal
        isShow={show}
        handleClose={() => setShow(false)}
        feed={feed}
      />
      <div className={`postContainer ${feed_highlighted ? 'highlighted' : ''}`}>
        <FeedHeader
          ownerName={owner_name}
          ownerImage={owner_image}
          ownerTimeElapse={owner_time_elapse}
          ownerUrl={owner_url}
          feedDeleteUrl={feed_delete_url}
          feedUnique={feed_unique}
        />
        <div onClick={() =>
          (owner_file_image || owner_file_video || owner_file_document)
          && setShow(true)
        }
        >
          {children}
        </div>
        <div className="job-status-bar">
          <ul className="reactions-list">
            <li>
              <button
                type="button"
                id={feedIsLiked ? `btn-unlike-${feed_unique}` : `btn-like-${feed_unique}`}
                data-feed-unique={feed_unique}
                className={feedIsLiked ? "btn-unlike" : "btn-like"}
                onClick={() => likeHandler(feedIsLiked ? feed_unlike_url : feed_like_url)}
              >
                {feedIsLiked ? <BsHeartFill className="mr-1" /> : <BsHeart className="mr-1" />}
                {likesState}
              </button>
            </li>
            <li>
              <button
                type="button"
                id={`btn-comments-${feed_unique}`}
                className="btn-indicator"
              >
                <BiMessage className="mr-1" />
                {totalComments}
              </button>
            </li>
            <li>
              <button
                type="button"
                id={`btn-share-${feed_unique}`}
                className="btn-indicator"
                onClick={btnShareHandler}
              >
                <RiShareForwardLine className="mr-1" />
                {sharedState}
              </button>
            </li>
            <li className="position-relative">
              <button
                type="button"
                className="btn-indicator"
                onClick={() => setShareOptions(!shareOptions)}
              >
                <BiShareAlt />
              </button>
              {
                shareOptions &&
                <div className="ext_share" ref={shareContainer}>
                  <FacebookShareButton url={feed_share_external_url}>
                    <FacebookIcon size={32} round />
                  </FacebookShareButton>
                  <TwitterShareButton url={feed_share_external_url}>
                    <TwitterIcon size={32} round />
                  </TwitterShareButton>
                  <TelegramShareButton url={feed_share_external_url}>
                    <TelegramIcon size={32} round />
                  </TelegramShareButton>
                  <WhatsappShareButton url={feed_share_external_url}>
                    <WhatsappIcon size={32} round />
                  </WhatsappShareButton>
                  <RedditShareButton url={feed_share_external_url}>
                    <RedditIcon size={32} round />
                  </RedditShareButton>
                  <EmailShareButton url={feed_share_external_url}>
                    <EmailIcon size={32} round />
                  </EmailShareButton>
                </div>
              }
            </li>
          </ul>
        </div>
        {commentsRender}
        <div>
          <form
            className={`form-comment-feed-${feed_unique}`}
            data-feed-unique={feed_unique}
            onSubmit={handleSubmit(submitCommentHandler)}
          >
            <div className='feedCommentContainer'>
              <img src={image} alt="User profile image" />
              <input
                className='commentInput'
                type="text"
                name="comment"
                id={`comment-${feed_unique}`}
                maxLength="256"
                placeholder="Escribe un comentario"
                ref={register({
                  required: {
                    value: "true",
                    message: "El campo es requerido",
                  },
                })}
              />
              <button className={`shareIconContainer iconActive`} >
                <TbSend className='shareIcon' />
              </button>
            </div>
          </form>
          {errors.comment &&
            <FormErrorFeedback>
              {errors.comment.message}
            </FormErrorFeedback>
          }
        </div>
      </div >
    </React.Fragment >
  );
};

export default React.memo(FeedTemplate);