Proyectos de Subversion LeadersLinked - SPA

Rev

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

Rev Autor Línea Nro. Línea
520 stevensc 1
import React, { useEffect, useState } from 'react'
2
import { axios } from '../../utils'
3
import { useLocation } from 'react-router-dom'
4
import { getBackendVars } from '../../services/backendVars'
5
import { addNotification } from '../../redux/notification/notification.actions'
6
import { Col, Container, Row } from 'react-bootstrap'
7
import { useDispatch, useSelector } from 'react-redux'
5 stevensc 8
 
520 stevensc 9
import TungstenIcon from '@mui/icons-material/Tungsten'
10
import RecommendIcon from '@mui/icons-material/Recommend'
11
import AccessTimeIcon from '@mui/icons-material/AccessTime'
12
import FavoriteIcon from '@mui/icons-material/FavoriteTwoTone'
13
import SendOutlinedIcon from '@mui/icons-material/SendOutlined'
14
import ChatOutlinedIcon from '@mui/icons-material/ChatOutlined'
15
import EmojiEmotionsIcon from '@mui/icons-material/EmojiEmotions'
16
import VolunteerActivismIcon from '@mui/icons-material/VolunteerActivism'
5 stevensc 17
 
520 stevensc 18
import { CommentForm, CommentsList } from '../../components/feed/CommentSection'
19
import HomeNews from '../../components/widgets/default/HomeNews'
20
import InputOption from '../../components/dashboard/linkedin/action-button/InputOption'
21
import ReactionsButton from '../../components/UI/buttons/ReactionsButton'
22
import withExternalShare from '../../components/dashboard/linkedin/withExternalShare'
23
import Paraphrase from '../../components/UI/Paraphrase'
24
 
5 stevensc 25
const PostViewPage = () => {
520 stevensc 26
  const [post, setPost] = useState({})
27
  const [totalSends, setTotalSends] = useState(0)
28
  const [reactions, setReactions] = useState([])
29
  const [myReaction, setMyReaction] = useState('')
30
  const [totalReactions, setTotalReactions] = useState(0)
31
  const [comments, setComments] = useState([])
32
  const [showComments, setShowComments] = useState(false)
33
  const labels = useSelector(({ intl }) => intl.labels)
34
  const dispatch = useDispatch()
35
  const { pathname } = useLocation()
5 stevensc 36
 
37
  const reactionsOptions = [
38
    {
520 stevensc 39
      type: 'r',
40
      icon: <RecommendIcon style={{ color: '#7405f9' }} />,
5 stevensc 41
    },
42
    {
520 stevensc 43
      type: 's',
44
      icon: <VolunteerActivismIcon style={{ color: '#6495ED' }} />,
5 stevensc 45
    },
46
    {
520 stevensc 47
      type: 'l',
48
      icon: <FavoriteIcon style={{ color: '#DF704D' }} />,
5 stevensc 49
    },
50
    {
520 stevensc 51
      type: 'i',
5 stevensc 52
      icon: (
53
        <TungstenIcon
520 stevensc 54
          style={{ color: '#F5BB5C', transform: 'rotate(180deg)' }}
5 stevensc 55
        />
56
      ),
57
    },
58
    {
520 stevensc 59
      type: 'f',
60
      icon: <EmojiEmotionsIcon style={{ color: '#FF7F50' }} />,
5 stevensc 61
    },
520 stevensc 62
  ]
5 stevensc 63
 
64
  const displayCommentSection = () => {
520 stevensc 65
    setShowComments(!showComments)
66
  }
5 stevensc 67
 
68
  const getComments = () => {
69
    axios.get(post.comments_url).then((response) => {
520 stevensc 70
      const { data, success } = response.data
5 stevensc 71
 
72
      if (!success) {
73
        const errorMessage =
520 stevensc 74
          typeof data === 'string' ? data : 'Error interno. Intente más tarde.'
5 stevensc 75
 
520 stevensc 76
        dispatch(addNotification({ style: 'danger', msg: errorMessage }))
77
        return
5 stevensc 78
      }
79
 
520 stevensc 80
      setComments(data)
81
    })
82
  }
5 stevensc 83
 
84
  const handleExternalShare = (value) => {
520 stevensc 85
    setTotalSends(value)
86
  }
5 stevensc 87
 
88
  const ExternalShareButton = withExternalShare(
89
    InputOption,
520 stevensc 90
    post.share_external_url
91
  )
5 stevensc 92
 
93
  const addComment = ({ comment }) => {
520 stevensc 94
    const formData = new FormData()
95
    formData.append('comment', comment)
5 stevensc 96
 
97
    axios.post(post.comments_add_url, formData).then((response) => {
520 stevensc 98
      const { success, data } = response.data
5 stevensc 99
 
100
      if (!success) {
101
        const errorMessage =
520 stevensc 102
          typeof data === 'string' ? data : 'Error interno. Intente más tarde.'
5 stevensc 103
 
520 stevensc 104
        dispatch(addNotification({ style: 'danger', msg: errorMessage }))
105
        return
5 stevensc 106
      }
107
 
520 stevensc 108
      setComments((prevMessages) => [...prevMessages, data])
109
    })
110
  }
5 stevensc 111
 
112
  const deleteComment = (commentUnique, deleteCommentUrl) => {
113
    axios
114
      .post(deleteCommentUrl)
115
      .then((response) => {
520 stevensc 116
        const { success, data } = response.data
5 stevensc 117
 
118
        if (!success) {
119
          const errorMessage =
520 stevensc 120
            typeof data === 'string'
5 stevensc 121
              ? data
520 stevensc 122
              : 'Error interno. Intente más tarde.'
5 stevensc 123
 
520 stevensc 124
          dispatch(addNotification({ style: 'danger', msg: errorMessage }))
125
          return
5 stevensc 126
        }
127
 
128
        setComments((prevComments) =>
129
          prevComments.filter((comment) => comment.unique !== commentUnique)
520 stevensc 130
        )
131
        dispatch(addNotification({ style: 'success', msg: data }))
5 stevensc 132
      })
133
      .catch((error) => {
520 stevensc 134
        dispatch(addNotification({ style: 'danger', msg: error }))
135
        throw new Error(error)
136
      })
137
  }
5 stevensc 138
 
139
  useEffect(() => {
140
    getBackendVars(pathname)
141
      .then((post) => {
520 stevensc 142
        setMyReaction(post.my_reaction)
143
        setTotalSends(post.total_share_external)
144
        setPost(post)
5 stevensc 145
      })
520 stevensc 146
      .catch(() => {
5 stevensc 147
        dispatch(
148
          addNotification({
520 stevensc 149
            style: 'danger',
150
            message: 'Error interno. Por favor, inténtelo de nuevo más tarde.',
5 stevensc 151
          })
520 stevensc 152
        )
153
      })
154
  }, [pathname])
5 stevensc 155
 
156
  useEffect(() => {
157
    if (showComments && !comments.length) {
520 stevensc 158
      getComments()
5 stevensc 159
    }
520 stevensc 160
  }, [showComments])
5 stevensc 161
 
162
  useEffect(() => {
163
    const feedReactions = reactions.reduce(
164
      (acc, reaction) => acc + Number(reaction.total),
165
 
520 stevensc 166
    )
5 stevensc 167
 
520 stevensc 168
    setTotalReactions(feedReactions)
169
  }, [reactions])
5 stevensc 170
 
171
  return (
172
    <Container>
173
      <Row>
174
        <Col md="8">
175
          <div className="feed">
176
            <div className="feed__body">
177
              {post.image && (
178
                <img
179
                  src={`/storage/type/post/code/${post.uuid}/filename/${post.image}`}
180
                />
181
              )}
182
            </div>
183
            <div className="feed__body">
184
              <div className="feed__header">
185
                <div className="feed__info">
186
                  <h2>{post.title}</h2>
187
                  <div className="time__elapse">
188
                    <p>{post.addedOn}</p>
189
                    <AccessTimeIcon className="time__elapse-icon" />
190
                  </div>
191
                </div>
192
              </div>
520 stevensc 193
              <Paraphrase>{post.description}</Paraphrase>
5 stevensc 194
              {post.file && (
195
                <a href={post.file} download>
196
                  <img
197
                    className="pdf"
198
                    src="/images/extension/pdf.png"
199
                    alt="pdf"
200
                  />
201
                </a>
202
              )}
203
            </div>
204
            <div className="d-flex justify-content-between align-items-center px-3">
205
              <div className="reactions-counter">
206
                {reactionsOptions
207
                  .filter((option) =>
208
                    reactions.find(({ reaction }) => reaction === option.type)
209
                  )
210
                  .map((reaction) => reaction.icon)}
211
                <span>{totalReactions} reacciones</span>
212
              </div>
213
              {!!totalSends && (
214
                <span>{`${totalSends} ${labels.sends?.toLowerCase()}`}</span>
215
              )}
216
            </div>
217
            <div className="feed__buttons">
218
              <ReactionsButton
219
                className="btn feed__share-option position-relative"
220
                currentReaction={myReaction}
221
                withLabel
222
                onChange={({ reactions }) => setReactions(reactions)}
223
              />
224
              <InputOption
520 stevensc 225
                icon={ChatOutlinedIcon}
226
                label={labels.comments}
227
                iconColor="gray"
228
                className="btn feed__share-option"
5 stevensc 229
                onClick={displayCommentSection}
230
              />
520 stevensc 231
              <ExternalShareButton
232
                icon={SendOutlinedIcon}
233
                iconColor="gray"
234
                label={labels.send}
235
                shareUrl={post.increment_external_counter_url}
236
                setValue={handleExternalShare}
237
              />
5 stevensc 238
            </div>
239
            {showComments && (
240
              <>
241
                <CommentForm onSubmit={addComment} />
242
                <CommentsList comments={comments} onDelete={deleteComment} />
243
              </>
244
            )}
245
          </div>
246
        </Col>
247
        <Col md="4">
248
          <HomeNews currentPost={post.uuid} />
249
        </Col>
250
      </Row>
251
    </Container>
520 stevensc 252
  )
253
}
5 stevensc 254
 
520 stevensc 255
export default PostViewPage