Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

import React, { useEffect, useState, useRef } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { axios } from '../../../utils'
import {
  EmailIcon,
  EmailShareButton,
  FacebookIcon,
  FacebookShareButton,
  RedditIcon,
  RedditShareButton,
  TelegramIcon,
  TelegramShareButton,
  TwitterIcon,
  TwitterShareButton,
  WhatsappIcon,
  WhatsappShareButton,
} from 'react-share'
import parse from 'html-react-parser'
import RecommendIcon from '@mui/icons-material/Recommend'
import FavoriteIcon from '@mui/icons-material/FavoriteTwoTone'
import VolunteerActivismIcon from '@mui/icons-material/VolunteerActivism'
import EmojiEmotionsIcon from '@mui/icons-material/EmojiEmotions'
import TungstenIcon from '@mui/icons-material/Tungsten'
import GroupsRoundedIcon from '@mui/icons-material/GroupsRounded'

import { feedTypes } from '../../redux/feed/feed.types'
import { shareModalTypes } from '../../../redux/share-modal/shareModal.types'

import { deleteFeed } from '../../redux/feed/feed.actions'
import { openShareModal } from '../../../redux/share-modal/shareModal.actions'
import { addNotification } from '../../../redux/notification/notification.actions'

import FeedCommentSection from './CommentSection'
import useOutsideClick from '../../hooks/useOutsideClick'

import FeedModal from './FeedModal'
import ConfirmModal from '../modals/ConfirmModal'
import SurveyForm from '../survey-form/SurveyForm'
import ReactionsButton from '../UI/buttons/ReactionsButton'

const Feed = ({ feed, owner_shared, image }) => {
  const {
    feed_unique,
    owner_name,
    owner_url,
    owner_image,
    owner_time_elapse,
    owner_file_image,
    owner_file_video,
    owner_file_document,
    owner_feed_type,
    feed_highlighted,
    feed_share_url,
    feed_delete_url,
    comments,
    comment_add_url,
    feed_share_external_url,
  } = feed
  const [totalComments, setTotalComments] = useState(0)
  const [ownerReactions, setOwnerReaction] = useState(feed.feed_reactions)
  const [totalReactions, setTotalReactions] = useState(0)
  const [sharedState, setSharedState] = useState(owner_shared)
  const [shareUrl, setShareUrl] = useState('')

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

  const shareContainer = useRef(null)
  const dispatch = useDispatch()

  useOutsideClick(shareContainer, () => setShareOptions(false))

  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 getShareUrl = new Promise((resolve, reject) => {
    if (shareOptions) {
      axios
        .get(feed_share_external_url)
        .then(({ data }) => {
          if (!data.success) {
            dispatch(addNotification({ style: 'danger', msg: data.data }))
            setShareOptions(false)
            return reject(data.data)
          }
          setShareUrl(data.data)
          return resolve(data.data)
        })
        .catch((err) => reject(err))
    }
  })

  const displayComments = () => {
    setShowComments(!showComments)
  }

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

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

  useEffect(() => {
    const feedReactions = ownerReactions.reduce(
      (acc, reaction) => acc + Number(reaction.total),
      0
    )
    setTotalReactions(feedReactions)
  }, [ownerReactions])

  return (
    <>
      <FeedModal isShow={show} handleClose={() => setShow(false)} feed={feed} />
      <div className={`feed ${feed_highlighted ? 'highlighted' : ''}`}>
        <FeedHeader
          ownerName={owner_name}
          ownerImage={owner_image}
          ownerTimeElapse={owner_time_elapse}
          ownerUrl={owner_url}
          feedDeleteUrl={feed_delete_url}
          feedUnique={feed_unique}
          feedType={owner_feed_type}
        />
        <div
          onClick={() =>
            (owner_file_image || owner_file_video || owner_file_document) &&
            setShow(true)
          }
        >
          <Feed.Content
            isShare={!!feed.shared_name}
            image={feed.owner_file_image}
            fileVideo={feed.owner_file_video}
            imagePreview={feed.owner_file_image_preview}
            document={feed.owner_file_document}
            description={feed.owner_description}
            type={feed.feed_content_type}
            voteUrl={feed.feed_vote_url}
            sharedItem={{
              name: feed.shared_name,
              image: feed.shared_image,
              time_elapse: feed.shared_time_elapse,
              description: feed.shared_description,
              file_video: feed.shared_file_video,
              file_image_preview: feed.shared_file_image_preview,
              file_image: feed.shared_file_image,
              file_document: feed.shared_file_document,
            }}
          />
        </div>
        <div className="reactions-counter">
          {reactionsOptions
            .filter((option) =>
              ownerReactions.find(
                (reaction) => reaction.reaction === option.type
              )
            )
            .map((reaction) => reaction.icon)}
          <span>{totalReactions} reacciones</span>
        </div>
        <ul className="reactions-list">
          <li>
            <ReactionsButton
              onChange={(reactions) => setOwnerReaction(reactions)}
              currentReaction={feed.feed_my_reaction}
              withLabel
              deleteUrl={feed.feed_delete_reaction_url}
              reactionTypesUrl={{
                r: feed.feed_save_reaction_recommended_url,
                s: feed.feed_save_reaction_support_url,
                l: feed.feed_save_reaction_love_url,
                i: feed.feed_save_reaction_interest_url,
                f: feed.feed_save_reaction_fun_url,
              }}
            />
          </li>
          <li>
            <button
              type="button"
              id={`btn-comments-${feed_unique}`}
              className="btn-indicator"
              onClick={displayComments}
            >
              <img src="/images/icons/message.png" className="mr-1 img-icon" />
              {totalComments}
            </button>
          </li>
          <li>
            <button
              type="button"
              id={`btn-share-${feed_unique}`}
              className="btn-indicator"
              onClick={btnShareHandler}
            >
              <img src="/images/icons/share.png" className="mr-1 img-icon" />
              {sharedState}
            </button>
          </li>
          <li className="position-relative">
            <button
              type="button"
              className="btn-indicator"
              onClick={() => setShareOptions(!shareOptions)}
            >
              <i className="mr-1 far fa-share-square" />
            </button>
            {shareOptions && (
              <div className="ext_share" ref={shareContainer}>
                <FacebookShareButton
                  beforeOnClick={() => getShareUrl}
                  url={shareUrl}
                >
                  <FacebookIcon size={32} round />
                </FacebookShareButton>
                <TwitterShareButton
                  beforeOnClick={() => getShareUrl}
                  url={shareUrl}
                >
                  <TwitterIcon size={32} round />
                </TwitterShareButton>
                <TelegramShareButton
                  beforeOnClick={() => getShareUrl}
                  url={shareUrl}
                >
                  <TelegramIcon size={32} round />
                </TelegramShareButton>
                <WhatsappShareButton
                  beforeOnClick={() => getShareUrl}
                  url={shareUrl}
                >
                  <WhatsappIcon size={32} round />
                </WhatsappShareButton>
                <RedditShareButton
                  beforeOnClick={() => getShareUrl}
                  url={shareUrl}
                >
                  <RedditIcon size={32} round />
                </RedditShareButton>
                <EmailShareButton
                  beforeOnClick={() => getShareUrl}
                  url={shareUrl}
                >
                  <EmailIcon size={32} round />
                </EmailShareButton>
              </div>
            )}
          </li>
        </ul>
        <FeedCommentSection
          isShow={showComments}
          image={image}
          addUrl={comment_add_url}
          currentComments={comments}
          updateTotalComments={(totalComments) =>
            setTotalComments(totalComments)
          }
        />
      </div>
    </>
  )
}

export const FeedContent = ({
  showDescription = true,
  image,
  video,
  imagePreview,
  document,
  description,
  isShare,
  sharedItem,
  type,
  voteUrl,
}) => {
  const labels = useSelector((state) => state.labels)

  return (
    <div className="job_descp">
      {type !== 'fast-survey' && showDescription ? (
        <Feed.Description description={description} />
      ) : (
        <SurveyForm
          active={description.active}
          question={description.question}
          answers={[
            description.answer1,
            description.answer2,
            description.answer3,
            description.answer4,
            description.answer5,
          ]}
          votes={
            description.votes1 && [
              description.votes1,
              description.votes2,
              description.votes3,
              description.votes4,
              description.votes5,
            ]
          }
          time={description.time_remaining}
          voteUrl={voteUrl}
          resultType={description.result_type}
        />
      )}

      {image && <img src={image} className="Entradas" loading="lazy" />}
      {video && (
        <video src={video} controls poster={imagePreview} preload="none" />
      )}
      {document && (
        <a href={document} target="_blank" rel="noreferrer">
          {labels.DOWNLOAD}
        </a>
      )}
      {isShare && (
        <Feed.Shared
          name={sharedItem.name}
          image={sharedItem.image}
          timeElapse={sharedItem.time_elapse}
          description={sharedItem.description}
          video={sharedItem.file_video}
          imagePreview={sharedItem.file_image_preview}
          document={sharedItem.file_document}
        />
      )}
    </div>
  )
}
export const FeedDescription = ({ description }) => {
  const [isReadMoreActive, setIsReadMoreActive] = useState(false)
  const labels = useSelector((state) => state.labels)

  const readMoreHandler = () => setIsReadMoreActive(!isReadMoreActive)

  const htmlParsedText = (fullStringText) => {
    const fullText = parse(fullStringText)
    if (fullStringText.length > 500) {
      const shortenedString = fullStringText.substr(0, 500)
      const shortenedText = parse(`${shortenedString}... `)
      return (
        <p>
          {isReadMoreActive ? fullText : shortenedText}
          <span className="cursor-pointer" onClick={readMoreHandler}>
            {isReadMoreActive ? labels.READ_LESS : labels.READ_MORE}
          </span>
        </p>
      )
    }
    return <p>{fullText}</p>
  }

  return <div className="show-read-more">{htmlParsedText(description)}</div>
}

export const FeedShared = ({
  name,
  image,
  timeElapse,
  description,
  video,
  imagePreview,
  document,
}) => {
  const [isReadMoreActive, setIsReadMoreActive] = useState(false)
  const labels = useSelector((state) => state.labels)

  const readMoreHandler = () => setIsReadMoreActive(!isReadMoreActive)

  const htmlParsedText = (fullStringText) => {
    const fullText = parse(fullStringText)
    if (fullStringText.length > 500) {
      const shortenedString = fullStringText.substr(0, 500)
      const shortenedText = parse(`${shortenedString}... `)
      return (
        <p>
          {isReadMoreActive ? fullText : shortenedText}
          <span className="cursor-pointer" onClick={readMoreHandler}>
            {isReadMoreActive ? labels.READ_LESS : labels.READ_MORE}
          </span>
        </p>
      )
    }
    return <p>{fullText}</p>
  }

  return (
    <div className="shared-post-bar">
      <div className="post-bar">
        <div className="post_topbar">
          <div className="usy-dt">
            <img src={image} alt="" style={{ width: '50px', height: 'auto' }} />
            <div className="usy-name">
              <h3>{name}</h3>
              <span>{timeElapse}</span>
            </div>
          </div>
        </div>
        <div className="job_descp">
          <div className="show-read-more">{htmlParsedText(description)}</div>
          {image && <img src={image} className="Entradas" loading="lazy" />}
          {video && (
            <video src={video} controls poster={imagePreview} preload="none" />
          )}
          {document && (
            <a href={document} target="_blank" rel="noreferrer">
              {labels.DOWNLOAD}
            </a>
          )}
        </div>
      </div>
    </div>
  )
}

export const FeedHeader = ({
  ownerName,
  ownerImage,
  ownerTimeElapse,
  ownerUrl,
  feedDeleteUrl,
  feedUnique,
  feedType,
}) => {
  const [showConfirmModal, setShowConfirmModal] = useState(false)
  const [displayOption, setDisplayOption] = useState(false)
  const deleteButton = useRef(null)

  const labels = useSelector(({ intl }) => intl.labels)
  const dispatch = useDispatch()

  useOutsideClick(deleteButton, () => setDisplayOption(false))

  const handleShowConfirmModal = () => {
    setShowConfirmModal(!showConfirmModal)
  }

  const deleteFeedHandler = () => {
    axios.post(feedDeleteUrl).then((res) => {
      const { data } = res
      if (!data.success) {
        dispatch(addNotification({ style: 'danger', msg: data.data }))
        return
      }
      dispatch(addNotification({ style: 'success', msg: data.data }))
      handleShowConfirmModal()
      dispatch(deleteFeed(feedUnique))
    })
  }

  return (
    <>
      <div className="post_topbar">
        <div className="usy-dt">
          <a href={ownerUrl}>
            <img
              src={ownerImage}
              alt=""
              style={{ width: '50px', height: 'auto' }}
            />
          </a>
          <div className="usy-name">
            <a href={ownerUrl}>
              <h3>{ownerName}</h3>
            </a>
            <span>
              {feedType === 'g' && <GroupsRoundedIcon />}
              {ownerTimeElapse}
            </span>
          </div>
        </div>
        {feedDeleteUrl && (
          <div className="cursor-pointer d-flex align-items-center">
            <img
              src="/images/icons/options.png"
              className="cursor-pointer img-icon options"
              onClick={() => setDisplayOption(!displayOption)}
            />
            <div className={`feed-options ${displayOption ? 'active' : ''}`}>
              <ul>
                <li>
                  <button
                    className="option-btn"
                    onClick={handleShowConfirmModal}
                    ref={deleteButton}
                  >
                    <i className="fa fa-trash-o mr-1" />
                    {labels.delete}
                  </button>
                </li>
              </ul>
            </div>
            <ConfirmModal
              show={showConfirmModal}
              onClose={() => handleShowConfirmModal(false)}
              onAccept={deleteFeedHandler}
              acceptLabel="Aceptar"
            />
          </div>
        )}
      </div>
    </>
  )
}

Feed.Shared = FeedShared
Feed.Description = FeedDescription
Feed.Content = FeedContent
Feed.Header = FeedHeader

export default React.memo(Feed)