Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 7226 | 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 AccessTimeIcon from '@mui/icons-material/AccessTime'
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/feed/linkedin/InputOption'
import ReactionsButton from '../../components/UI/buttons/ReactionsButton'
import withExternalShare from '../../components/feed/linkedin/withExternalShare'

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 [comments, setComments] = useState([])
  const [readMore, setReadMore] = useState(false)
  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 readMoreHandler = () => setReadMore(!readMore)

  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,
    {
      Icon: SendOutlinedIcon,
      color: 'gray',
      title: 'Enviar',
      shareUrl: post.share_increment_external_counter_url,
      setValue: handleExternalShare,
      withTitle: true,
    }
  )

  const htmlParsedText = (fullStringText) => {
    const fullText = parse(fullStringText)
    if (fullStringText.length > 500) {
      const shortenedString = fullStringText.substr(0, 500)
      const shortenedText = parse(`${shortenedString}... `)
      return (
        <>
          {readMore ? fullText : shortenedText}
          <span className="cursor-pointer" onClick={readMoreHandler}>
            {readMore ? ' Leer menos' : ' Leer más'}
          </span>
        </>
      )
    }
    return <p>{fullText}</p>
  }

  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((error) => {
        dispatch(
          addNotification({
            style: 'danger',
            message: 'Error interno. Por favor, inténtelo de nuevo más tarde.',
          })
        )
        throw new Error(error)
      })
  }, [])

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

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

    setTotalReactions(feedReactions)
  }, [reactions])

  return (
    <Container>
      <Row>
        <Col md="8">
          <div className="feed">
            <div className="feed__body">
              {post.image && (
                <img
                  src={`/storage/type/post/code/${post.uuid}/filename/${post.image}`}
                />
              )}
            </div>
            <div className="feed__body">
              <div className="feed__header">
                <div className="feed__info">
                  <h2>{post.title}</h2>
                  <div className="time__elapse">
                    <p>{post.addedOn}</p>
                    <AccessTimeIcon className="time__elapse-icon" />
                  </div>
                </div>
              </div>
              {post.description && htmlParsedText(post.description)}
              {post.file && (
                <a href={post.file} download>
                  <img
                    className="pdf"
                    src="/images/extension/pdf.png"
                    alt="pdf"
                  />
                </a>
              )}
            </div>
            <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>
            <div className="feed__buttons">
              <ReactionsButton
                className="btn feed__share-option position-relative"
                currentReaction={myReaction}
                withLabel
                onChange={({ reactions }) => setReactions(reactions)}
              />
              <InputOption
                Icon={ChatOutlinedIcon}
                title={labels.comments}
                color="gray"
                onClick={displayCommentSection}
                withTitle
              />
              <ExternalShareButton />
            </div>
            {showComments && (
              <>
                <CommentForm onSubmit={addComment} />
                <CommentsList comments={comments} onDelete={deleteComment} />
              </>
            )}
          </div>
        </Col>
        <Col md="4">
          <HomeNews currentPost={post.uuid} />
        </Col>
      </Row>
    </Container>
  )
}

export default PostViewPage