Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 2188 | Rev 2190 | 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 { useDispatch, useSelector } from 'react-redux'
import { Container, Grid } from '@mui/material'
import parse from 'html-react-parser'

import SendOutlinedIcon from '@mui/icons-material/SendOutlined'
import ChatOutlinedIcon from '@mui/icons-material/ChatOutlined'

import HomeNews from '../../components/widgets/default/HomeNews'
import withExternalShare from '../../components/dashboard/linkedin/withExternalShare'
import Paraphrase from '../../components/UI/Paraphrase'
import WidgetWrapper from '../../components/widgets/WidgetLayout'
import withReactions from '../../hocs/withReaction'
import MobileShare from '../../components/dashboard/linkedin/mobile-share/MobileShare'
import CommentForm from '@app/components/dashboard/linkedin/comments/comment-form'
import CommentsList from '@app/components/dashboard/linkedin/comments/comment-list'
import Button from '@app/components/UI/buttons/Buttons'
import FeedReactions from '@app/components/dashboard/linkedin/feed/FeedReactions'
import PostFile from '@app/components/post/PostFile'
import useMobile from '@app/hooks/useMobile'

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

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

  const getComments = (url) => {
    axios.get(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(Button, post.share_external_url)

  const ReactionButton = withReactions(Button)

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

  useEffect(() => {
    if (post.comments_url) getComments(post.comments_url)
  }, [post])

  return (
    <Container as='main' className='px-0'>
      <Grid container spacing={2}>
        <Grid item xs={12} md={8}>
          <WidgetWrapper>
            <img
              src={post.image}
              style={{
                width: '100%',
                maxHeight: '450px',
                objectFit: 'contain'
              }}
            />
            <WidgetWrapper.Body>
              <h2>{post.title}</h2>
              <Paraphrase>{post.description}</Paraphrase>
              <PostFile file={post.file} type={post.type} />
            </WidgetWrapper.Body>

            <div className='d-flex justify-content-between align-items-center px-3'>
              <FeedReactions
                reactions={reactions}
                reactionsUrl={post.reactions_url}
              />

              {!!totalSends && (
                <span>{`${totalSends} ${labels.sends?.toLowerCase()}`}</span>
              )}
            </div>

            <WidgetWrapper.Actions>
              <ReactionButton
                currentReactionType={myReaction}
                saveUrl={post.save_reaction_url}
                deleteUrl={post.delete_reaction_url}
                onReaction={({ reactions }, currentReaction) => {
                  setReactions(reactions)
                  setMyReaction(currentReaction)
                }}
              />

              <Button onClick={displayCommentSection}>
                <ChatOutlinedIcon style={{ color: 'gray' }} />
                {labels.comment}
              </Button>

              {!isMobile ? (
                <ExternalShareButton
                  shorterUrl={post.share_increment_external_counter_url}
                  setValue={handleExternalShare}
                >
                  <SendOutlinedIcon style={{ color: 'gray' }} />
                  {labels.send}
                </ExternalShareButton>
              ) : (
                <MobileShare
                  shareData={{
                    title: 'Leaders Linked',
                    text: parse(post.description ?? ''),
                    url: post.share_external_url
                  }}
                >
                  <SendOutlinedIcon />
                  {labels.send}
                </MobileShare>
              )}
            </WidgetWrapper.Actions>

            {showComments && (
              <div className='px-3 pb-2'>
                <CommentForm onSubmit={addComment} />
                <CommentsList comments={comments} onDelete={deleteComment} />
              </div>
            )}
          </WidgetWrapper>
        </Grid>

        <Grid item xs={12} md={4}>
          <HomeNews currentPost={post.uuid} />
        </Grid>
      </Grid>
    </Container>
  )
}

export const renderContent = ({ type, file }) => {
  switch (type) {
    case 'video': {
      return (
        <video src={file} controls preload='none' controlsList='nodownload' />
      )
    }

    case 'image': {
      return <img src={file} />
    }

    case 'document': {
      return (
        <a href={file} target='_blank' rel='noreferrer'>
          <img className='pdf' src='/images/extension/pdf.png' alt='pdf' />
        </a>
      )
    }

    case 'audio': {
      return (
        <audio controls>
          <source src={file} />
        </audio>
      )
    }

    default: {
      return (
        <a href={file} target='_blank' rel='noreferrer'>
          <img className='pdf' src='/images/extension/pdf.png' alt='pdf' />
        </a>
      )
    }
  }
}

export default PostViewPage